"""Import Solutions Applicatives depuis CSV iTop -> table applications.

Champs essentiels (max utile pour le patching):
 - nom_court          <- Nom
 - nom_complet        <- Nom complet
 - description        <- Description
 - editeur            <- Editeur->Nom
 - status             <- Etat (Actif/Obsolete/...)
 - criticite          <- Criticité (basse/standard/haute/critique)
 - responsable_dsi    <- Responsable de service - DSI (nom + email)
 - admin_technique    <- Administrateur technique (nom + email)

Ajoute colonnes responsable_dsi_*/admin_tech_* si absentes.

Usage:
    python tools/import_sanef_applications.py <csv> [--truncate] [--dry-run]
"""
import os
import csv
import argparse
from sqlalchemy import create_engine, text

DATABASE_URL = os.getenv("DATABASE_URL_DEMO") or os.getenv("DATABASE_URL") \
    or "postgresql://patchcenter:PatchCenter2026!@localhost:5432/patchcenter_demo"


def clean(v):
    if v is None:
        return None
    s = str(v).strip().replace("\xa0", " ")
    return s or None


CRIT_MAP = {
    "critique": "critique", "haute": "haute",
    "standard": "standard", "basse": "basse", "faible": "basse",
}


def norm_crit(v):
    if not v:
        return "standard"
    s = v.strip().lower()
    return CRIT_MAP.get(s, "standard")


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("csv_path")
    parser.add_argument("--truncate", action="store_true")
    parser.add_argument("--dry-run", action="store_true")
    args = parser.parse_args()

    engine = create_engine(DATABASE_URL)
    print(f"[INFO] DB: {DATABASE_URL.split('@')[-1]}")
    conn = engine.connect().execution_options(isolation_level="AUTOCOMMIT")

    # Colonnes supplementaires
    conn.execute(text("ALTER TABLE applications ADD COLUMN IF NOT EXISTS responsable_dsi_nom varchar(200)"))
    conn.execute(text("ALTER TABLE applications ADD COLUMN IF NOT EXISTS responsable_dsi_email varchar(255)"))
    conn.execute(text("ALTER TABLE applications ADD COLUMN IF NOT EXISTS admin_tech_nom varchar(200)"))
    conn.execute(text("ALTER TABLE applications ADD COLUMN IF NOT EXISTS admin_tech_email varchar(255)"))
    conn.execute(text("ALTER TABLE applications ADD COLUMN IF NOT EXISTS etat varchar(30)"))

    if args.truncate and not args.dry_run:
        conn.execute(text("TRUNCATE applications RESTART IDENTITY CASCADE"))
        print("[INFO] applications vidée")

    with open(args.csv_path, "r", encoding="utf-8-sig", newline="") as f:
        sample = f.read(4096); f.seek(0)
        delim = ";" if sample.count(";") > sample.count(",") else ","
        rows = list(csv.DictReader(f, delimiter=delim))
    print(f"[INFO] {len(rows)} lignes (delim={delim!r})")

    stats = {"inserted": 0, "updated": 0, "skipped": 0}

    for r in rows:
        nom = clean(r.get("Nom"))
        if not nom:
            stats["skipped"] += 1
            continue

        vals = {
            "nom_court": nom[:50],
            "nom_complet": clean(r.get("Nom complet") or nom)[:200] if clean(r.get("Nom complet") or nom) else None,
            "description": clean(r.get("Description")),
            "editeur": (clean(r.get("Editeur->Nom")) or "")[:100] or None,
            "criticite": norm_crit(r.get("Criticité")),
            "etat": clean(r.get("Etat"))[:30] if clean(r.get("Etat")) else None,
            "resp_nom": clean(r.get("Responsable de service - DSI->Nom complet")
                              or r.get("Responsable de service - DSI->Nom")),
            "resp_email": clean(r.get("Responsable de service - DSI->Email")),
            "admin_nom": clean(r.get("Administrateur technique->Nom complet")
                               or r.get("Administrateur technique->Nom")),
            "admin_email": clean(r.get("Administrateur technique->Email")),
        }

        if args.dry_run:
            print(f"  DRY: {vals['nom_court']:30s} [{vals['etat'] or '-'}] "
                  f"resp={vals['resp_nom'] or '-'}")
            continue

        try:
            existing = conn.execute(text("SELECT id FROM applications WHERE nom_court=:n"),
                                    {"n": vals["nom_court"]}).fetchone()
            if existing:
                conn.execute(text("""
                    UPDATE applications SET
                        nom_complet=:nom_complet, description=:description,
                        editeur=:editeur, criticite=:criticite, etat=:etat,
                        responsable_dsi_nom=:resp_nom, responsable_dsi_email=:resp_email,
                        admin_tech_nom=:admin_nom, admin_tech_email=:admin_email,
                        updated_at=now()
                    WHERE id=:id
                """), {**vals, "id": existing.id})
                stats["updated"] += 1
            else:
                conn.execute(text("""
                    INSERT INTO applications
                    (nom_court, nom_complet, description, editeur, criticite, etat,
                     responsable_dsi_nom, responsable_dsi_email,
                     admin_tech_nom, admin_tech_email)
                    VALUES (:nom_court, :nom_complet, :description, :editeur,
                            :criticite, :etat,
                            :resp_nom, :resp_email, :admin_nom, :admin_email)
                """), vals)
                stats["inserted"] += 1
        except Exception as e:
            print(f"  [ERR] {vals['nom_court']}: {str(e)[:120]}")
            stats["skipped"] += 1

    conn.close()
    print(f"\n[DONE] Inserts: {stats['inserted']} | Updates: {stats['updated']} | Skip: {stats['skipped']}")


if __name__ == "__main__":
    main()
