"""
MCP server setup and tool registration for CRM workflows.
"""

from __future__ import annotations

from dataclasses import dataclass
from typing import Any, Callable, Dict, List, Tuple

from g_gremlin.mcp import (
    dynamics_tools_analyze,
    dynamics_tools_read,
    dynamics_tools_write,
    tools_analyze,
    tools_read,
    tools_write,
)


ToolHandler = Callable[..., Dict[str, Any]]
ToolTuple = Tuple[str, ToolHandler, str]


@dataclass(frozen=True)
class RegisteredTool:
    name: str
    handler: ToolHandler
    description: str


@dataclass(frozen=True)
class ProviderRegistry:
    server_name: str
    instructions: str
    read_module: Any
    analyze_module: Any
    write_module: Any


PROVIDERS: Dict[str, ProviderRegistry] = {
    "sfdc": ProviderRegistry(
        server_name="g-gremlin-sfdc",
        instructions="Salesforce MCP server for read/analyze tools with optional write gates.",
        read_module=tools_read,
        analyze_module=tools_analyze,
        write_module=tools_write,
    ),
    "dynamics": ProviderRegistry(
        server_name="g-gremlin-dynamics",
        instructions=(
            "Dynamics 365 / Dataverse MCP server for read/analyze tools with optional write gates. "
            "Write tools require plan_hash from corresponding *.plan calls."
        ),
        read_module=dynamics_tools_read,
        analyze_module=dynamics_tools_analyze,
        write_module=dynamics_tools_write,
    ),
}


def _resolve_provider(provider: str) -> ProviderRegistry:
    provider_key = str(provider or "sfdc").strip().lower()
    if provider_key not in PROVIDERS:
        allowed = ", ".join(sorted(PROVIDERS.keys()))
        raise ValueError(f"Unknown MCP provider '{provider}'. Allowed values: {allowed}.")
    return PROVIDERS[provider_key]


def get_registered_tools(*, enable_writes: bool = False, provider: str = "sfdc") -> List[RegisteredTool]:
    registry = _resolve_provider(provider)
    tool_tuples: List[ToolTuple] = []
    tool_tuples.extend(registry.read_module.get_tools())
    tool_tuples.extend(registry.analyze_module.get_tools())
    if enable_writes:
        tool_tuples.extend(registry.write_module.get_tools())
    return [RegisteredTool(name=name, handler=handler, description=description) for name, handler, description in tool_tuples]


def list_registered_tool_names(*, enable_writes: bool = False, provider: str = "sfdc") -> List[str]:
    return [tool.name for tool in get_registered_tools(enable_writes=enable_writes, provider=provider)]


def create_fastmcp_server(*, enable_writes: bool = False, provider: str = "sfdc"):
    registry = _resolve_provider(provider)
    try:
        from mcp.server.fastmcp import FastMCP
    except Exception as exc:
        raise RuntimeError(
            "MCP SDK is not installed. Install with: pip install 'g-gremlin[mcp]'"
        ) from exc

    server = FastMCP(
        name=registry.server_name,
        instructions=registry.instructions,
    )
    for tool in get_registered_tools(enable_writes=enable_writes, provider=provider):
        server.add_tool(tool.handler, name=tool.name, description=tool.description)
    return server


def run_server(*, enable_writes: bool = False, provider: str = "sfdc") -> None:
    server = create_fastmcp_server(enable_writes=enable_writes, provider=provider)
    server.run(transport="stdio")
