"""
Colunas do log de leitura OMR (log_leitura_omr.csv).
"""
from __future__ import annotations

import csv
from pathlib import Path
from typing import Any

import pandas as pd

LOG_OMR_COLUNAS: list[str] = [
    "arquivo",
    "status",
    "registro_academico",
    "codigo_barras",
    "total_perguntas_modelo",
    "total_respostas_lidas",
    "precisa_correcao_manual",
    "detalhe",
]

COLUNAS_LOG_LEGADAS_REMOVIDAS: frozenset[str] = frozenset({
    "debug_bolhas",
    "debug_cantos",
    "arquivo_manual",
    "total_erros",
    "erros",
    "correcao_manual",
})

_AVISOS_NAO_BLOQUEIAM_CORRECAO = (
    "validação pela api",
    "validacao pela api",
    "sem id final",
    "identificação será concluída",
    "identificacao sera concluida",
)


def erros_exigem_correcao_manual(erros: list | None) -> bool:
    """True apenas para falhas reais, não avisos de pendência cadastral."""
    if not erros:
        return False

    for erro in erros:
        texto = str(erro or "").strip().lower()
        if not texto:
            continue
        if any(fragmento in texto for fragmento in _AVISOS_NAO_BLOQUEIAM_CORRECAO):
            continue
        return True

    return False


def calcular_precisa_correcao_manual(
    status: str,
    resultado: dict | None,
    erros: list | None = None,
    *,
    tem_json_manual: bool = False,
) -> str:
    """Retorna SIM/NÃO — cartão que exige intervenção no painel de correção."""
    if tem_json_manual:
        return "SIM"
    if str(status or "").upper() == "ERRO" or not resultado:
        return "SIM"
    if erros_exigem_correcao_manual(erros):
        return "SIM"
    return "NÃO"


def montar_linha_log(**campos: Any) -> dict[str, Any]:
    linha: dict[str, Any] = {}
    for coluna in LOG_OMR_COLUNAS:
        valor = campos.get(coluna, "")
        if coluna in ("total_perguntas_modelo", "total_respostas_lidas"):
            linha[coluna] = valor if valor != "" else 0
        else:
            linha[coluna] = valor
    return linha


def normalizar_linha_log_bruta(linha: dict[str, Any]) -> dict[str, Any]:
    campos = {coluna: linha.get(coluna, "") for coluna in LOG_OMR_COLUNAS}

    if not str(campos.get("precisa_correcao_manual") or "").strip():
        legado = str(
            linha.get("precisa_correcao_manual")
            or linha.get("correcao_manual")
            or ""
        ).strip()
        if legado:
            campos["precisa_correcao_manual"] = legado
        elif int(linha.get("total_erros") or 0) > 0 or linha.get("erros"):
            campos["precisa_correcao_manual"] = "SIM"
        else:
            campos["precisa_correcao_manual"] = "NÃO"

    return montar_linha_log(**campos)


def dataframe_log_omr(linhas: list[dict[str, Any]]) -> pd.DataFrame:
    normalizadas = [normalizar_linha_log_bruta(item) for item in linhas if isinstance(item, dict)]
    return pd.DataFrame(normalizadas, columns=LOG_OMR_COLUNAS)


def salvar_log_omr_csv(caminho: str | Path, linhas: list[dict[str, Any]]) -> None:
    dataframe_log_omr(linhas).to_csv(
        caminho,
        index=False,
        sep=";",
        encoding="utf-8-sig",
    )


def ler_linhas_log_csv(caminho: Path) -> tuple[list[str], list[dict[str, str]]]:
    with open(caminho, "r", encoding="utf-8-sig", newline="") as arquivo:
        leitor = csv.DictReader(arquivo, delimiter=";")
        linhas = list(leitor)
    return LOG_OMR_COLUNAS, [normalizar_linha_log_bruta(linha) for linha in linhas]


def linha_precisa_correcao_manual(linha: dict) -> bool:
    valor = str(
        linha.get("precisa_correcao_manual")
        or linha.get("correcao_manual")
        or ""
    ).strip().upper()
    return valor == "SIM"
