"""
Wbudowane narzędzia zarządzania backendami MCP.

Odpowiedzialność:
- Definiuje narzędzia management__* widoczne dla Claude'a
- Deleguje operacje do Orchestratora
- Nie zna szczegółów protokołu MCP — zwraca string wynikowy
"""

from __future__ import annotations

import json
from collections.abc import Callable, Coroutine
from dataclasses import dataclass
from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    from .orchestrator import Orchestrator
    from .registry import Registry


@dataclass
class BuiltinTool:
    name: str
    description: str
    input_schema: dict[str, Any]
    handler: Callable[..., Coroutine[Any, Any, str]]


class ManagementTools:
    def __init__(self, orchestrator: Orchestrator, registry: Registry):
        self._orchestrator = orchestrator
        self._registry = registry

    def get_tools(self) -> list[BuiltinTool]:
        return [
            BuiltinTool(
                name="add_mcp_server",
                description="Dodaje nowy serwer MCP jako backend gateway. Po dodaniu jego narzędzia stają się dostępne.",
                input_schema={
                    "type": "object",
                    "properties": {
                        "id": {"type": "string", "description": "Unikalny identyfikator backendu (np. 'mcp_dom')"},
                        "url": {"type": "string", "description": "URL serwera MCP (np. 'http://localhost:8124/mcp')"},
                    },
                    "required": ["id", "url"],
                },
                handler=self._add_mcp_server,
            ),
            BuiltinTool(
                name="remove_mcp_server",
                description="Usuwa serwer MCP z gateway. Wszystkie jego narzędzia przestają być dostępne.",
                input_schema={
                    "type": "object",
                    "properties": {
                        "id": {"type": "string", "description": "Identyfikator backendu do usunięcia"},
                    },
                    "required": ["id"],
                },
                handler=self._remove_mcp_server,
            ),
            BuiltinTool(
                name="list_mcp_servers",
                description="Zwraca listę aktualnie zarejestrowanych serwerów MCP wraz z ich URL-ami.",
                input_schema={
                    "type": "object",
                    "properties": {},
                },
                handler=self._list_mcp_servers,
            ),
            BuiltinTool(
                name="refresh_mcp_server",
                description="Odświeża listę narzędzi z podanego serwera MCP (przydatne gdy serwer dodał nowe narzędzia).",
                input_schema={
                    "type": "object",
                    "properties": {
                        "id": {"type": "string", "description": "Identyfikator backendu do odświeżenia"},
                    },
                    "required": ["id"],
                },
                handler=self._refresh_mcp_server,
            ),
        ]

    async def _add_mcp_server(self, id: str, url: str) -> str:
        await self._orchestrator.add_backend(id, url)
        tools = [m.public_name for m in self._registry.list_tools() if m.backend.id == id]
        return f"Dodano backend '{id}' ({url}). Zarejestrowano {len(tools)} narzędzi: {', '.join(tools)}"

    async def _remove_mcp_server(self, id: str) -> str:
        await self._orchestrator.remove_backend(id)
        return f"Usunięto backend '{id}'."

    async def _list_mcp_servers(self) -> str:
        backends = list(self._registry._backends.values())
        if not backends:
            return "Brak zarejestrowanych backendów."
        items = [{"id": b.id, "url": b.url} for b in backends]
        return json.dumps(items, ensure_ascii=False, indent=2)

    async def _refresh_mcp_server(self, id: str) -> str:
        await self._orchestrator.refresh_backend(id)
        tools = [m.public_name for m in self._registry.list_tools() if m.backend.id == id]
        return f"Odświeżono backend '{id}'. Aktualne narzędzia ({len(tools)}): {', '.join(tools)}"
