"""Tools para consulta de processos judiciais."""

from typing import Any

from fastmcp import Context, FastMCP

from services.llm_service import get_llm_service
from services.supabase_client import get_supabase_client
from tools.documentos import _montar_contexto_documentos

# URL para sincronizar processos
SYNC_URL = "https://tecjusticamcp3.vercel.app/login"

# Limites de contexto por modelo
LIMITE_GEMINI = 3_000_000  # 3M chars (~750k tokens)
LIMITE_GROK = 7_000_000  # 7M chars (~1.7M tokens)

# Mensagem padrao para processo nao encontrado
MSG_PROCESSO_NAO_ENCONTRADO = (
    "Processo {numero} nao encontrado no sistema. "
    f"Acesse {SYNC_URL} para sincronizar o processo antes de consultar."
)


def register_processos_tools(mcp: FastMCP) -> None:
    """Registra tools de processos no servidor MCP."""

    @mcp.tool
    async def buscar_processo(
        numero_processo: str,
        ctx: Context,
    ) -> dict[str, Any]:
        """
        Busca um processo judicial pelo numero e retorna resumo otimizado.

        Args:
            numero_processo: Numero do processo no formato CNJ (NNNNNNN-DD.AAAA.J.TR.OOOO)

        Returns:
            Resumo estruturado do processo (pre-processado por LLM)
        """
        client = get_supabase_client()
        processo = await client.processo_completo(numero_processo)

        if not processo:
            return {
                "erro": MSG_PROCESSO_NAO_ENCONTRADO.format(numero=numero_processo),
                "encontrado": False,
            }

        # Pre-processa com Gemini para resumo compacto
        llm = get_llm_service()
        resumo = await llm.processar_processo_para_claude(processo)

        return {
            "encontrado": True,
            "numero_processo": numero_processo,
            "resumo": resumo,
        }

    @mcp.tool
    async def listar_processos(
        limite: int = 20,
        ctx: Context = None,
    ) -> dict[str, Any]:
        """
        Lista todos os processos disponiveis no sistema.

        Args:
            limite: Quantidade maxima de processos (default: 20, max: 50)

        Returns:
            Lista compacta de processos
        """
        limite = min(limite, 50)
        client = get_supabase_client()
        jobs = await client.listar_todos_processos(limite=limite)

        # Formato compacto direto (sem LLM para lista simples)
        processos = []
        for job in jobs:
            processo_data = job.get("processos")
            if processo_data:
                processos.append(
                    {
                        "numero": job.get("numero_processo"),
                        "classe": processo_data.get("classe_descricao"),
                        "tribunal": processo_data.get("sigla_tribunal"),
                        "valor": processo_data.get("valor_causa"),
                        "status": job.get("status"),
                    }
                )

        return {
            "total": len(processos),
            "processos": processos,
        }

    @mcp.tool
    async def buscar_por_parte(
        nome_parte: str,
        ctx: Context,
    ) -> dict[str, Any]:
        """
        Busca processos por nome de parte.

        Args:
            nome_parte: Nome ou parte do nome

        Returns:
            Lista compacta de processos encontrados
        """
        client = get_supabase_client()
        processos = await client.buscar_por_parte(nome_parte)

        # Formato compacto
        lista = [
            {
                "numero": p.get("numero_processo"),
                "classe": p.get("classe_descricao"),
                "tribunal": p.get("sigla_tribunal"),
            }
            for p in processos[:10]  # Max 10
        ]

        return {
            "termo": nome_parte,
            "total": len(processos),
            "processos": lista,
        }

    @mcp.tool
    async def estatisticas_processo(
        numero_processo: str,
        ctx: Context,
    ) -> dict[str, Any]:
        """
        Estatisticas do processo.

        Args:
            numero_processo: Numero do processo

        Returns:
            Estatisticas resumidas
        """
        client = get_supabase_client()
        stats = await client.stats_processo(numero_processo)

        if not stats:
            return {
                "erro": MSG_PROCESSO_NAO_ENCONTRADO.format(numero=numero_processo),
                "encontrado": False,
            }

        return {
            "encontrado": True,
            "numero_processo": numero_processo,
            "classe": stats.get("classe_descricao"),
            "tribunal": stats.get("sigla_tribunal"),
            "valor": stats.get("valor_causa"),
            "docs": stats.get("docs_extraidos", 0),
            "movs": stats.get("movs_sincronizados", 0),
            "tamanho_mb": round((stats.get("tamanho_total_bytes") or 0) / 1024 / 1024, 2),
        }

    @mcp.tool
    async def resumo_processo(
        numero_processo: str,
        pergunta: str | None = None,
        ctx: Context = None,
    ) -> dict[str, Any]:
        """
        Resumo executivo do processo com possibilidade de pergunta especifica.

        Args:
            numero_processo: Numero do processo
            pergunta: Pergunta especifica sobre o processo (opcional)

        Returns:
            Resumo gerado por LLM
        """
        client = get_supabase_client()
        processo = await client.processo_completo(numero_processo)

        if not processo:
            return {
                "erro": MSG_PROCESSO_NAO_ENCONTRADO.format(numero=numero_processo),
                "encontrado": False,
            }

        # Pre-processa com Gemini incluindo pergunta se houver
        llm = get_llm_service()
        resumo = await llm.processar_processo_para_claude(processo, pergunta=pergunta)

        return {
            "encontrado": True,
            "numero_processo": numero_processo,
            "resumo": resumo,
        }

    @mcp.tool
    async def analisar_processo(
        numero_processo: str,
        pergunta: str = "Faca uma analise completa deste processo",
        ctx: Context = None,
    ) -> dict[str, Any]:
        """
        Analisa processo com estrategia inteligente e fallback de modelo.

        Estrategia:
        1. Busca markdown completo do processo
        2. Escolhe modelo pelo tamanho:
           - <= 3M chars: Gemini Flash (1M tokens)
           - > 3M chars: Grok Fast (2M tokens!)
        3. Se markdown > 7M chars: selecao inteligente de documentos

        Args:
            numero_processo: Numero do processo
            pergunta: Pergunta ou instrucao para analise

        Returns:
            Resposta com estrategia e modelo utilizados
        """
        client = get_supabase_client()
        llm = get_llm_service()

        # 1. Busca markdown completo
        job = await client.obter_markdown_processo(numero_processo)
        markdown = job.get("markdown") if job else None

        if markdown:
            tamanho = len(markdown)

            if tamanho <= LIMITE_GEMINI:
                modelo = "gemini-flash"
            elif tamanho <= LIMITE_GROK:
                modelo = "grok-fast"
            else:
                modelo = None

            if modelo:
                resposta = await llm.query(
                    pergunta=pergunta,
                    contexto=markdown,
                    model=modelo,
                    max_tokens=4000,
                )
                return {
                    "sucesso": True,
                    "estrategia": "markdown_completo",
                    "modelo": modelo,
                    "contexto_chars": tamanho,
                    "resposta": resposta.text,
                }

        # 2. Fallback: Selecao inteligente
        docs = await client.selecionar_documentos_inteligente(
            numero_processo, max_chars=LIMITE_GROK
        )

        if not docs:
            return {
                "erro": MSG_PROCESSO_NAO_ENCONTRADO.format(numero=numero_processo),
                "sucesso": False,
            }

        contexto = _montar_contexto_documentos(docs, max_chars=LIMITE_GROK)
        modelo = "grok-fast" if len(contexto) > LIMITE_GEMINI else "gemini-flash"

        resposta = await llm.query(
            pergunta=pergunta,
            contexto=contexto,
            model=modelo,
            max_tokens=4000,
        )

        return {
            "sucesso": True,
            "estrategia": "selecao_inteligente",
            "modelo": modelo,
            "documentos_selecionados": len(docs),
            "contexto_chars": len(contexto),
            "resposta": resposta.text,
        }
