#!/usr/bin/env python3
"""
Allinea il DVR di UNA sede al suo file Word, dopo un import_dvr.py mirato.

Serve perché il parser dell'import, per i Word, perde i punteggi P e G della
Valutazione e appiattisce i testi su più righe dei Pericoli: sono gli stessi
difetti già corretti in produzione sui 196 Word ad agosto e settembre, qui
applicati a un singolo DVR appena reimportato in uno snapshot locale.

Legge le celle con row._tr.tc_lst, mai row.cells.

  python3 import-tools/scripts/allinea_dvr_docx.py <snapshot.db> <file.docx> <agenzia_id>        # dry-run
  python3 import-tools/scripts/allinea_dvr_docx.py <snapshot.db> <file.docx> <agenzia_id> --apply
"""
import sys, os, re, sqlite3, warnings
warnings.filterwarnings("ignore")
from docx import Document

db_path, docx_path, agenzia_id = sys.argv[1], sys.argv[2], int(sys.argv[3])
APPLY = "--apply" in sys.argv
db = sqlite3.connect(db_path)
cur = db.cursor()

def n(s):
    s = re.sub(r"[ \t]+", " ", str(s or "")).strip()
    return s or None
def cells(row): return [n("".join(x.text for x in tc.iter() if x.tag.endswith("}t"))) for tc in row._tr.tc_lst]
def ip(v):
    try: x = int(v)
    except (TypeError, ValueError): return None
    return x if 0 <= x <= 4 else None
def ig(v):
    try: x = int(v)
    except (TypeError, ValueError): return None
    return x if 1 <= x <= 4 else None

doc = Document(docx_path)
dvr_id = cur.execute("SELECT id FROM dvr WHERE agenzia_id = ?", (agenzia_id,)).fetchone()
if not dvr_id: sys.exit(f"Nessun DVR per l'agenzia {agenzia_id}")
dvr_id = dvr_id[0]

# ── Pericoli: testo di Verifica (C) e Note (F) così come stanno nel file
peric = {}
for t in doc.tables:
    for row in t.rows:
        c = cells(row)
        if c and c[0] and re.match(r"^\d+(\.\d+)+\.?$", c[0]) and len(c) >= 6:
            peric.setdefault(c[0].rstrip("."), (c[2], c[5]))

n_per = 0
for rif, (col_c, col_f) in peric.items():
    r = cur.execute("""SELECT p.id, COALESCE(c.testo, p.col_c_override), COALESCE(f.testo, p.col_f_override)
                       FROM dvr_pericoli p JOIN lookup_pericoli_punti pt ON pt.id = p.punto_id
                       LEFT JOIN lookup_pericoli_combo c ON c.id = p.col_c_lookup_id
                       LEFT JOIN lookup_pericoli_combo f ON f.id = p.col_f_lookup_id
                       WHERE p.dvr_id = ? AND pt.rif = ?""", (dvr_id, rif)).fetchone()
    if not r: continue
    pid, cur_c, cur_f = r
    if n(cur_c) == col_c and n(cur_f) == col_f: continue
    n_per += 1
    if APPLY:
        cur.execute("""UPDATE dvr_pericoli SET col_c_lookup_id = NULL, col_c_override = ?,
                                               col_f_lookup_id = NULL, col_f_override = ? WHERE id = ?""",
                    (col_c, col_f, pid))

# ── Valutazione: P e G dal file (l'import dei Word non li prende)
elem = {nome: eid for eid, nome in cur.execute("SELECT id, nome FROM lookup_valutazione_elementi")}
n_val = 0
for t in doc.tables:
    for row in t.rows:
        c = cells(row)
        if not c or not c[0] or len(c) < 7: continue
        eid = elem.get(c[0])
        if eid is None: continue
        p, g = ip(c[4]), ig(c[5])
        if p is None or g is None: continue
        r = cur.execute("SELECT id, p, g FROM dvr_valutazione WHERE dvr_id = ? AND elemento_id = ?", (dvr_id, eid)).fetchone()
        if not r or (r[1], r[2]) == (p, g): continue
        n_val += 1
        if APPLY: cur.execute("UPDATE dvr_valutazione SET p = ?, g = ? WHERE id = ?", (p, g, r[0]))

# ── Inquadramento: descrizione immobile e rischi territoriali, che il parser
# dei Word non importava affatto (stesso recupero fatto a luglio sugli altri).
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import json, subprocess
inq = json.loads(subprocess.run([sys.executable, os.path.join(os.path.dirname(os.path.abspath(__file__)), "fix_docx_inquadramento.py")],
                                capture_output=True, text=True).stdout or "{}").get(os.path.basename(docx_path), {})
campi = ("descrizione_immobile", "rischio_sismico_descr", "rischio_idro_si_no", "rischio_idro_descr",
         "rischio_ambientale_si_no", "rischio_ambientale_descr")
attuale = dict(zip(campi, cur.execute(f"SELECT {', '.join(campi)} FROM dvr WHERE id = ?", (dvr_id,)).fetchone()))
da_scrivere = {k: (int(v) if k.endswith("si_no") and v is not None else v)
               for k, v in inq.items() if k in campi and v is not None and attuale.get(k) is None}
if da_scrivere and APPLY:
    cur.execute(f"UPDATE dvr SET {', '.join(k + ' = ?' for k in da_scrivere)} WHERE id = ?",
                (*da_scrivere.values(), dvr_id))

print(f"{'APPLY' if APPLY else 'DRY-RUN'} — DVR {dvr_id} (agenzia {agenzia_id}) ← {os.path.basename(docx_path)}")
print(f"  pericoli con testo da allineare: {n_per}")
print(f"  valutazioni con P/G da scrivere: {n_val}")
print(f"  campi Inquadramento da riempire: {len(da_scrivere)} {list(da_scrivere)}")
if APPLY:
    db.commit()
    print("  scritto.")
