"""MCP-over-HTTP adapter — native MCP protocol at /mcp.

Provides tool discovery (GET /mcp) and invocation (POST /mcp) using
MCP JSON-RPC wire format, enabling AI agents (Claude, etc.) to interact
with all DataBridge tools natively.
"""

from __future__ import annotations

import logging
from typing import Any, Dict, List, Optional

from fastapi import APIRouter, Depends, Request
from fastapi.responses import JSONResponse
from pydantic import BaseModel, Field

from ..context import RequestContext
from ..registry import ToolRegistry

logger = logging.getLogger(__name__)

router = APIRouter(tags=["MCP Protocol"])

_registry: ToolRegistry | None = None
_tenant_registry: Any = None


def init_mcp(registry: ToolRegistry, tenant_registry: Any = None) -> None:
    """Wire the shared ToolRegistry into this adapter."""
    global _registry, _tenant_registry
    _registry = registry
    _tenant_registry = tenant_registry


# ------------------------------------------------------------------
# MCP JSON-RPC models
# ------------------------------------------------------------------

class MCPParams(BaseModel):
    """MCP tool call parameters."""
    name: str
    arguments: Dict[str, Any] = Field(default_factory=dict)


class MCPRequest(BaseModel):
    """MCP JSON-RPC request envelope."""
    jsonrpc: str = "2.0"
    id: Optional[str | int] = None
    method: str = "tools/call"
    params: MCPParams


class MCPContent(BaseModel):
    """Single content item in an MCP response."""
    type: str = "text"
    text: str = ""


class MCPResult(BaseModel):
    """MCP tool call result."""
    content: List[MCPContent] = Field(default_factory=list)
    isError: bool = False


class MCPResponse(BaseModel):
    """MCP JSON-RPC response envelope."""
    jsonrpc: str = "2.0"
    id: Optional[str | int] = None
    result: Optional[MCPResult] = None
    error: Optional[Dict[str, Any]] = None


# ------------------------------------------------------------------
# Dependency
# ------------------------------------------------------------------

async def _get_mcp_context(request: Request) -> RequestContext:
    """Build RequestContext for MCP requests."""
    from ..middleware.auth import get_request_context
    return await get_request_context(request, _tenant_registry, protocol="mcp")


# ------------------------------------------------------------------
# Routes
# ------------------------------------------------------------------

@router.post("/mcp")
async def mcp_invoke(
    request: MCPRequest,
    context: RequestContext = Depends(_get_mcp_context),
) -> JSONResponse:
    """Native MCP tool invocation — same ToolRegistry, MCP wire format.

    Accepts MCP JSON-RPC requests and returns MCP-format responses.
    Supports method: "tools/call" for tool execution.
    """
    if request.method == "tools/list":
        manifest = _registry.generate_mcp_manifest()
        return JSONResponse(content={
            "jsonrpc": "2.0",
            "id": request.id,
            "result": manifest,
        })

    if request.method != "tools/call":
        return JSONResponse(
            status_code=400,
            content={
                "jsonrpc": "2.0",
                "id": request.id,
                "error": {
                    "code": -32601,
                    "message": f"Method not found: {request.method}",
                },
            },
        )

    result = await _registry.invoke(
        request.params.name,
        request.params.arguments,
        context,
    )

    # Check for gateway-level errors
    if "error" in result:
        return JSONResponse(
            status_code=result.get("code", 500),
            content={
                "jsonrpc": "2.0",
                "id": request.id,
                "error": {
                    "code": result.get("code", -32000),
                    "message": result["error"],
                },
            },
        )

    # Wrap in MCP response format
    text = result.get("result", "")
    if not isinstance(text, str):
        import json
        text = json.dumps(text, default=str)

    return JSONResponse(content={
        "jsonrpc": "2.0",
        "id": request.id,
        "result": {
            "content": [{"type": "text", "text": text}],
            "isError": False,
        },
    })


@router.get("/mcp")
async def mcp_manifest(
    context: RequestContext = Depends(_get_mcp_context),
) -> JSONResponse:
    """Tool discovery — returns MCP manifest with all available tools."""
    manifest = _registry.generate_mcp_manifest()
    return JSONResponse(content=manifest)
