"""Repara `historico_empleados`: filas donde `tipo_contrato` es un FOLIO numérico (bug de
`cierre_mes.py`, corregido en esta rama). Seco por defecto (ROLLBACK); con --confirm escribe.

Qué hace, todo en UNA transacción:
  1. Cuenta las filas con `tipo_contrato ~ '^[0-9]+$'` (por mes) y aborta si no hay ninguna.
  2. Respalda esas filas COMPLETAS en `backups/reparar_tipo_contrato_<fecha>.csv` (antes de tocar).
  3. Pone `tipo_contrato = NULL` en esas filas, y `fecha_vencimiento_contrato = NULL` SOLO donde la
     misma fila tiene folio Y vencimiento == ingreso (nunca "vence == ingreso" suelto).
  4. Verifica que ya no quede ningún folio; si no, aborta y revierte.

El dashboard deriva el tipo con `tipoContrato(fi, fv, cargo)` (NULL/igual-al-ingreso → Indefinido), así
que la vista no cambia; solo deja de haber un número donde debe haber un tipo.

  python3 reparar_tipo_contrato_folio.py              # ensayo: ROLLBACK
  python3 reparar_tipo_contrato_folio.py --confirm    # escribe
"""
import csv
import sys
from datetime import datetime
from pathlib import Path

import psycopg2

from app_config import db_config

FOLIO = "tipo_contrato ~ '^[0-9]+$'"


def main(confirm: bool) -> int:
    conn = psycopg2.connect(**db_config(), connect_timeout=15)
    conn.autocommit = False
    cur = conn.cursor()
    try:
        cur.execute(f"SELECT fecha, count(*), count(*) FILTER (WHERE fecha_vencimiento_contrato = fecha_ingreso) "
                    f"FROM historico_empleados WHERE {FOLIO} GROUP BY fecha ORDER BY fecha")
        por_mes = cur.fetchall()
        if not por_mes:
            print("No hay filas con folio en tipo_contrato: nada que reparar.")
            conn.rollback()
            return 0
        for fecha, n, v in por_mes:
            print(f"  {fecha}: {n} con folio · {v} además con vencimiento == ingreso")

        cur.execute(f"SELECT * FROM historico_empleados WHERE {FOLIO}")
        columnas = [d[0] for d in cur.description]
        filas = cur.fetchall()
        destino = Path(__file__).parent / "backups" / f"reparar_tipo_contrato_{datetime.now():%Y%m%d_%H%M%S}.csv"
        destino.parent.mkdir(exist_ok=True)
        with destino.open("w", newline="", encoding="utf-8") as f:
            w = csv.writer(f)
            w.writerow(columnas)
            w.writerows(filas)
        print(f"Respaldo: {destino} ({len(filas)} filas)")

        cur.execute(f"UPDATE historico_empleados SET "
                    f"fecha_vencimiento_contrato = CASE WHEN fecha_vencimiento_contrato = fecha_ingreso "
                    f"THEN NULL ELSE fecha_vencimiento_contrato END, tipo_contrato = NULL WHERE {FOLIO}")
        actualizadas = cur.rowcount
        if actualizadas != len(filas):
            raise RuntimeError(f"UPDATE tocó {actualizadas} filas y el respaldo tiene {len(filas)}")
        cur.execute(f"SELECT count(*) FROM historico_empleados WHERE {FOLIO}")
        if cur.fetchone()[0] != 0:
            raise RuntimeError("Quedaron folios tras el UPDATE")
        print(f"UPDATE: {actualizadas} filas.")
        if confirm:
            conn.commit()
            print("CONFIRMADO: cambios escritos.")
        else:
            conn.rollback()
            print("ENSAYO: ROLLBACK, nada escrito. Use --confirm para escribir.")
        return 0
    except Exception as exc:  # noqa: BLE001
        conn.rollback()
        print(f"ABORTA (revertido): {exc}")
        return 1
    finally:
        conn.close()


if __name__ == "__main__":
    sys.exit(main("--confirm" in sys.argv))
