from __future__ import annotations

from dataclasses import dataclass
from typing import Any, Literal

from niannian.mcp.client.pool import MCPClientPool
from niannian.mcp.service import NianNianService

RouteKind = Literal["memory", "external", "device", "composite"]


@dataclass
class BridgeRoute:
    kind: RouteKind
    detail: str = ""


class ToolBridge:
    """内外 MCP 编排骨架 — Chat / Agent 意图路由。"""

    def __init__(
        self,
        service: NianNianService,
        pool: MCPClientPool | None = None,
        *,
        proxy_external: bool = False,
    ) -> None:
        self._service = service
        self._pool = pool or MCPClientPool()
        self._proxy_external = proxy_external

    def resolve(self, intent: str) -> BridgeRoute:
        text = intent.lower()
        if any(k in text for k in ("记住", "记录", "ingest", "record", "review", "adopt")):
            return BridgeRoute("memory", "record/recall")
        if any(k in text for k in ("文件", "github", "filesystem", "外部")):
            return BridgeRoute("external", "mcp_client")
        if any(k in text for k in ("设备", "打开", "mac", "device")):
            return BridgeRoute("device", "mac_only")
        if "仓库" in text or "readme" in text:
            return BridgeRoute("composite", "recall+external")
        return BridgeRoute("memory", "recall")

    def proxy_call(self, server: str, tool: str, args: dict[str, Any]) -> dict[str, Any]:
        if not self._proxy_external:
            raise RuntimeError("mcp.proxy_external is disabled")
        return self._pool.call_tool(server, tool, args)

    def composite_recall_and_external(
        self,
        task: str,
        *,
        scope: dict[str, Any] | None = None,
        server: str,
        tool: str,
        args: dict[str, Any],
    ) -> dict[str, Any]:
        pack = self._service.recall(task, scope=scope, policy="assist_default")
        external = self._pool.call_tool(server, tool, args)
        return {"recall": pack, "external": external}
