"""
Migracao one-time: JSON para SQLite.
Execute UMA VEZ apos criar o banco:
    cd C:\\CONCILIADOR_DZ9
    .\\venv\\Scripts\\python.exe db\\migrar_json.py
Os arquivos JSON originais sao mantidos em rh/backup_pre_migracao/.
"""

import sys
if hasattr(sys.stdout, 'reconfigure'):
    sys.stdout.reconfigure(encoding='utf-8', errors='replace')

import shutil
from pathlib import Path
from datetime import date

sys.path.insert(0, str(Path(__file__).resolve().parent.parent))

from db.database import criar_tabelas, get_session
from db.models import Colaborador, RegistroPonto, EscalaItem, Ferias
from db import repos

import json

PASTA_BASE = Path(__file__).resolve().parent.parent
PASTA_RH   = PASTA_BASE / "rh"


def _ler(caminho: Path, padrao):
    if caminho.exists():
        try:
            return json.loads(caminho.read_text(encoding="utf-8"))
        except Exception as e:
            print(f"  Aviso: não foi possível ler {caminho}: {e}")
    return padrao


def _parse_date_br(s: str) -> date | None:
    """DD/MM/AAAA → date."""
    try:
        d, m, a = str(s).strip().split("/")
        return date(int(a), int(m), int(d))
    except Exception:
        return None


def migrar():
    print("=" * 60)
    print("MIGRACAO JSON para SQLite")
    print("=" * 60)

    criar_tabelas()

    # ── 1. Colaboradores ─────────────────────────────────────────
    print("\n[1/4] Colaboradores...")
    colabs_json = _ler(PASTA_RH / "colaboradores.json", [])
    ok = 0
    with get_session() as s:
        for d in colabs_json:
            if s.get(Colaborador, d.get("id")):
                print(f"  Já existe: {d.get('nome')} — pulando")
                continue
            c = Colaborador(
                id       = d.get("id"),
                nome     = d.get("nome", ""),
                cpf      = d.get("cpf") or None,
                cargo    = d.get("cargo") or None,
                salario  = float(d.get("salario") or 0),
                admissao = _parse_date_br(d.get("admissao", "")),
                telefone = d.get("telefone") or None,
                email    = d.get("email") or None,
                status   = d.get("status", "ativo"),
            )
            s.add(c)
            ok += 1
        s.commit()
    print(f"  {ok} colaborador(es) importado(s).")

    # ── 2. Ponto ─────────────────────────────────────────────────
    print("\n[2/4] Registros de ponto...")
    total_ponto = 0
    pasta_ponto = PASTA_RH / "ponto"
    if pasta_ponto.exists():
        for arquivo in sorted(pasta_ponto.glob("*.json")):
            try:
                ano, mes = [int(x) for x in arquivo.stem.split("-")]
            except Exception:
                continue
            dados = _ler(arquivo, {})
            with get_session() as s:
                for id_colab, dias in dados.items():
                    for dia_str, status in dias.items():
                        if not status:
                            continue
                        data_reg = date(ano, mes, int(dia_str))
                        existe = s.query(RegistroPonto).filter_by(
                            colaborador_id=id_colab, data=data_reg
                        ).first()
                        if not existe:
                            s.add(RegistroPonto(
                                colaborador_id=id_colab,
                                data=data_reg,
                                status=status,
                            ))
                            total_ponto += 1
                s.commit()
    print(f"  {total_ponto} registro(s) de ponto importado(s).")

    # ── 3. Escala ─────────────────────────────────────────────────
    print("\n[3/4] Escalas...")
    total_escala = 0
    pasta_escala = PASTA_RH / "escala"
    if pasta_escala.exists():
        for arquivo in sorted(pasta_escala.glob("*.json")):
            try:
                segunda = date.fromisoformat(arquivo.stem)
            except Exception:
                continue
            dados = _ler(arquivo, {})
            with get_session() as s:
                for id_colab, dias in dados.items():
                    for dow_str, turno in dias.items():
                        existe = s.query(EscalaItem).filter_by(
                            colaborador_id=id_colab,
                            semana_inicio=segunda,
                            dia_semana=int(dow_str),
                        ).first()
                        if not existe:
                            s.add(EscalaItem(
                                colaborador_id=id_colab,
                                semana_inicio=segunda,
                                dia_semana=int(dow_str),
                                turno=turno,
                            ))
                            total_escala += 1
                s.commit()
    print(f"  {total_escala} item(ns) de escala importado(s).")

    # ── 4. Férias ─────────────────────────────────────────────────
    print("\n[4/4] Férias...")
    total_ferias = 0
    ferias_json = _ler(PASTA_RH / "ferias.json", [])
    with get_session() as s:
        for d in ferias_json:
            if s.get(Ferias, d.get("id")):
                continue
            try:
                inicio = date.fromisoformat(d["inicio"])
                fim    = date.fromisoformat(d["fim"])
            except Exception:
                print(f"  Data inválida em férias: {d}")
                continue
            s.add(Ferias(
                id=d.get("id"),
                colaborador_id=d.get("id_colab"),
                inicio=inicio,
                fim=fim,
                obs=d.get("obs") or None,
            ))
            total_ferias += 1
        s.commit()
    print(f"  {total_ferias} período(s) de férias importado(s).")

    # ── Backup dos JSONs originais ─────────────────────────────────
    backup = PASTA_RH / "backup_pre_migracao"
    backup.mkdir(exist_ok=True)
    copiados = 0
    for arq in PASTA_RH.rglob("*.json"):
        if "backup_pre_migracao" in str(arq):
            continue
        try:
            rel  = arq.relative_to(PASTA_RH)
            dest = backup / rel
            dest.parent.mkdir(parents=True, exist_ok=True)
            shutil.copy2(arq, dest)
            copiados += 1
        except Exception:
            pass   # caminho muito longo ou sem permissão — ignora
    print(f"\n  {copiados} JSON(s) preservado(s) em: {backup}")

    print("\n" + "=" * 60)
    print("MIGRAÇÃO CONCLUÍDA.")
    print("O banco okgestor.db está pronto.")
    print("=" * 60)


if __name__ == "__main__":
    migrar()
