#!/usr/bin/env python3
"""
VBS Element 3 & 4 — Cross-Reference Integration Fix Script
Adds cross-reference sections to 13 documents with version bump.
"""

from docx import Document
from docx.shared import Pt, Cm, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT
import shutil, os, re

# ── Style constants ──
HEADING_COLOR = RGBColor(0x00, 0x33, 0x66)
BODY_FONT = 'Calibri'
BODY_SIZE = Pt(11)

DOCUMENTS = [
    {
        "id": "E3#01",
        "path": "/root/projects/jg/2026-PM-VBS-Element3/deliverables/docx/PM_VBS03_01_Control_of_Work_v1.1.docx",
        "new_version": "v1.2",
        "title": "Noodwerk Vergunningsprocedure",
        "rows": [
            ["E4#06", "Noodinspectie & Herstel", "Versneld CoW-proces bij noodherstel; crisisleider kan noodvergunning afgeven"],
        ],
        "extra_text": (
            "Bij noodherstel werkt het Control of Work (CoW) systeem versneld. "
            "De crisisleider (zie E4#06 Noodinspectie & Herstel) is bevoegd om een noodvergunning af te geven "
            "zonder de volledige goedkeuringsketen te doorlopen. Na afloop van het noodherstel wordt de noodvergunning "
            "retroactief geëvalueerd en gedocumenteerd."
        ),
    },
    {
        "id": "E3#02",
        "path": "/root/projects/jg/2026-PM-VBS-Element3/deliverables/docx/PM_VBS03_02_Heet_Werk_Vonken_v1.0.docx",
        "new_version": "v1.1",
        "title": "ATEX-zone Pre-conditie (E2#06)",
        "rows": [
            ["E2#06", "ATEX-zone Classificatie", "VERPLICHTE ATEX-zone check als pre-conditie voor heet werk"],
        ],
        "extra_text": (
            "Voorafgaand aan elke heet werk vergunning is een VERPLICHTE ATEX-zone check vereist (E2#06). "
            "Heet werk in ATEX zone 20, 21 of 22 is verboden zonder uitgebreide Task Risk Analysis (TRA). "
            "De TRA moet specifieke maatregelen bevatten voor explosieve atmosferen."
        ),
    },
    {
        "id": "E3#05",
        "path": "/root/projects/jg/2026-PM-VBS-Element3/deliverables/docx/PM_VBS03_05_Onderhoud_v1.1.docx",
        "new_version": "v1.2",
        "title": "Koppeling met Noodinspectie (E4#06)",
        "rows": [
            ["E4#06", "Noodinspectie & Herstel", "Onderhoudsstatus raadplegen na incident voor schadebeoordeling; onderhoudslog als input voor herstelplan"],
        ],
        "extra_text": (
            "Na een incident wordt de actuele onderhoudsstatus geraadpleegd voor schadebeoordeling. "
            "Het onderhoudslog dient als input voor het E4#06 Noodinspectie & Herstel herstelplan. "
            "Dit omvat openstaande werkorders, recente reparaties en gepland onderhoud."
        ),
    },
    {
        "id": "E3#08",
        "path": "/root/projects/jg/2026-PM-VBS-Element3/deliverables/docx/PM_VBS03_08_PSSR_v1.1.docx",
        "new_version": "v1.2",
        "title": "PSSR bij Herstart na Incident (E4#06)",
        "rows": [
            ["E4#06", "Noodinspectie & Herstel", "VERPLICHTE PSSR bij herstart na incident; herstart alleen na E4#06 fase 7 goedkeuring"],
        ],
        "extra_text": (
            "Een VERPLICHTE Pre-Startup Safety Review (PSSR) is vereist bij herstart na elk incident. "
            "De herstart mag pas plaatsvinden na goedkeuring in fase 7 van het E4#06 Noodinspectie & Herstel protocol. "
            "De PSSR resultaten worden formeel gedocumenteerd en gearchiveerd."
        ),
    },
    {
        "id": "E3#09",
        "path": "/root/projects/jg/2026-PM-VBS-Element3/deliverables/docx/PM_VBS03_09_Operationele_Inspectie_v1.1.docx",
        "new_version": "v1.2",
        "title": "Opschalingsprotocol naar Noodinspectie (E4#06)",
        "rows": [
            ["E4#06", "Noodinspectie & Herstel", "Criteria voor escalatie van routine-inspectie naar noodinspectie"],
        ],
        "extra_text": (
            "Wanneer een routine-inspectie ernstige afwijkingen constateert die direct veiligheidsrisico's opleveren, "
            "wordt opgeschaald naar E4#06 Noodinspectie. Opschalingscriteria omvatten: structurele schade, "
            "lekken van gevaarlijke stoffen, falen van primaire barrières, en directe bedreiging van personeelsveiligheid."
        ),
    },
    {
        "id": "E3#10",
        "path": "/root/projects/jg/2026-PM-VBS-Element3/deliverables/docx/PM_VBS03_10_KPI_Matrix_v1.1.docx",
        "new_version": "v1.2",
        "title": "Noodresponse KPI's",
        "rows": [
            ["E4#03", "BHV Organisatie", "Responstijd BHV — target: < 3 minuten"],
            ["E4#07", "Oefenprogramma", "Oefenfrequentie — minimaal 4x per jaar per team"],
            ["E4#05", "Crisiscommunicatie", "Crisiscommunicatie response tijd — target: < 15 minuten"],
        ],
        "extra_text": (
            "De KPI Matrix bevat noodresponse-indicatoren die de effectiviteit van de noodorganisatie meten. "
            "Deze KPI's worden kwartaallijks geëvalueerd en ingevoerd in het management review proces."
        ),
    },
    {
        "id": "E4#01",
        "path": "/root/projects/jg/2026-PM-VBS-Element4/deliverables/docx/PM_VBS04_01_Bedrijfsnoodplan_v1.0.docx",
        "new_version": "v1.1",
        "title": "Beleids- en Analyse-koppelingen",
        "rows": [
            ["E1#01", "PBZO Beleidsdocument", "Strategisch kader voor bedrijfsnoodplan"],
            ["E1#03", "Organigram", "Noodorganisatie rollen en verantwoordelijkheden"],
            ["E2#08", "BowTie Analyse", "Barrières falen = noodscenario; input voor scenario-definitie"],
        ],
        "extra_text": (
            "Het bedrijfsnoodplan is gebaseerd op het PBZO-beleid (E1#01) en de daarin gedefinieerde strategische kaders. "
            "De noodorganisatie-rollen zijn afgeleid van het organigram (E1#03). "
            "BowTie-analyses (E2#08) identificeren welke barrières kunnen falen en leiden tot noodscenario's."
        ),
    },
    {
        "id": "E4#02",
        "path": "/root/projects/jg/2026-PM-VBS-Element4/deliverables/docx/PM_VBS04_02_Noodprocedures_Scenario's_v1.1.docx",
        "new_version": "v1.2",
        "title": "Scenario-input uit Risicoanalyses",
        "rows": [
            ["E2#01", "Stofinventarisatie", "Stoffen data als input voor chemische noodscenario's"],
            ["E2#07", "HAZOP", "Deviaties → scenario-ontwikkeling voor noodprocedures"],
            ["E2#08", "BowTie Analyse", "Barrières → preventie-maatregelen in noodprocedures"],
        ],
        "extra_text": (
            "Noodscenario's worden ontwikkeld op basis van data uit de stofinventarisatie (E2#01), "
            "HAZOP-deviaties (E2#07) en BowTie-barrièreanalyses (E2#08). "
            "Dit waarborgt dat noodprocedures aansluiten bij de geïdentificeerde risico's."
        ),
    },
    {
        "id": "E4#03",
        "path": "/root/projects/jg/2026-PM-VBS-Element4/deliverables/docx/PM_VBS04_03_BHV_Organisatie_v1.1.docx",
        "new_version": "v1.2",
        "title": "Training & Certificering (E1#04)",
        "rows": [
            ["E1#04", "Training Matrix", "Hercertificering BHV via training matrix; BHV-training opnemen in E1#04"],
        ],
        "extra_text": (
            "BHV-hercertificering wordt aangestuurd via de E1#04 Training Matrix. "
            "Alle BHV-trainingen zijn opgenomen in de matrix met geldigheidsduren en herhalingsfrequentie. "
            "Dit waarborgt dat alle BHV'ers te allen tijde gecertificeerd zijn."
        ),
    },
    {
        "id": "E4#05",
        "path": "/root/projects/jg/2026-PM-VBS-Element4/deliverables/docx/PM_VBS04_05_Crisiscommunicatie_v1.1.docx",
        "new_version": "v1.2",
        "title": "Communicatie- & Organisatie-koppelingen",
        "rows": [
            ["E1#12", "Communicatie Meldingsprocedure", "Meldingsprocedure voor crisiscommunicatie"],
            ["E1#03", "Organigram", "Communicatieverantwoordelijken en autoriteitsniveaus"],
        ],
        "extra_text": (
            "De crisiscommunicatieprocedure sluit aan bij de E1#12 Communicatie Meldingsprocedure. "
            "Communicatieverantwoordelijken en hun autoriteitsniveaus zijn vastgelegd in het E1#03 Organigram."
        ),
    },
    {
        "id": "E4#06",
        "path": "/root/projects/jg/2026-PM-VBS-Element4/deliverables/docx/PM_VBS04_06_Noodinspectie_Herstel_v1.1.docx",
        "new_version": "v1.2",
        "title": "Herstart & Onderhouds-koppelingen",
        "rows": [
            ["E3#08", "PSSR", "VERPLICHTE PSSR bij herstart na noodherstel"],
            ["E3#05", "Onderhoud", "Onderhoudslog als input voor herstelplan"],
            ["E3#09", "Operationele Inspectie", "Inspectie data voor schadebeoordeling"],
        ],
        "extra_text": (
            "Bij herstart na noodherstel is een VERPLICHTE PSSR (E3#08) vereist. "
            "Het onderhoudslog (E3#05) en inspectie data (E3#09) dienen als input voor het herstelplan."
        ),
    },
    {
        "id": "E4#07",
        "path": "/root/projects/jg/2026-PM-VBS-Element4/deliverables/docx/PM_VBS04_07_Oefenprogramma_v1.1.docx",
        "new_version": "v1.2",
        "title": "Training Matrix Koppeling (E1#04)",
        "rows": [
            ["E1#04", "Training Matrix", "Oefeningen afgestemd op training; jaarplanning afstemmen met trainingsschema"],
        ],
        "extra_text": (
            "Oefeningen worden voorbereid met de bijbehorende training uit E1#04 Training Matrix. "
            "De jaarplanning van het oefenprogramma wordt afgestemd met het trainingsschema om synergie te waarborgen."
        ),
    },
    {
        "id": "E4#08",
        "path": "/root/projects/jg/2026-PM-VBS-Element4/deliverables/docx/PM_VBS04_08_Formulierenpakket_v1.1.docx",
        "new_version": "v1.2",
        "title": "Risicoclassificatie Referenties",
        "rows": [
            ["E3#07", "Risicobeheersmaatregelen", "Risicoclassificatie methodiek voor formulieren"],
            ["E2#03", "Risicoanalyse", "Risicomatrix en classificatiecriteria"],
        ],
        "extra_text": (
            "Formulieren in dit pakket verwijzen naar de risicoclassificatie uit E3#07 Risicobeheersmaatregelen "
            "en E2#03 Risicoanalyse voor consistente toepassing van risicomatrix en classificatiecriteria."
        ),
    },
]


