"""Motor de Recuperación de Licencias invocado por la capa PHP.

Uso:
    python recuperacion_engine.py --excel <ruta.xlsx> --modo prueba|envio --job <id>

Escribe avance y resultados en estado/<job>.json (PHP lo consulta y luego
guarda los resultados en MySQL).
"""
import argparse
import json
import os
import time
import traceback
from datetime import datetime

from recuperacion_reader import leer_recuperaciones
from recuperacion import RecuperacionBot
from automation import LicenciaError

ESTADO_DIR = "estado"


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--excel", required=True)
    ap.add_argument("--modo", choices=["prueba", "envio"], default="prueba")
    ap.add_argument("--job", required=True)
    args = ap.parse_args()

    os.makedirs(ESTADO_DIR, exist_ok=True)
    ruta_estado = os.path.join(ESTADO_DIR, f"{args.job}.json")
    enviar = args.modo == "envio"

    estado = {
        "corriendo": True, "terminado": False, "modo": args.modo,
        "total": 0, "progreso": 0, "paso": "Iniciando...",
        "log": [], "resultados": [], "excel": args.excel,
        "inicio": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
    }

    def guardar():
        tmp = ruta_estado + ".tmp"
        try:
            with open(tmp, "w", encoding="utf-8") as f:
                json.dump(estado, f, ensure_ascii=False)
        except Exception:
            return
        for _ in range(20):
            try:
                os.replace(tmp, ruta_estado); return
            except PermissionError:
                time.sleep(0.1)
            except Exception:
                break
        try:
            with open(ruta_estado, "w", encoding="utf-8") as f:
                json.dump(estado, f, ensure_ascii=False)
            if os.path.exists(tmp):
                os.remove(tmp)
        except Exception:
            pass

    def log(msg):
        estado["log"].append(f"[{datetime.now():%H:%M:%S}] {msg}")
        guardar()

    guardar()
    try:
        registros = leer_recuperaciones(args.excel)
        total = len(registros) or 1
        estado["total"] = len(registros)
        log(f"{len(registros)} recuperación(es) a procesar. Modo: "
            f"{'ENVÍO REAL' if enviar else 'PRUEBA (no graba)'}")

        with RecuperacionBot(headless=True) as bot:
            estado["paso"] = "Iniciando sesión..."; guardar()
            log("Iniciando sesión en el sistema...")
            bot.login()
            bot.abrir()
            log("Sesión iniciada; página de Recuperación abierta.")

            for i, reg in enumerate(registros):
                fila = reg.get("_fila_excel")
                # Si la fila trae avisos de validación (RUT/licencia), no procesar
                if reg.get("avisos"):
                    coment = "ERROR: " + " · ".join(reg["avisos"])
                    estado["resultados"].append({
                        "fila": fila, "rut": reg.get("rut"),
                        "num_licencia": reg.get("num_licencia"),
                        "estado": "ERROR", "comentario": coment, "error": coment})
                    log(f"Fila {fila}: {coment}")
                    estado["progreso"] = int((i + 1) / total * 100); guardar()
                    continue

                log(f"Fila {fila} · RUT {reg['rut']} · Lic {reg['num_licencia']} — procesando...")

                def cb(frac, texto, _i=i, _fila=fila):
                    estado["progreso"] = min(100, int((_i + frac) / total * 100))
                    estado["paso"] = f"Recuperación {_i + 1}/{total} (fila {_fila}): {texto}"
                    guardar()

                try:
                    r = bot.procesar_fila(reg, enviar=enviar, prog=cb)
                    if not enviar:
                        coment = "Prueba OK (no grabado)"
                    elif r.get("enviado"):
                        coment = "Grabado"
                    else:
                        coment = r.get("comentario", "Revisar: no se confirmó el grabado")
                    if r.get("avisos"):
                        coment += " · " + " · ".join(r["avisos"])
                    r["estado"] = "OK" if (not enviar or r.get("enviado")) else "ERROR"
                    r["comentario"] = coment
                    r["excel_origen"] = os.path.basename(args.excel)
                    estado["resultados"].append(r)
                    estado["progreso"] = int((i + 1) / total * 100)
                    log(f"Fila {fila}: {coment} — {r.get('nombre')}")
                except (LicenciaError, Exception) as e:
                    estado["resultados"].append({
                        "fila": fila, "rut": reg.get("rut"),
                        "num_licencia": reg.get("num_licencia"),
                        "estado": "ERROR", "comentario": f"ERROR: {e}", "error": str(e)})
                    log(f"Fila {fila}: ERROR — {e}")
                    estado["progreso"] = int((i + 1) / total * 100); guardar()
        estado["progreso"] = 100
        estado["paso"] = "Proceso finalizado."
        log("Proceso finalizado.")
    except Exception as e:
        estado["paso"] = f"Error: {e}"
        log(f"FALLO GENERAL: {e}")
        log(traceback.format_exc())
    finally:
        estado["corriendo"] = False
        estado["terminado"] = True
        guardar()


if __name__ == "__main__":
    main()
