#!/usr/bin/env python3
"""Importa lotes legados em arquivo para as tabelas MySQL separadas por cartao.

Uso:
  python scripts/importar_lotes_file_para_mysql.py --school develop
  python scripts/importar_lotes_file_para_mysql.py --school develop --apply

Sem ``--apply`` o comando apenas informa o que seria gravado.
"""
from __future__ import annotations

import argparse
import json
import sys
from pathlib import Path

from dotenv import load_dotenv


BACKEND_DIR = Path(__file__).resolve().parent.parent
if str(BACKEND_DIR) not in sys.path:
    sys.path.insert(0, str(BACKEND_DIR))
load_dotenv(BACKEND_DIR / ".env")

from app.db import get_engine  # noqa: E402
from app.db_models import LoteLeituraModel, LoteProcessamentoModel  # noqa: E402
from app.lote_leitura import compactar_dados_leitura  # noqa: E402
from app.settings import MYSQL_DATABASE, PASTA_PROCESSAMENTOS, nome_pasta_processamentos_para_escola  # noqa: E402


def _ler_lotes(pasta: Path):
    for caminho in sorted(pasta.glob("*/lote.json")):
        try:
            dados = json.loads(caminho.read_text(encoding="utf-8"))
        except (OSError, json.JSONDecodeError):
            continue
        if not isinstance(dados, dict):
            continue
        nome = str((dados.get("metadados") or {}).get("id_processamento") or caminho.parent.name).strip()
        leituras = dados.get("leituras") or {}
        if nome and isinstance(leituras, dict):
            yield nome, dados, leituras


def importar(school: str, aplicar: bool) -> tuple[int, int]:
    pasta = PASTA_PROCESSAMENTOS / nome_pasta_processamentos_para_escola(school)
    if not pasta.is_dir():
        raise FileNotFoundError(f"Pasta não encontrada: {pasta}")

    from sqlalchemy.orm import sessionmaker

    fabrica = sessionmaker(bind=get_engine(MYSQL_DATABASE), autoflush=False, expire_on_commit=False)
    lotes, leituras_total = 0, 0
    with fabrica() as session:
        for nome, dados, leituras in _ler_lotes(pasta):
            lotes += 1
            leituras_total += len(leituras)
            print(f"[{'IMPORTAR' if aplicar else 'SIMULAR'}] {nome} ({len(leituras)} leitura(s))")
            if not aplicar:
                continue
            lote = session.query(LoteProcessamentoModel).filter_by(
                nome_processamento=nome, schoolname=school
            ).one_or_none()
            if lote is None:
                lote = LoteProcessamentoModel(nome_processamento=nome, schoolname=school)
                session.add(lote)
                session.flush()
            lote.metadados = dict(dados.get("metadados") or {})
            lote.estado = dict(dados.get("estado") or {})
            lote.leituras = {}
            session.query(LoteLeituraModel).filter_by(lote_id=lote.id).delete()
            session.add_all(
                LoteLeituraModel(lote_id=lote.id, chave=str(chave), dados=compactar_dados_leitura(valor))
                for chave, valor in leituras.items()
            )
        if aplicar:
            session.commit()
    return lotes, leituras_total


def main() -> int:
    parser = argparse.ArgumentParser(description="Importa lotes JSON para MySQL.")
    parser.add_argument("--school", required=True)
    parser.add_argument("--apply", action="store_true", help="Confirma a gravação no MySQL.")
    args = parser.parse_args()
    try:
        lotes, leituras = importar(str(args.school).strip().lower(), args.apply)
    except (FileNotFoundError, OSError) as erro:
        print(f"[ERRO] {erro}")
        return 1
    acao = "importado(s)" if args.apply else "encontrado(s)"
    print(f"Resumo: {lotes} lote(s) {acao}; {leituras} leitura(s).")
    if not args.apply:
        print("Nenhum dado foi alterado. Revise e execute novamente com --apply.")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
