"""智能体扩展参数容器（对齐 Java ``AgentParam``）。

链式调用：``AgentParam.create().set_string("action", "move_forward").set_integer("step", 3)``。
"""

from __future__ import annotations

from typing import Any, Dict, List, Optional


class AgentParam:
    """轻量 KV 包装器，底层是 ``dict``，方便走 ``json.dumps``。"""

    __slots__ = ("_ext_param",)

    def __init__(self, ext_param: Optional[Dict[str, Any]] = None) -> None:
        self._ext_param: Dict[str, Any] = dict(ext_param) if ext_param else {}

    @classmethod
    def create(cls) -> "AgentParam":
        return cls()

    # --- typed getters / setters --------------------------------------------------

    def get_string(self, key: str) -> Optional[str]:
        value = self._ext_param.get(key)
        return None if value is None else str(value)

    def set_string(self, key: str, value: Optional[str]) -> "AgentParam":
        self._ext_param[key] = value
        return self

    def get_integer(self, key: str) -> Optional[int]:
        value = self._ext_param.get(key)
        if value is None or isinstance(value, bool):
            # 注意：Python 中 bool 是 int 子类，需要先排除
            return None
        try:
            return int(value)
        except (TypeError, ValueError):
            return None

    def set_integer(self, key: str, value: Optional[int]) -> "AgentParam":
        self._ext_param[key] = value
        return self

    # 与 Java 对齐：Long 在 Python 里和 int 同义
    get_long = get_integer
    set_long = set_integer

    def get_short(self, key: str) -> Optional[int]:
        return self.get_integer(key)

    def set_short(self, key: str, value: Optional[int]) -> "AgentParam":
        return self.set_integer(key, value)

    def get_double(self, key: str) -> Optional[float]:
        value = self._ext_param.get(key)
        if value is None or isinstance(value, bool):
            return None
        try:
            return float(value)
        except (TypeError, ValueError):
            return None

    def set_double(self, key: str, value: Optional[float]) -> "AgentParam":
        self._ext_param[key] = value
        return self

    def get_boolean(self, key: str) -> Optional[bool]:
        value = self._ext_param.get(key)
        if value is None:
            return None
        if isinstance(value, bool):
            return value
        if isinstance(value, str):
            lo = value.lower()
            if lo == "true":
                return True
            if lo == "false":
                return False
            return None
        return bool(value)

    def set_boolean(self, key: str, value: Optional[bool]) -> "AgentParam":
        self._ext_param[key] = value
        return self

    def get_object(self, key: str) -> Any:
        return self._ext_param.get(key)

    def set_object(self, key: str, value: Any) -> "AgentParam":
        self._ext_param[key] = value
        return self

    def get_list(self, key: str) -> Optional[List[Any]]:
        value = self._ext_param.get(key)
        return value if isinstance(value, list) else None

    def set_list(self, key: str, value: Optional[List[Any]]) -> "AgentParam":
        self._ext_param[key] = value
        return self

    # --- bulk access --------------------------------------------------------------

    def get_ext_param(self) -> Dict[str, Any]:
        """返回底层 dict（**不拷贝**，与 Java 保持引用语义）。"""
        return self._ext_param

    def __contains__(self, key: str) -> bool:
        return key in self._ext_param

    def __eq__(self, other: object) -> bool:
        if isinstance(other, AgentParam):
            return self._ext_param == other._ext_param
        return NotImplemented

    def __repr__(self) -> str:
        return f"AgentParam({self._ext_param!r})"

    def __str__(self) -> str:
        import json
        return json.dumps(self._ext_param, ensure_ascii=False)
