"""
Testes da integração pandas (pyjuris.pandas_utils).
Requer: pip install pyjuris[pandas]
"""

import json
import pytest
from pathlib import Path

pd = pytest.importorskip("pandas")

from pyjuris.pandas_utils import (
    normalizar_dataframe,
    expandir_campos,
    to_instancias_dataframe,
    fenomenos_dataframe,
)
from pyjuris import normalizar_processo

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


def load(name):
    return json.loads((FIXTURES / name).read_text())


@pytest.fixture
def payloads():
    return [
        load("payload_simples.json"),
        load("payload_stj_recurso_especial.json"),
        load("payload_encerrado.json"),
        load("payload_trabalhista.json"),
    ]


@pytest.fixture
def resultados(payloads):
    return [normalizar_processo(p, input_template="escavador") for p in payloads]


@pytest.fixture
def df_payloads(payloads):
    return pd.DataFrame({"payload": payloads})


# ---------------------------------------------------------------------------
# normalizar_dataframe
# ---------------------------------------------------------------------------

def test_normalizar_dataframe_retorna_dataframe(df_payloads):
    result = normalizar_dataframe(df_payloads)
    assert isinstance(result, pd.DataFrame)
    assert "pyjuris" in result.columns


def test_normalizar_dataframe_preserva_linhas(df_payloads):
    result = normalizar_dataframe(df_payloads)
    assert len(result) == len(df_payloads)


def test_normalizar_dataframe_resultado_e_dict(df_payloads):
    result = normalizar_dataframe(df_payloads)
    for val in result["pyjuris"]:
        assert isinstance(val, dict)
        assert "numero_cnj" in val


def test_normalizar_dataframe_coluna_customizada(df_payloads):
    result = normalizar_dataframe(df_payloads, coluna_resultado="normalizado")
    assert "normalizado" in result.columns


def test_normalizar_dataframe_none_em_payload_nulo():
    df = pd.DataFrame({"payload": [None]})
    result = normalizar_dataframe(df)
    assert result["pyjuris"].iloc[0] is None


def test_normalizar_dataframe_erro_coerce():
    df = pd.DataFrame({"payload": [{"numero_cnj": "INVALIDO", "fontes": []}]})
    result = normalizar_dataframe(df, erros="coerce")
    # Não levanta exceção — retorna resultado (cnj_invalido é fenômeno, não erro)
    assert result["pyjuris"].iloc[0] is not None


def test_normalizar_dataframe_template_datajud():
    df = pd.DataFrame({"payload": [load("datajud_simples.json")]})
    result = normalizar_dataframe(df, input_template="datajud")
    assert result["pyjuris"].iloc[0]["numero_cnj"] == "0012345-67.2024.8.19.0001"


# ---------------------------------------------------------------------------
# expandir_campos
# ---------------------------------------------------------------------------

def test_expandir_campos_retorna_dataframe(resultados):
    df = expandir_campos(resultados)
    assert isinstance(df, pd.DataFrame)
    assert len(df) == len(resultados)


def test_expandir_campos_colunas_padrao(resultados):
    df = expandir_campos(resultados)
    assert "numero_cnj" in df.columns
    assert "tipo_principal" in df.columns
    assert "fase_atual" in df.columns
    assert "fenomenos_detectados" in df.columns


def test_expandir_campos_fenomenos_como_string(resultados):
    df = expandir_campos(resultados)
    # fenomenos_detectados vira string CSV (amigável p/ Excel)
    assert df["fenomenos_detectados"].dtype == object


def test_expandir_campos_colunas_customizadas(resultados):
    df = expandir_campos(resultados, campos=["numero_cnj", "polo_ativo"])
    assert list(df.columns) == ["numero_cnj", "polo_ativo"]


def test_expandir_campos_none_ignorado(resultados):
    df = expandir_campos(resultados + [None])
    assert len(df) == len(resultados) + 1
    assert df.iloc[-1]["numero_cnj"] is None


# ---------------------------------------------------------------------------
# to_instancias_dataframe
# ---------------------------------------------------------------------------

def test_instancias_dataframe_retorna_dataframe(resultados):
    df = to_instancias_dataframe(resultados)
    assert isinstance(df, pd.DataFrame)


def test_instancias_dataframe_uma_linha_por_instancia(resultados):
    total_instancias = sum(r["total_instancias"] for r in resultados)
    df = to_instancias_dataframe(resultados)
    assert len(df) == total_instancias


def test_instancias_dataframe_colunas(resultados):
    df = to_instancias_dataframe(resultados)
    assert "numero_cnj" in df.columns
    assert "grau" in df.columns
    assert "tribunal_sigla" in df.columns
    assert "classe" in df.columns


def test_instancias_dataframe_stj_tem_grau_3(resultados):
    df = to_instancias_dataframe(resultados)
    stj = df[df["tribunal_sigla"] == "STJ"]
    assert len(stj) == 1
    assert stj.iloc[0]["grau"] == 3


def test_instancias_dataframe_encerrado_arquivado(resultados):
    df = to_instancias_dataframe(resultados)
    encerradas = df[df["status_instancia"] == "INATIVO"]
    # payload_encerrado tem 2 instâncias inativas
    assert len(encerradas) >= 2


# ---------------------------------------------------------------------------
# fenomenos_dataframe
# ---------------------------------------------------------------------------

def test_fenomenos_dataframe_retorna_dataframe(resultados):
    df = fenomenos_dataframe(resultados)
    assert isinstance(df, pd.DataFrame)


def test_fenomenos_dataframe_colunas(resultados):
    df = fenomenos_dataframe(resultados)
    assert "fenomeno" in df.columns
    assert "count" in df.columns


def test_fenomenos_dataframe_ordenado_por_freq(resultados):
    # Injeta fenômeno repetido
    from pyjuris import normalizar_processo
    payloads_inv = [load("payload_inversao_polo.json")] * 3
    res = [normalizar_processo(p, input_template="escavador") for p in payloads_inv]
    df = fenomenos_dataframe(res)
    if len(df) > 0:
        assert df.iloc[0]["count"] >= df.iloc[-1]["count"]


def test_fenomenos_dataframe_sem_fenomenos():
    r = [normalizar_processo(load("payload_simples.json"), input_template="escavador")]
    df = fenomenos_dataframe(r)
    assert isinstance(df, pd.DataFrame)
