"""Complete domain_environments.responsable_email / referent_email depuis contacts.

Match sur le nom (contacts.name ≈ responsable_nom ou referent_nom).

Usage:
    python tools/fill_emails_from_contacts.py [--dry-run]
"""
import os
import argparse
import unicodedata
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 normalize(s):
    """Normalise un nom: ASCII lowercase sans accent ni espaces multiples."""
    if not s:
        return ""
    nfkd = unicodedata.normalize("NFKD", s.strip().lower())
    ascii_str = "".join(c for c in nfkd if not unicodedata.combining(c))
    return " ".join(ascii_str.split())


def synth_email(name):
    """Genere prenom.nom@sanef.com a partir d'un nom complet.
    'Frédéric GRAFFAGNINO' -> 'frederic.graffagnino@sanef.com'
    'Pierre-Louis THOUVENOT' -> 'pierre-louis.thouvenot@sanef.com'
    """
    if not name:
        return None
    norm = normalize(name)
    parts = [p for p in norm.split() if p]
    if len(parts) < 2:
        return None
    first = parts[0]
    last = parts[-1]
    # Nettoie caracteres parasites (garde lettres + tiret + apostrophe)
    import re
    first = re.sub(r"[^a-z\-']", "", first)
    last = re.sub(r"[^a-z\-']", "", last)
    if not first or not last:
        return None
    return f"{first}.{last}@sanef.com"


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--dry-run", action="store_true")
    parser.add_argument("--overwrite", action="store_true",
                        help="Ecrase les emails existants (defaut: ne remplit que les vides)")
    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")

    # Cache contacts: normalized name -> email
    contacts = conn.execute(text(
        "SELECT name, email FROM contacts WHERE email IS NOT NULL AND email != ''"
    )).fetchall()
    name_to_email = {}
    for c in contacts:
        key = normalize(c.name)
        if key and "no-email" not in (c.email or "").lower():
            name_to_email[key] = c.email
    print(f"[INFO] {len(name_to_email)} contacts avec email")

    # Domain_environments: si overwrite, on prend tous ceux avec un nom renseigne
    if args.overwrite:
        filter_clause = "WHERE responsable_nom IS NOT NULL OR referent_nom IS NOT NULL"
    else:
        filter_clause = ("WHERE (responsable_email IS NULL OR responsable_email = '' "
                         "OR referent_email IS NULL OR referent_email = '')")
    rows = conn.execute(text(f"""
        SELECT id, responsable_nom, responsable_email, referent_nom, referent_email
        FROM domain_environments
        {filter_clause}
    """)).fetchall()
    print(f"[INFO] {len(rows)} (dom,env) a completer")

    updated = 0
    from_contacts = synth = 0
    for r in rows:
        updates = {}
        # En mode overwrite: recalcule toujours. Sinon skip si email existe.
        if r.responsable_nom and (args.overwrite or not (r.responsable_email or "").strip()):
            key = normalize(r.responsable_nom)
            email = name_to_email.get(key)
            new_email = email or synth_email(r.responsable_nom)
            if new_email and new_email != (r.responsable_email or ""):
                updates["responsable_email"] = new_email
                if email:
                    from_contacts += 1
                else:
                    synth += 1
        if r.referent_nom and (args.overwrite or not (r.referent_email or "").strip()):
            key = normalize(r.referent_nom)
            email = name_to_email.get(key)
            new_email = email or synth_email(r.referent_nom)
            if new_email and new_email != (r.referent_email or ""):
                updates["referent_email"] = new_email
                if email:
                    from_contacts += 1
                else:
                    synth += 1

        if not updates:
            continue
        if args.dry_run:
            print(f"  DRY: de_id={r.id}  {updates}")
        else:
            sets = ", ".join(f"{k}=:{k}" for k in updates)
            params = dict(updates); params["id"] = r.id
            conn.execute(text(f"UPDATE domain_environments SET {sets} WHERE id=:id"), params)
        updated += 1

    conn.close()
    print(f"\n[DONE] Maj: {updated} | depuis contacts: {from_contacts} | "
          f"synthetises (prenom.nom@sanef.com): {synth}")


if __name__ == "__main__":
    main()
