#!/usr/bin/env python3
"""
Estrae dai file .docx originali i campi Inquadramento che l'import di mesi fa
NON aveva importato per i Word: descrizione immobile + rischi (sismico,
idrogeologico, ambientale). NON tocca il database: produce solo un JSON.

Uso:
  python3 import-tools/scripts/fix_docx_inquadramento.py > /tmp/docx_inq.json
"""
import sys, os, re, json, glob
from docx import Document

DVR_DIR = os.path.join(os.path.dirname(__file__), "..", "..", "-mat", "DVR")

# Paragrafi che segnano la fine della DESCRIZIONE IMMOBILE.
STOP_DESCR = re.compile(
    r"INDIVIDUAZIONE DEI PERICOLI|METODO DELLA MATRICE|DATI IDENTIFICATIVI|"
    r"PIANO DI GESTIONE|RISCHIO INCENDIO|VALUTAZIONE SECONDO|PIANO DI MIGLIORAMENTO",
    re.I,
)
NON_PRESENTE = re.compile(r"non\s+presente|assente|nessun|non\s+applicabile", re.I)


def norm(s):
    if s is None:
        return None
    s = re.sub(r"[ \t]+", " ", s).strip()
    return s or None


def estrai_descrizione(doc):
    paras = [p.text.strip() for p in doc.paragraphs]
    idx = None
    for i, t in enumerate(paras):
        if "DESCRIZIONE IMMOBILE" in t.upper():
            idx = i
            break
    if idx is None:
        return None
    buf = []
    for t in paras[idx + 1:]:
        if not t:
            continue
        if STOP_DESCR.search(t):
            break
        buf.append(t)
    return norm(" ".join(buf)) if buf else None


def si_no(val):
    """1 = rischio presente, 0 = non presente, None = sconosciuto."""
    if not val:
        return None
    if NON_PRESENTE.search(val):
        return 0
    return 1


def estrai_rischi(doc):
    out = {
        "rischio_sismico_descr": None,
        "rischio_idro_si_no": None,
        "rischio_idro_descr": None,
        "rischio_ambientale_si_no": None,
        "rischio_ambientale_descr": None,
    }
    for t in doc.tables:
        for row in t.rows:
            cells = [c.text.strip() for c in row.cells]
            if not cells or not cells[0]:
                continue
            key = cells[0].upper()
            val = norm(" ".join(c for c in cells[1:] if c)) if len(cells) > 1 else None
            if "SISMIC" in key and out["rischio_sismico_descr"] is None:
                out["rischio_sismico_descr"] = val
            elif "IDROGEOLOG" in key and out["rischio_idro_descr"] is None:
                out["rischio_idro_descr"] = val
                out["rischio_idro_si_no"] = si_no(val)
            elif "AMBIENTAL" in key and out["rischio_ambientale_descr"] is None:
                out["rischio_ambientale_descr"] = val
                out["rischio_ambientale_si_no"] = si_no(val)
    return out


def estrai_fallback(path):
    """Per i docx che python-docx non apre (es. immagine con CRC rotto): legge
    il solo word/document.xml dallo zip e ricava il testo dei paragrafi."""
    import zipfile, html

    with zipfile.ZipFile(path) as z:
        xml = z.read("word/document.xml").decode("utf-8", "ignore")
    paras = []
    for pblock in re.split(r"</w:p>", xml):
        texts = re.findall(r"<w:t[^>]*>(.*?)</w:t>", pblock, re.S)
        paras.append(html.unescape("".join(texts)).strip())

    rec = {
        "descrizione_immobile": None,
        "rischio_sismico_descr": None,
        "rischio_idro_si_no": None,
        "rischio_idro_descr": None,
        "rischio_ambientale_si_no": None,
        "rischio_ambientale_descr": None,
    }
    idx = next((i for i, t in enumerate(paras) if "DESCRIZIONE IMMOBILE" in t.upper()), None)
    if idx is not None:
        buf = []
        for t in paras[idx + 1:]:
            if not t:
                continue
            if STOP_DESCR.search(t):
                break
            buf.append(t)
        rec["descrizione_immobile"] = norm(" ".join(buf))

    def next_val(keyword):
        for i, t in enumerate(paras):
            if keyword in t.upper():
                for t2 in paras[i + 1:]:
                    if t2.strip():
                        return norm(t2)
        return None

    rec["rischio_sismico_descr"] = next_val("RISCHIO SISMIC")
    idro = next_val("RISCHIO IDROGEOLOG")
    rec["rischio_idro_descr"] = idro
    rec["rischio_idro_si_no"] = si_no(idro)
    amb = next_val("RISCHIO AMBIENTAL")
    rec["rischio_ambientale_descr"] = amb
    rec["rischio_ambientale_si_no"] = si_no(amb)
    return rec


def main():
    files = sorted(glob.glob(os.path.join(DVR_DIR, "*.docx")))
    result = {}
    errori = 0
    for f in files:
        name = os.path.basename(f)
        try:
            doc = Document(f)
            rec = {"descrizione_immobile": estrai_descrizione(doc)}
            rec.update(estrai_rischi(doc))
            result[name] = rec
        except Exception:
            try:
                result[name] = estrai_fallback(f)
                sys.stderr.write(f"FALLBACK XML usato per {name}\n")
            except Exception as e2:
                errori += 1
                sys.stderr.write(f"ERRORE su {name}: {e2}\n")
    sys.stderr.write(f"Elaborati {len(result)} docx, {errori} errori.\n")
    json.dump(result, sys.stdout, ensure_ascii=False, indent=0)


if __name__ == "__main__":
    main()
