"""
Testes de validação contra payloads reais da API pública DataJud CNJ.

Fixtures capturadas em 2026-03-14 via:
  POST https://api-publica.datajud.cnj.jus.br/api_publica_{tribunal}/_search

Cobrem:
  - TJSP G1  (datajud_real_tjsp.json) — formato dataAjuizamento YYYYMMDDHHmmss,
              numeroProcesso sem pontuação, sistema "Projudi"
  - STJ SUP  (datajud_real_stj.json)  — grau SUP → 3, sistema "Inválido" → None,
              classe G3, encoding Mojibake no nome do orgão
"""

import json
import pytest
from pathlib import Path
from pyjuris import normalizar_processo
from pyjuris.inputs.datajud import _normalize_numero_cnj, _parse_data_ajuizamento

FIXTURES = Path(__file__).parent / "fixtures"


def load(name: str) -> dict:
    return json.loads((FIXTURES / name).read_text())


# ---------------------------------------------------------------------------
# Helpers unitários
# ---------------------------------------------------------------------------

class TestNormalizarNumeroCnj:
    def test_20_digitos_sem_pontuacao(self):
        assert _normalize_numero_cnj("40079797120268260506") == "4007979-71.2026.8.26.0506"

    def test_ja_formatado_nao_altera(self):
        assert _normalize_numero_cnj("0012345-67.2024.8.19.0001") == "0012345-67.2024.8.19.0001"

    def test_none_retorna_none(self):
        assert _normalize_numero_cnj(None) is None

    def test_invalido_retorna_como_veio(self):
        # Não é 20 dígitos → devolve como veio (será marcado cnj_invalido pelo parser)
        assert _normalize_numero_cnj("INVALIDO") == "INVALIDO"

    def test_formatacao_stj(self):
        assert _normalize_numero_cnj("23226121920238260000") == "2322612-19.2023.8.26.0000"


class TestParseDataAjuizamento:
    def test_formato_datajud_nativo_14_digitos(self):
        assert _parse_data_ajuizamento("20260306110756") == "2026-03-06"

    def test_formato_iso_date(self):
        assert _parse_data_ajuizamento("2024-03-10") == "2024-03-10"

    def test_formato_iso_datetime(self):
        result = _parse_data_ajuizamento("2024-03-10T14:22:00Z")
        assert result.startswith("2024-03-10")

    def test_none_retorna_none(self):
        assert _parse_data_ajuizamento(None) is None

    def test_zeros_no_horario(self):
        # "20240621000000" → só a data importa
        assert _parse_data_ajuizamento("20240621000000") == "2024-06-21"


# ---------------------------------------------------------------------------
# TJSP G1 — payload real
# ---------------------------------------------------------------------------

@pytest.fixture
def tjsp():
    return normalizar_processo(load("datajud_real_tjsp.json"), input_template="datajud")


def test_tjsp_sem_fenomenos(tjsp):
    assert tjsp["fenomenos_detectados"] == []


def test_tjsp_numero_cnj_formatado(tjsp):
    # Payload tem "40079797120268260506" (sem pontuação) → deve ser normalizado
    cnj = tjsp["numero_cnj"]
    assert "-" in cnj and "." in cnj, f"CNJ não formatado: {cnj}"


def test_tjsp_data_inicio_parseada(tjsp):
    # dataAjuizamento "20260306110756" → "2026-03-06"
    assert tjsp["data_inicio"] == "2026-03-06"
    assert tjsp["ano_inicio"] == 2026


def test_tjsp_data_ultima_movimentacao(tjsp):
    assert tjsp["data_ultima_movimentacao"] is not None


def test_tjsp_grau(tjsp):
    inst = tjsp["instancias"][0]
    assert inst["grau"] == 1
    assert inst["grau_formatado"] == "Primeiro Grau"


def test_tjsp_tribunal(tjsp):
    inst = tjsp["instancias"][0]
    assert inst["tribunal"]["sigla"] == "TJSP"
    # Sistema vindo diretamente da API (não do nosso mapeamento)
    assert inst["tribunal"]["sistema"] == "Projudi"


