"""
MCP 工具注册中心
提供 @register_tool 装饰器和全局 TOOL_REGISTRY
"""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, Callable, Coroutine
from sqlalchemy.ext.asyncio import AsyncSession
from app.schemas.auth import CurrentUserPayload


@dataclass
class MCPToolMeta:
    """MCP 工具元信息"""
    name: str
    description: str
    parameters: dict[str, Any]  # JSON Schema 描述
    handler: Callable[
        [AsyncSession, CurrentUserPayload, dict[str, Any]],
        Coroutine[Any, Any, "MCPToolResult"]
    ] | None = None


@dataclass
class MCPToolResult:
    """MCP 工具执行结果"""
    success: bool = True
    # 返回给 AI/前端的类型：text 或 action_card
    response_type: str = "text"  # "text" | "action_card"
    data: dict[str, Any] = field(default_factory=dict)
    message: str = ""


# ── 全局工具注册表 ────────────────────────────────────────
TOOL_REGISTRY: dict[str, MCPToolMeta] = {}


def register_tool(
    name: str,
    description: str,
    parameters: dict[str, Any] | None = None,
):
    """装饰器：注册 MCP 工具到全局注册表"""
    def decorator(fn: Callable):
        meta = MCPToolMeta(
            name=name,
            description=description,
            parameters=parameters or {},
            handler=fn,
        )
        TOOL_REGISTRY[name] = meta
        return fn
    return decorator


def get_tools_manifest() -> list[dict[str, Any]]:
    """返回所有已注册工具的清单（供 Dify Agent 读取配置）"""
    return [
        {
            "name": meta.name,
            "description": meta.description,
            "parameters": meta.parameters,
        }
        for meta in TOOL_REGISTRY.values()
    ]


async def execute_tool(
    tool_name: str,
    db: AsyncSession,
    user: CurrentUserPayload,
    params: dict[str, Any],
) -> MCPToolResult:
    """根据工具名称执行对应 handler"""
    meta = TOOL_REGISTRY.get(tool_name)
    if meta is None or meta.handler is None:
        return MCPToolResult(
            success=False,
            message=f"工具 '{tool_name}' 未注册或无 handler",
        )
    return await meta.handler(db, user, params)
