"""MCP JSON-RPC client for EasyClaw Foreman chat."""

from __future__ import annotations

import re
from typing import Any

import httpx

MCP_URL = "https://mcp.easyclaw.help/mcp"

# Keywords that signal which MCP tool to route to
_GATEWAY_KEYWORDS = re.compile(
    r"gateway|bind|port|421|proxy|traefik|reverse proxy|https|tls|ssl|certificate|misdirected",
    re.IGNORECASE,
)
_DIAGNOSE_KEYWORDS = re.compile(
    r"error|fail|crash|broken|not working|won't start|can't connect|timeout|refused|"
    r"exit code|traceback|exception|502|503|404|ECONNREFUSED",
    re.IGNORECASE,
)
_SECURITY_KEYWORDS = re.compile(
    r"security|audit|hardening|firewall|allowlist|dmpolicy|token|permission|auth",
    re.IGNORECASE,
)


def route_query(text: str) -> tuple[str, dict[str, Any]]:
    """Pick the best MCP tool for a user's chat message."""
    if _GATEWAY_KEYWORDS.search(text):
        return "troubleshoot_gateway", {"symptom": text}
    if _DIAGNOSE_KEYWORDS.search(text):
        return "diagnose_issue", {"error_text": text}
    if _SECURITY_KEYWORDS.search(text):
        return "security_audit", {}
    # Default to knowledge search
    return "search_knowledge", {"query": text}


class MCPClient:
    """Sends JSON-RPC 2.0 requests to the EasyClaw MCP server."""

    def __init__(self, api_key: str, base_url: str = MCP_URL) -> None:
        self.api_key = api_key
        self.base_url = base_url
        self._id = 0

    def _next_id(self) -> int:
        self._id += 1
        return self._id

    async def call_tool(self, tool_name: str, arguments: dict[str, Any] | None = None) -> dict[str, Any]:
        """Call an MCP tool and return the result."""
        payload = {
            "jsonrpc": "2.0",
            "id": self._next_id(),
            "method": "tools/call",
            "params": {
                "name": tool_name,
                "arguments": arguments or {},
            },
        }
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self.api_key}",
        }
        async with httpx.AsyncClient(timeout=30.0) as client:
            resp = await client.post(self.base_url, json=payload, headers=headers)
            resp.raise_for_status()
            data = resp.json()

        if "error" in data:
            return {"error": data["error"].get("message", str(data["error"]))}

        result = data.get("result", {})
        # MCP returns content array — extract text
        if isinstance(result, dict) and "content" in result:
            texts = [c.get("text", "") for c in result["content"] if c.get("type") == "text"]
            return {"text": "\n".join(texts)}
        return result

    async def smart_query(self, text: str) -> str:
        """Route a user message to the best MCP tool and return the response."""
        tool_name, args = route_query(text)
        result = await self.call_tool(tool_name, args)
        return result.get("text", result.get("error", "No response"))

    async def diagnose(self, error_text: str) -> str:
        """Diagnose an issue using the MCP server."""
        result = await self.call_tool("diagnose_issue", {"error_text": error_text})
        return result.get("text", result.get("error", "No diagnosis available"))

    async def search_knowledge(self, query: str) -> str:
        """Search the knowledge base."""
        result = await self.call_tool("search_knowledge", {"query": query})
        return result.get("text", result.get("error", "No results"))

    async def troubleshoot_gateway(self, symptom: str) -> str:
        """Troubleshoot gateway issues."""
        result = await self.call_tool("troubleshoot_gateway", {"symptom": symptom})
        return result.get("text", result.get("error", "No troubleshooting info"))

    async def validate_deployment(self) -> str:
        """Run a full deployment health check."""
        result = await self.call_tool("validate_deployment", {})
        return result.get("text", result.get("error", "No validation data"))

    async def security_audit(self) -> str:
        """Run a security audit."""
        result = await self.call_tool("security_audit", {})
        return result.get("text", result.get("error", "No audit data"))

    async def health_check(self) -> bool:
        """Check if the MCP server is reachable."""
        try:
            async with httpx.AsyncClient(timeout=10.0) as client:
                resp = await client.get(
                    self.base_url.replace("/mcp", "/health"),
                    headers={"Authorization": f"Bearer {self.api_key}"},
                )
                return resp.status_code == 200
        except Exception:
            return False