def set_cell_text(cell, text, bold=False, size=BODY_SIZE):
    """Set cell text with formatting."""
    cell.text = ""
    p = cell.paragraphs[0]
    run = p.add_run(text)
    run.font.name = BODY_FONT
    run.font.size = size
    run.font.bold = bold


def find_insertion_index(doc):
    """Find insertion point: before Bronnenlijst/TierVerify/last section."""
    for i, para in enumerate(doc.paragraphs):
        text = para.text.lower()
        if any(kw in text for kw in ['bronnen', 'bronnverwijzing', 'tierverify', 'verify', 'referenties']):
            return i
    # If nothing found, insert before last 2 paragraphs
    return max(len(doc.paragraphs) - 1, 1)


def process_document(doc_info):
    """Process a single document: add cross-reference section."""
    src = doc_info["path"]
    
    if not os.path.exists(src):
        print(f"  ⚠️  SKIP: {src} not found")
        return False
    
    # Determine new filename
    base = os.path.splitext(os.path.basename(src))[0]
    # Replace version suffix
    new_base = re.sub(r'_v\d+\.\d+$', f'_{doc_info["new_version"]}', base)
    new_path = src.replace(os.path.basename(src), new_base + '.docx')
    
    # Copy to new version
    shutil.copy2(src, new_path)
    
    doc = Document(new_path)
    
    # Find insertion point
    idx = find_insertion_index(doc)
    
    # Insert heading + table + text before that point
    # We add paragraphs at the end and then move them... 
    # Actually python-docx doesn't support easy insertion at index, 
    # so we add at end and use XML manipulation
    
    from docx.oxml.ns import qn
    import copy
    
    body = doc.element.body
    
    # Find the paragraph element at insertion index
    target_para = doc.paragraphs[idx]
    target_elem = target_para._element
    
    # Create heading
    heading_para = doc.add_paragraph()
    heading_para.style = doc.styles['Heading 2']
    run = heading_para.add_run(doc_info["title"])
    run.font.color.rgb = HEADING_COLOR
    
    # Create table
    num_rows = len(doc_info["rows"]) + 1
    table = doc.add_table(rows=num_rows, cols=3)
    table.style = 'Light Grid Accent 1'
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    
    # Header row
    for j, header in enumerate(["VBS Referentie", "Document", "Koppeling / Beschrijving"]):
        set_cell_text(table.rows[0].cells[j], header, bold=True)
    
    # Data rows
    for i, row_data in enumerate(doc_info["rows"]):
        for j, val in enumerate(row_data):
            set_cell_text(table.rows[i+1].cells[j], val)
    
    # Extra text paragraph
    extra_para = doc.add_paragraph()
    extra_para.paragraph_format.space_before = Pt(6)
    run = extra_para.add_run(doc_info.get("extra_text", ""))
    run.font.name = BODY_FONT
    run.font.size = BODY_SIZE
    
    # Move inserted elements before target
    # The added elements are at the end of body; move them before target_elem
    heading_elem = heading_para._element
    table_elem = table._element
    extra_elem = extra_para._element
    
    # Remove from current position, insert before target
    body.remove(heading_elem)
    body.remove(table_elem)
    body.remove(extra_elem)
    
    target_elem.addprevious(heading_elem)
    heading_elem.addnext(table_elem)
    table_elem.addnext(extra_elem)
    
    doc.save(new_path)
    print(f"  ✅ {os.path.basename(new_path)}")
    return True


def main():
    print("=" * 60)
    print("VBS Element 3 & 4 — Cross-Reference Integration Fix")
    print("=" * 60)
    
    success = 0
    failed = 0
    
    for doc_info in DOCUMENTS:
        print(f"\n📌 {doc_info['id']}: {doc_info['title']}")
        try:
            if process_document(doc_info):
                success += 1
            else:
                failed += 1
        except Exception as e:
            print(f"  ❌ ERROR: {e}")
            failed += 1
    
    print(f"\n{'=' * 60}")
    print(f"Resultaat: {success} succes, {failed} overgeslagen/fout")
    print(f"{'=' * 60}")


if __name__ == "__main__":
    main()