def test_tjsp_classe(tjsp):
    inst = tjsp["instancias"][0]
    assert inst["classe"] == "PROCEDIMENTO COMUM CÍVEL"
    assert inst["classe_codigo"] == 7


def test_tjsp_assunto(tjsp):
    inst = tjsp["instancias"][0]
    assert inst["assunto_principal"] is not None
    assert len(inst["assuntos"]) >= 1


def test_tjsp_orgao_julgador(tjsp):
    inst = tjsp["instancias"][0]
    assert inst["orgao_julgador"] is not None
    assert inst["orgao_julgador_codigo"] is not None
    assert inst["orgao_julgador_municipio_ibge"] is not None


def test_tjsp_movimentos_preenchidos(tjsp):
    inst = tjsp["instancias"][0]
    assert len(inst["movimentos"]) > 0
    mov = inst["movimentos"][0]
    assert mov["codigo"] is not None
    assert mov["nome"] is not None
    assert mov["data_hora"] is not None


def test_tjsp_nivel_sigilo(tjsp):
    assert tjsp["nivel_sigilo"] == 0
    assert tjsp["segredo_justica"] is False


def test_tjsp_tipo_e_fase(tjsp):
    assert tjsp["tipo_principal"] == "ACAO_ORIGINAL"
    assert tjsp["fase_atual"] == "PRIMEIRO_GRAU"


# ---------------------------------------------------------------------------
# STJ SUP (grau 3) — payload real
# ---------------------------------------------------------------------------

@pytest.fixture
def stj():
    return normalizar_processo(load("datajud_real_stj.json"), input_template="datajud")


def test_stj_sem_fenomenos(stj):
    assert stj["fenomenos_detectados"] == []


def test_stj_numero_cnj_formatado(stj):
    cnj = stj["numero_cnj"]
    assert "-" in cnj and "." in cnj


def test_stj_grau_sup(stj):
    # grau "SUP" → 3
    inst = stj["instancias"][0]
    assert inst["grau"] == 3
    assert inst["grau_formatado"] == "Terceiro Grau"


def test_stj_tribunal(stj):
    inst = stj["instancias"][0]
    assert inst["tribunal"]["sigla"] == "STJ"


def test_stj_sistema_invalido_normalizado(stj):
    # API retorna sistema.nome = "Inválido" → deve ser None
    inst = stj["instancias"][0]
    assert inst["tribunal"]["sistema"] is None


def test_stj_classe(stj):
    inst = stj["instancias"][0]
    assert inst["classe"] == "AGRAVO EM RECURSO ESPECIAL"
    assert inst["classe_codigo"] == 11881


def test_stj_tipo(stj):
    assert stj["tipo_principal"] == "RECURSO_SUPERIOR"
    assert stj["fase_atual"] == "TERCEIRO_GRAU"


def test_stj_data_inicio(stj):
    # dataAjuizamento "20240621000000" → "2024-06-21"
    assert stj["data_inicio"] == "2024-06-21"
    assert stj["ano_inicio"] == 2024


def test_stj_orgao_encoding_corrigido(stj):
    # Nome vinha com Mojibake "VILLAS BÃ\x94AS" → deve ser "BÔAS"
    inst = stj["instancias"][0]
    assert inst["orgao_julgador"] is not None
    assert "BÃ" not in inst["orgao_julgador"], "Mojibake não corrigido"
    assert "BÔAS" in inst["orgao_julgador"] or "CUEVA" in inst["orgao_julgador"]


def test_stj_movimentos(stj):
    inst = stj["instancias"][0]
    assert len(inst["movimentos"]) > 0


def test_stj_envelope_nao_afeta(stj):
    # Confirma que envelope _source também funciona
    payload = load("datajud_real_stj.json")
    envelope = {"_source": payload, "_index": "stj", "_id": "abc"}
    result = normalizar_processo(envelope, input_template="datajud")
    assert result["numero_cnj"] == stj["numero_cnj"]
