"""Tool function builder for Data API.

This module provides functionality to dynamically build executable Python functions
from tool schemas, enabling seamless integration with AI agents and automated workflows.

@deprecated: This module is deprecated and will be removed in future releases.
"""

from collections.abc import Callable
from inspect import Parameter, Signature
from pathlib import Path
from typing import Any

from hezor_common.data_model.searching.data.api_models import SearchResponse, ToolSchema
from hezor_common.transfer.base_sdk import MetaInfo
from hezor_common.transfer.datahub_sdk.base.constants import (
    DEFAULT_DATA_API_BASE_URL,
    DEFAULT_DATA_API_KEY,
)


def _convert_json_type_to_python(json_type: str) -> type:
    """将JSON Schema类型转换为Python类型。

    Parameters
    ----------
    json_type : str
        JSON Schema类型名称（string, integer, number, boolean, array, object）

    Returns
    -------
    type
        对应的Python类型
    """
    type_mapping = {
        "string": str,
        "integer": int,
        "number": float,
        "boolean": bool,
        "array": list,
        "object": dict,
    }
    return type_mapping.get(json_type, str)


def build_tool_functions(
    tools: SearchResponse | list[ToolSchema],
    base_url: str = DEFAULT_DATA_API_BASE_URL,
    api_key: str | None = DEFAULT_DATA_API_KEY,
    meta_info: MetaInfo | None = None,
    private_key_path: str | Path | None = None,
    password: bytes | None = None,
    meta_info_expires_in: int = 3600,
) -> dict[str, Callable]:
    """从搜索结果构建可执行的工具函数。

    将SearchResponse或工具列表转换为可执行的函数字典。

    Parameters
    ----------
    tools : SearchResponse | list[ToolSchema]
        搜索结果或工具列表
    base_url : str
        API基础URL，用于执行工具
    api_key : str | None
        API密钥，用于Bearer token认证
    meta_info : MetaInfo | None
        元信息对象，用于生成请求头
    private_key_path : str | Path | None
        私钥文件路径，用于JWT签名
    password : bytes | None
        私钥密码
    meta_info_expires_in : int
        MetaInfo JWT token过期时间（秒）

    Returns
    -------
    dict[str, Callable]
        工具名称到可执行函数的映射字典
        每个函数具有完整的类型签名和docstring

    Examples
    --------
    >>> # 搜索工具并构建工具函数
    >>> search_result = await search_tools("查询天气", top_k=3)
    >>> tool_functions = build_tool_functions(search_result)
    >>>
    >>> # 使用构建的工具
    >>> result = await tool_functions["get_weather"](city="北京")
    >>> print(result)

    Notes
    -----
    - 每个生成的函数都有完整的类型签名和docstring
    - 返回值是ExecuteResponse.data
    - 函数名称和描述来自原始工具的元数据
    """
    # Import here to avoid circular dependency
    from hezor_common.transfer.datahub_sdk.execute_tool import execute_tool

    # 提取工具列表
    tool_list = tools.tools if isinstance(tools, SearchResponse) else tools

    tool_functions = {}

    for tool_schema in tool_list:
        # 使用闭包捕获当前工具的schema
        def make_tool_func(
            schema: ToolSchema,
            api_base_url: str,
            api_key_val: str | None,
            meta_info_val: MetaInfo | None,
            private_key_path_val: str | Path | None,
            password_val: bytes | None,
            expires_in_val: int,
        ) -> Callable:
            """创建工具执行函数的工厂函数。"""

            async def tool_func(**kwargs: Any) -> Any:
                """动态生成的工具函数（docstring会被下面覆盖）。"""
                # 过滤掉可能被智能体错误传递的认证参数
                # 只保留业务参数传递给 execute_tool
                reserved_params = {
                    "api_key",
                    "meta_info",
                    "private_key_path",
                    "password",
                    "meta_info_expires_in",
                    "base_url",
                }
                filtered_args = {k: v for k, v in kwargs.items() if k not in reserved_params}

                response = await execute_tool(
                    tool_name=schema.name,
                    args=filtered_args,
                    base_url=api_base_url,
                    api_key=api_key_val,
                    meta_info=meta_info_val,
                    private_key_path=private_key_path_val,
                    password=password_val,
                    meta_info_expires_in=expires_in_val,
                )
                return response.data

            # 构建函数签名（从ToolSchema.params提取参数信息）
            parameters = []
            param_docs = []

            if schema.params and schema.params.props:
                props = schema.params.props
                required_params = schema.params.required or []

                for param_name, param_schema in props.items():
                    # 确定参数类型（从JSON Schema类型转换为Python类型）
                    param_type_str = param_schema.type or "string"
                    param_type = _convert_json_type_to_python(param_type_str)

                    # 确定是否必填
                    is_required = param_name in required_params if required_params else False
                    default_value = Parameter.empty if is_required else None

                    # 如果不是必填参数，类型注解需要包含 None
                    if not is_required:
                        param_type = param_type | None  # type: ignore[assignment]

                    # 创建参数对象
                    param = Parameter(
                        name=param_name,
                        kind=Parameter.KEYWORD_ONLY,
                        annotation=param_type,
                        default=default_value,
                    )
                    parameters.append(param)

                    # 添加参数文档
                    param_desc = param_schema.desc or "参数说明"
                    required_marker = "" if is_required else ", optional"
                    param_docs.append(
                        f"    {param_name} : {param_type_str}{required_marker}\n        {param_desc}"
                    )

            # 设置函数签名
            tool_func.__signature__ = Signature(parameters=parameters)  # type: ignore[attr-defined]

            # 设置函数名称
            tool_func.__name__ = schema.name

            # 构建完整的docstring（包含参数说明）
            docstring_parts = [schema.desc or "执行数据工具查询"]
            if param_docs:
                docstring_parts.append("\nParameters\n----------")
                docstring_parts.extend(param_docs)
            docstring_parts.append("\nReturns\n-------\nAny\n    工具执行结果")

            tool_func.__doc__ = "\n".join(docstring_parts)

            return tool_func

        # 创建工具函数
        func = make_tool_func(
            tool_schema,
            base_url,
            api_key,
            meta_info,
            private_key_path,
            password,
            meta_info_expires_in,
        )

        # 添加到工具字典
        tool_functions[tool_schema.name] = func

    return tool_functions


__all__ = [
    "build_tool_functions",
]
