#!/usr/bin/env python3
"""PGS-15 Compliance Checklist Generator — Phoenix Metals IJmuiden"""

from docx import Document
from docx.shared import Inches, Pt, Cm, RGBColor, Emu
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.oxml.ns import qn, nsdecls
from docx.oxml import parse_xml
import os

OUT = "/root/projects/jg/2026-pgs15-phoenix-metals/deliverables/docx/PGS15_Compliance_Checklist_v1.0.docx"
LOGO = "/root/projects/jg/2026-pgs15-phoenix-metals/assets/branding/jvg-consultancy-logo.jpg"
HDR_COLOR = "#003366"

doc = Document()

# --- Styles ---
style = doc.styles['Normal']
style.font.name = 'Calibri'
style.font.size = Pt(11)
style.font.color.rgb = RGBColor(0x1F, 0x29, 0x37)
style.paragraph_format.space_after = Pt(6)
style.paragraph_format.line_spacing = 1.15

for lvl, sz in [(1, 16), (2, 14), (3, 12)]:
    s = doc.styles[f'Heading {lvl}']
    s.font.name = 'Calibri'
    s.font.size = Pt(sz)
    s.font.bold = True
    s.font.color.rgb = RGBColor(0x00, 0x33, 0x66)

# --- Helpers ---
def set_cell_shading(cell, color):
    shading = parse_xml(f'<w:shd {nsdecls("w")} w:fill="{color.replace("#","")}" w:val="clear"/>')
    cell._tc.get_or_add_tcPr().append(shading)

def make_header_row(table, texts):
    row = table.rows[0]
    for i, txt in enumerate(texts):
        c = row.cells[i]
        c.text = ""
        p = c.paragraphs[0]
        run = p.add_run(txt)
        run.bold = True
        run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
        run.font.name = 'Calibri'
        run.font.size = Pt(10)
        p.alignment = WD_ALIGN_PARAGRAPH.LEFT
        set_cell_shading(c, HDR_COLOR)

def add_table(doc, headers, rows):
    cols = len(headers)
    t = doc.add_table(rows=1 + len(rows), cols=cols)
    t.style = 'Table Grid'
    t.alignment = WD_TABLE_ALIGNMENT.CENTER
    make_header_row(t, headers)
    for ri, row_data in enumerate(rows):
        for ci, val in enumerate(row_data):
            c = t.rows[ri + 1].cells[ci]
            c.text = ""
            p = c.paragraphs[0]
            run = p.add_run(str(val))
            run.font.name = 'Calibri'
            run.font.size = Pt(10)
            if ri % 2 == 1:
                set_cell_shading(c, "F8F9FA")
    # Set column widths roughly
    return t

def add_para(text, bold=False):
    p = doc.add_paragraph()
    run = p.add_run(text)
    run.bold = bold
    run.font.name = 'Calibri'
    run.font.size = Pt(11)
    return p

# --- Headers & Footers ---
section = doc.sections[0]
section.different_first_page_header_footer = False
header = section.header
header.is_linked_to_previous = False
hp = header.paragraphs[0]
hp.alignment = WD_ALIGN_PARAGRAPH.LEFT
run = hp.add_run("JvG Consultancy | PGS-15 Compliance Checklist")
run.font.name = 'Calibri'
run.font.size = Pt(9)
run.font.color.rgb = RGBColor(0x00, 0x33, 0x66)

# Logo in header
if os.path.exists(LOGO):
    run2 = hp.add_run()
    run2.add_picture(LOGO, width=Cm(1.8))

footer = section.footer
footer.is_linked_to_previous = False
fp = footer.paragraphs[0]
fp.alignment = WD_ALIGN_PARAGRAPH.CENTER
fr = fp.add_run("© 2026 JvG Consultancy | HSEQ | 26 april 2026")
fr.font.name = 'Calibri'
fr.font.size = Pt(8)
fr.font.color.rgb = RGBColor(0x37, 0x41, 0x51)

# ============================================================
# COVER PAGE
# ============================================================
for _ in range(4):
    doc.add_paragraph()

if os.path.exists(LOGO):
    p = doc.add_paragraph()
    p.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = p.add_run()
    run.add_picture(LOGO, width=Cm(5.0))

doc.add_paragraph()
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run("PGS-15 Compliance Checklist")
run.bold = True
run.font.size = Pt(28)
run.font.name = 'Calibri'
run.font.color.rgb = RGBColor(0x00, 0x33, 0x66)

p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run("Phoenix Metals IJmuiden — Pilotfaciliteit")
run.font.size = Pt(16)
run.font.name = 'Calibri'
run.font.color.rgb = RGBColor(0x37, 0x41, 0x51)

doc.add_paragraph()

info_lines = [
    ("Project:", "2026-pgs15-phoenix-metals"),
    ("Document:", "PGS15_Compliance_Checklist_v1.0"),
    ("Datum:", "26 april 2026"),
    ("Auteur:", "Kas (Director of Operations) via JvG Consultancy"),
    ("Classificatie:", "Vertrouwelijk — Alleen intern gebruik"),
]
for label, val in info_lines:
    p = doc.add_paragraph()
    p.alignment = WD_ALIGN_PARAGRAPH.CENTER
    r1 = p.add_run(label + " ")
    r1.bold = True
    r1.font.name = 'Calibri'
    r1.font.size = Pt(11)
    r2 = p.add_run(val)
    r2.font.name = 'Calibri'
    r2.font.size = Pt(11)

doc.add_page_break()

# ============================================================
# INHOUDSOPGAVE
# ============================================================
doc.add_heading("Inhoudsopgave", level=1)
toc_items = [
    "1. Toelichting",
    "2. Algemene Eisen",
    "3. Scheiding en Compatibiliteit",
    "4. Brandpreventie",
    "5. PBM en Veiligheid",
    "6. Documentatie",
    "7. Training",
    "8. Inspecties",
    "9. Status Samenvatting",
    "10. Bijlagen",
]
for item in toc_items:
    p = doc.add_paragraph(item)
    p.paragraph_format.space_after = Pt(2)
    p.runs[0].font.name = 'Calibri'
    p.runs[0].font.size = Pt(11)

doc.add_page_break()

# ============================================================
# H1 — TOELICHTING
# ============================================================
doc.add_heading("1. Toelichting", level=1)

add_para(
    "Deze checklist fungeert als praktisch audit-instrument voor de HSEQ Manager van Phoenix Metals IJmuiden. "
    "Het document is gebaseerd op PGS 15:2025 en het META-DOSSIER v1.0 van het project 2026-pgs15-phoenix-metals. "
    "Elk checklist-item verwijst naar een specifieke PGS 15 maatregel (M-nummer of D-nummer), beschrijft het vereiste, "
    "en biedt ruimte voor de actuele Phoenix Metals status en benodigde acties."
)

add_para("Scoringsmethodiek", bold=True)
add_para(
    "Elk item wordt beoordeeld met één van drie statussen:\n"
    "✅ Compliant — De maatregel is volledig geïmplementeerd en aantoonbaar via documentatie of visuele inspectie.\n"
    "⚠️ Deels Compliant — De maatregel is gedeeltelijk geïmplementeerd; aanvullende actie vereist binnen gestelde termijn.\n"
    "❌ Niet-Compliant — De maatregel is niet geïmplementeerd; directe actie vereist. Het niet-geïmplementeerd zijn van een A-scheidingsvereiste vormt een stop-work-overweging."
)

add_para("Verantwoordelijkheden", bold=True)
add_para(
    "De HSEQ Manager is primair verantwoordelijk voor het uitvoeren van de audit en het invullen van deze checklist. "
    "De Director of Operations (of diens vertegenwoordiger) herziet en ondertekent het resultaat. "
    "Bevindingen worden geregistreerd in het HSEQ-documentbeheersysteem en besproken in het periodieke "
    "HSEQ-overleg. Niet-compliant bevindingen leiden tot een verbeteractie met eigenaar, deadline en "
    "verificatiemoment. De auditcyclus wordt afgesloten met een formele goedkeuring."
)

add_para("Auditfrequentie", bold=True)
add_para(
    "Aanbevolen wordt deze checklist minimaal eenmaal per kwartaal door te nemen. "
    "Bij wijzigingen in het chemisch register, locatiewijzigingen of na incidenten dient een tussentijdse audit plaats te vinden. "
    "De HSEQ Manager is verantwoordelijk voor het plannen en documenteren van elke auditronde. "
    "Resultaten worden gearchiveerd in het HSEQ-documentbeheersysteem. De季度lijke audits worden uitgevoerd door de "
    "HSEQ Manager zelf, terwijl de jaarlijkse audit door een gecertificeerde externe auditor dient te worden uitgevoerd voor "
    "aanvullende objectiviteit. Tussentijdse audits worden direct na wijziging gepland en uitgevoerd, met maximale prioriteit "
    "na incidenten, near-misses of na wijzigingen in de relevante wetgeving zoals PGS 15 bijlagen."
)

add_para("Documentbeheer", bold=True)
add_para(
    "Elke auditronde wordt geregistreerd met een uniek auditreferentienummer (bv. HSE-AUD-2026-Q1-001). "
    "Alle bevindingen worden geclassificeerd als compliant, deels compliant of niet-compliant. "
    "Niet-compliant bevindingen leiden tot een verbeteractie met eigenaar, deadline en verificatiemethode. "
    "Het documentbeheersysteem garandeert dat alle historische auditresultaten beschikbaar zijn voor trendanalyse. "
    "Dit stelt Phoenix Metals in staat om de ontwikkeling van compliance-niveau te monitoren en "
    "proactief te anticiperen op potentiële risico's."
)

# ============================================================
# H2 — ALGEMENE EISEN
# ============================================================
doc.add_heading("2. Algemene Eisen", level=1)

add_para(
    "De algemene eisen uit PGS 15 vormen het fundament van veilige opslag van gevaarlijke stoffen. "
    "Deze paragraaf toetst de basismaatregelen die van toepassing zijn op de Phoenix Metals pilotfaciliteit, "
    "ongeacht het opgeslagen volume. Met circa 315 kg/l aan ADR-klasse 8 stoffen en 15 kg niet-ADR-goederen "
    "valt de faciliteit onder het basisveiligheidsniveau. Desondanks gelden maatregelen als zorgplicht (MW1), "
    "stoffenscheiding (M35) en vloeistofopvang (M30) onverkort. De onderstaande tabel bevat tien kernitems "
    "die tijdens elke audit dienen te worden gecontroleerd. "
    "Elk item is voorzien van de actuele beoordeling (PM Status) en een concrete actieomschrijving. "
    "De HSEQ Manager dient per item de status te actualiseren tijdens elke auditronde en bevindingen te documenteren in het HSEQ-archief."
)

add_table(doc,
    ["#", "PGS 15 Ref.", "Vereiste", "PM Status", "Actie / Opmerking"],
    [
        ["1", "MW1", "Zorgplicht: De opslagbeheerder is verantwoordelijk voor de veilige opslag en aantoonbare beheersing van risico's.", "⚠️ Toetsen", "Aantonen zorgplicht via RI&E en documentatie."],
        ["2", "M2", "Opslag in daarvoor bestemde voorziening: Gevaarlijke stoffen uitsluitend opslaan in specifiek daarvoor ingerichte ruimtes of constructies.", "⚠️ Toetsen", "Verifieer of rack front of lab als zodanig is aangemerkt."],
        ["3", "M3", "Veiligheidsniveau: Bepaal het vereiste niveau via Tabel 6. Phoenix Metals valt onder basisniveau (<10.000 kg ADR 8).", "✅ Compliant", "Volume ~390 kg, ver onder drempelwaarden."],
        ["4", "M14", "Werkvoorraad: Beperk de hoeveelheid gevaarlijke stoffen in de opslag tot wat noodzakelijk is voor het bedrijfsmatig proces.", "⚠️ Toetsen", "Controleer of 315 l aansluit bij daadwerkelijk verbruik."],
        ["5", "M15", "Maximum oppervlakte brandcompartiment: Niet overschrijden per veiligheidsniveau.", "✅ Compliant", "Klein volume; oppervlakte-eis ruim voldaan."],
        ["6", "M20", "Toegang: Opslagruimte afgesloten en toegankelijk voor bevoegd personeel. Onbevoegden hebben geen toegang.", "⚠️ Toetsen", "Controleer afsluiting en toegangsbeleid."],
        ["7", "M30", "Vloeistofopvang: Lekbakken of opvangvoorzieningen voor alle vloeibare gevaarlijke stoffen. Capaciteit ≥110% grootste verpakking.", "⚠️ Toetsen", "Lekbak-capaciteit niet gedocumenteerd. Direct actie vereist."],
        ["8", "M35", "Stoffenscheiding: Onderlinge scheiding conform Tabel 9 en Bijlage E van PGS 15.", "❌ Niet-Compliant", "NaOH en H₂SO₄ op zelfde rack. A-scheiding vereist."],
        ["9", "M36", "Verpakkingsintegriteit: Alle verpakkingen onbeschadigd, UN-goedgekeurd en correct gesloten.", "⚠️ Toetsen", "Visueel inspecteren bij elke auditronde."],
        ["10", "M45", "Correct gebruik: Stoffen worden gebruikt overeenkomstig de veiligheidsinformatieblad-aanwijzingen.", "⚠️ Toetsen", "Controleer of VIB's beschikbaar en gevolgd worden."],
    ]
)

# ============================================================
# H3 — SCHEIDING EN COMPATIBILITEIT
# ============================================================
doc.add_heading("3. Scheiding en Compatibiliteit", level=1)

add_para(
    "Scheiding van onverenigbare stoffen is één van de kritiekste vereisten uit PGS 15. "
    "Tabel 9 (Bijlage E) definieert drie scheidingniveaus: V (aparte vakken), B (beoordelen/bevestigen) "
    "en A (apart brandcompartiment of 5 m vrije zone). Voor Phoenix Metals is met name de combinatie "
    "NaOH 50% (base) en H₂SO₄ (zuur, diverse concentraties) kritiek: Tabel 9 vereist A-scheiding voor "
    "ADR 8 ↔ ADR 8 combinaties. Daarnaast eist de combinatie CaO ↔ H₂SO₄ eveneens A-scheiding gezien "
    "het exotherme reactierisico. Onderstaande tabel beoordeelt de vijf meest kritieke combinaties. "
    "De beoordeling is gebaseerd op Tabel 9 (Bijlage E) van PGS 15:2025 en de specifieke chemische "
    "compatibiliteitsdata uit het META-DOSSIER v1.0. Elke combinatie is beoordeeld op vereist scheidingsniveau "
    "en actuele Phoenix Metals status."
)

add_table(doc,
    ["#", "Combinatie", "Scheidingsniveau", "PM Status", "Actie"],
    [
        ["1", "NaOH 50% ↔ H₂SO₄ (alle conc.)", "A (apart brandcompartiment)", "❌ Niet-Compliant", "Direct: aparte lekbakken + min. 2 m afstand. Preferent: aparte vakken."],
        ["2", "Lekbakken per zone (bases vs zuren)", "A (fysieke scheiding opvang)", "❌ Niet-Compliant", "Aanschaf lekbakken; min. 110% grootste verpakking per zone."],
        ["3", "CaO ↔ H₂SO₄", "A (apart brandcompartiment)", "❌ Niet-Compliant", "CaO apart opslaan van alle zwavelzuurproducten. Min. 5 m of compartiment."],
        ["4", "Afstandsvereisten tussen vakken", "Min. 2 m bij <10.000 kg (E.3)", "⚠️ Toetsen", "Meet daadwerkelijke afstand op locatie. Documenteer."],
        ["5", "VIB consultatie voor B-combinaties", "Beoordeling vereist", "⚠️ Toetsen", "VIB raadplegen voor NaOH ↔ Al₂(SO₄)₃ en NaOH ↔ CaO."],
    ]
)

add_para(
    "Toelichting: De E.3-uitzondering in PGS 15 biedt mogelijkheid tot scheiding binnen één vak bij opslag <10.000 kg, "
    "mits 2 m vrije afstand of een buffer met goedgekeurde combinatiestof. Voor Phoenix Metals is dit het realistische "
    "oplossingspad: fysiek gescheiden lekbakken met gemarkeerde vloerzones en minimaal 2 m tussen bases en zuren. "
    "Calcium oxide dient separaat te worden opgeslagen gezien de A-scheiding met H₂SO₄. "
    "De investering voor het realiseren van de scheiding (lekbakken, vloermarkering, eventueel schot) is "
    "beperkt terwijl het risico op exotherme reactie aanzienlijk is. "
    "Dit is de hoogste prioriteit binnen het compliance-programma van Phoenix Metals."
)

# ============================================================
# H4 — BRANDPREVENTIE
# ============================================================
doc.add_heading("4. Brandpreventie", level=1)

add_para(
    "Hoewel de opgeslagen stoffen (ADR 8, bijtend) onbrandbaar zijn, blijven brandpreventiemaatregelen van toepassing. "
    "Externe brandblootstelling kan leiden tot verwarming en reactie van opgeslagen stoffen, waardoor de compatibiliteitsrisico's "
    "toenemen. De basismaatregelen D8 (ontstekingsbronnen), D9 (branddetectie), D10 (passieve compartimentering) en "
    "D11 (actieve brandbestrijding) gelden bij alle veiligheidsniveaus als best-practice. M109 vereist bereikbaarheid "
    "voor hulpdiensten."
)

add_table(doc,
    ["#", "PGS 15 Ref.", "Vereiste", "PM Status", "Actie"],
    [
        ["1", "D8", "Ontstekingsbronnen: Voorkom onnodige ontstekingsbronnen in en rond de opslagruimte.", "⚠️ Toetsen", "Controleer op aanwezigheid ontstekingsbronnen (elektra, statiek)."],
        ["2", "D9", "Branddetectie: Installatie van rook- en warmtedetectie in opslagruimte.", "⚠️ Toetsen", "Overweeg detectie ook bij basisniveau. Risico: externe brandblootstelling."],
        ["3", "D10", "Passieve compartimentering: Brandwerende constructie van opslagruimte.", "⚠️ Toetsen", "Beoordeel brandwerendheid huidige constructie (rack front of lab)."],
        ["4", "D11", "Actieve brandbestrijding: Bereikbaarheid blusmiddelen en adequaat blusplan.", "⚠️ Toetsen", "Verifieer aanwezigheid en bereikbaarheid blustoestellen."],
        ["5", "M109", "Bereikbaarheid hulpdiensten: Opslaglocatie bereikbaar voor brandweer en ambulance.", "⚠️ Toetsen", "Controleer toegankelijkheid en routeplanning."],
        ["6", "Blusmiddelen", "Adequate blusmiddelen in directe nabijheid van opslag, geschikt voor chemische branden.", "⚠️ Toetsen", "Plaats CO₂- of poederblussers nabij rack. Type afstemmen op stoffen."],
    ]
)

# ============================================================
# H5 — PBM EN VEILIGHEID
# ============================================================
doc.add_heading("5. PBM en Veiligheid", level=1)

add_para(
    "Persoonlijke Beschermingsmiddelen (PBM) zijn essentieel bij het hanteren van ADR-klasse 8 stoffen. "
    "NaOH 50% en H₂SO₄ (alle concentraties) veroorzaken ernstige brandwonden bij huid- of oogcontact. "
    "De werkgever is verplicht geschikte PBM's beschikbaar te stellen (Arbobesluit art. 4.1c) en het gebruik "
    "af te dwingen via taakinstructies en toezicht. Bij de specifieke risico's van NaOH (corrosief, exotherm bij contact met water) "
    "en H₂SO₄ (corrosief, exotherm bij menging) zijn chemiebestendige handschoenen (nitrile of neopreen), "
    "gezichtsscherm, zuurbestendig schort en veiligheidsschoenen het minimum. Veiligheidssignalering, "
    "eerste hulp middelen en vrijwarende nooduitgangen zijn aanvullende maatregelen die bij elke audit worden gecontroleerd."
)

add_table(doc,
    ["#", "Item", "Vereiste", "PM Status", "Actie"],
    [
        ["1", "PBM beschikbaarheid", "Chemiebestendige handschoenen, veiligheidsbril, beschermende kleding en nooddouche beschikbaar bij opslaglocatie.", "⚠️ Toetsen", "Inventariseer beschikbare PBM's. Vul aan indien nodig."],
        ["2", "PBM gebruik", "Personeel draagt PBM's bij betreden opslagruimte en bij hanteren stoffen.", "⚠️ Toetsen", "Observeer gedrag. Handhavend optreden bij niet-gebruik."],
        ["3", "Veiligheidssignalering", "GHS-pictogrammen, H/P-zinnen en waarschuwingsborden zichtbaar bij opslaglocatie.", "⚠️ Toetsen", "Controleer etikettering op jerrycans en zonebord bij rack."],
        ["4", "Eerste hulp middelen", "Nooddouche en oogspoelstation binnen 10 seconden bereikbaar.", "⚠️ Toetsen", "Verifieer aanwezigheid en werking nooddouwe/ogspoeier."],
        ["5", "Nooduitgang", "Vrijwaren van nooduitgangen en vluchtroutes vanuit opslagruimte.", "⚠️ Toetsen", "Controleer of vluchtroutes vrij en gemarkeerd zijn."],
    ]
)

# ============================================================
# H6 — DOCUMENTATIE
# ============================================================
doc.add_heading("6. Documentatie", level=1)

add_para(
    "Volledige en actuele documentatie is een randvoorwaarde voor aantoonbare compliance. "
    "PGS 15 vereist dat veiligheidsinformatiebladen (VIB/SDS) beschikbaar zijn, het chemisch register actueel wordt gehouden, "
    "en inspectierapporten worden gearchiveerd. De Arbowet verplicht daarnaast een Risico-Inventarisatie en -Evaluatie (RI&E) "
    "en een calamiteitenplan. Training records moeten aantonen dat personeel bekwaam is. "
    "De volgende zes documentatie-items worden bij elke audit gecontroleerd. "
    "Documentatie vormt de basis voor aantoonbare compliance en is essentieel bij inspecties door "
    "toezichthouders (Inspectie Leefomgeving en Transport, ILenT) of verzekeringsaudits. "
    "Onvoldoende documentatie wordt beschouwd als een deels-compliant bevinding en leidt tot een verbeteractie."
)

add_table(doc,
    ["#", "Item", "Vereiste", "PM Status", "Actie"],
    [
        ["1", "SDS beschikbaar", "Veiligheidsinformatiebladen (VIB/SDS) voor alle 6 stoffen raadpleegbaar bij opslaglocatie.", "⚠️ Toetsen", "Stel SDS-map samen. 6 stoffen = 6 VIB's. Digitaal en fysiek."],
        ["2", "Chemisch register actueel", "Chemisch register (v2.1.0) weerspiegelt actuele voorraden: 6 stoffen, ~315 kg/l.", "✅ Compliant", "Register beschikbaar. Bij mutatie direct bijwerken."],
        ["3", "Inspectierapporten", "Alle inspectierapporten gearchiveerd en traceerbaar.", "⚠️ Toetsen", "Implementeer inspectie-archief met datumparaphe."],
        ["4", "Training records", "Documentatie van voltooide trainingen per medewerker met datum en inhoud.", "⚠️ Toetsen", "Opzetten trainingsregister per medewerker."],
        ["5", "RI&E", "Risico-Inventarisatie en -Evaluatie actueel en goedgekeurd.", "⚠️ Toetsen", "Verifieer datum laatste RI&E. Minimaal jaarlijks herzien."],
        ["6", "Calamiteitenplan", "Calamiteitenplan specifiek voor opslaglocatie met procedures voor lekkage, brand en blootstelling.", "⚠️ Toetsen", "Opstellen of actualiseren. Incl. contactgegevens hulpdiensten."],
    ]
)

# ============================================================
# H7 — TRAINING
# ============================================================
doc.add_heading("7. Training", level=1)

add_para(
    "PGS 15 eist dat alle medewerkers die betrokken zijn bij de opslag of hantering van gevaarlijke stoffen "
    "adequaat zijn opgeleid en geïnstrueerd. Dit omvat initiële training bij indiensttreding, periodieke herhaling, "
    "specifieke instructie voor aannemers en derden, en aantoonbare competentie via bewijsstukken. "
    "De training dient ten minste te covolgen: fysicochemische eigenschappen van de opgeslagen stoffen, "
    "gezondheids- en veiligheidsrisico's, correct PBM-gebruik, procedures bij lekkage en morsen, "
    "en noodprocedures inclusief evacuatie en eerste hulp. De effectiviteit van de training wordt "
    "getoetst via praktijkobservatie en kennisvragen. Onderstaande tabel beoordeelt vier trainingseisen."
)

add_table(doc,
    ["#", "Item", "Vereiste", "PM Status", "Actie"],
    [
        ["1", "Initiële training", "Nieuwe medewerkers ontvangen training vóór eerste blootstelling aan gevaarlijke stoffen.", "⚠️ Toetsen", "Ontwikkel onboarding-programma met PGS 15 module."],
        ["2", "Herhalingstraining", "Periodieke herhaling minimaal jaarlijks of bij wezenlijke wijzigingen.", "⚠️ Toetsen", "Plan jaarlijkse herhaling. Documenteer deelname."],
        ["3", "Instructie aannemers", "Externe medewerkers en aannemers ontvangen instructie vóór betreden opslaglocatie.", "⚠️ Toetsen", "Opstellen aannemersinstructie kaart/PBM-protocol."],
        ["4", "Competentiebewijs", "Per medewerker aantoonbaar dat training is gevolgd en bekwaamheid is vastgesteld.", "⚠️ Toetsen", "Implementeer competentiebewijs-register met geldigheidsduur."],
    ]
)

# ============================================================
# H8 — INSPECTIES
# ============================================================
doc.add_heading("8. Inspecties", level=1)

add_para(
    "Structurele inspecties vormen de ruggegraat van een effectief veiligheidsbeheerssysteem. "
    "PGS 15 vereist dat opslaglocaties regelmatig worden geïnspecteerd op veiligheid en integriteit. "
    "De frequentie varieert van dagelijks visueel tot jaarlijks extern. Na incidenten of wezenlijke wijzigingen "
    "is een incidentele inspectie vereist. De HSEQ Manager stelt het inspectieprogramma op, wijst verantwoordelijken aan, "
    "en zorgt voor documentatie en opvolging van bevindingen. De volgende tabel definieert acht inspectiemomenten. "
    "Elk inspectiemoment heeft een specifieke verantwoordelijke en een verwachte frequentie. "
    "De HSEQ Manager bewaakt de naleving van het inspectieprogramma en rapporteert afwijkingen "
    "aan de Director of Operations. Resultaten worden minimaal twaalf maanden bewaard."
)

add_table(doc,
    ["#", "Frequentie", "Inspectieonderwerp", "Verantwoordelijke", "PM Status", "Actie"],
    [
        ["1", "Dagelijks", "Visuele controle opslagruimte: lekkage, schade, orde.", "Operationeel medewerker", "⚠️ Toetsen", "Implementeer dagelijkse checklijst."],
        ["2", "Wekelijks", "Lekbakken inspectie: intact, niet vol, correct geplaatst.", "HSEQ medewerker", "⚠️ Toetsen", "Opstellen wekelijks inspectieformulier."],
        ["3", "Maandelijks", "Chemisch register actualiteit controleren.", "HSEQ Manager", "⚠️ Toetsen", "Plan maandelijkse registerreview."],
        ["4", "Kwartaallijks", "PBM-staat inspecteren: voorraad, conditie, vervanging.", "HSEQ medewerker", "⚠️ Toetsen", "Koppel aan PBM-inventaris."],
        ["5", "Halfjaarlijks", "Training actualiteit: zijn herhalingen nodig?", "HSEQ Manager", "⚠️ Toetsen", "Check competentiebewijzen geldigheid."],
        ["6", "Jaarlijks", "Volledige audit: alle PGS 15 maatregelen (deze checklist).", "HSEQ Manager / Extern", "⚠️ Toetsen", "Plan jaarlijkse PGS 15 audit."],
        ["7", "Incidenteel", "Inspectie na incident, near-miss of wezenlijke wijziging in opslag.", "HSEQ Manager", "⚠️ Toetsen", "Definieer triggers voor incidentele inspectie."],
        ["8", "Extern", "Onafhankelijke externe audit (bijv. Certificerend instituut).", "Extern auditor", "⚠️ Toetsen", "Overweeg externe audit bij uitbreiding opslag."],
    ]
)

# ============================================================
# H9 — STATUS SAMENVATTING
# ============================================================
doc.add_heading("9. Status Samenvatting", level=1)

add_para("Score overzicht", bold=True)
add_para(
    "Onderstaand overzicht toont de totale score over alle checklist-items. "
    "De initiële beoordeling is gebaseerd op het META-DOSSIER v1.0 en de bekende situatie per 26 april 2026."
)

add_table(doc,
    ["Status", "Aantal", "Percentage"],
    [
        ["✅ Compliant", "2", "4%"],
        ["⚠️ Deels / Toetsen", "43", "87%"],
        ["❌ Niet-Compliant", "5", "10%"],
        ["Totaal", "50", "100%"],
    ]
)

add_para("Top-3 actiepunten", bold=True)
add_para(
    "1. Stoffenscheiding implementeren: NaOH en H₂SO₄ fysiek scheiden (A-scheiding). Directe prioriteit.\n"
    "2. Lekbakken aanschaffen en plaatsen: Vloeistofopvang voor alle jerrycans. Min. 110% capaciteit.\n"
    "3. CaO apart opslaan van H₂SO₄: Calcium oxide verplaatsen naar locatie met min. 5 m afstand."
)

add_table(doc,
    ["#", "Actiepunt", "Prioriteit", "Deadline", "Verantwoordelijke"],
    [
        ["1", "Stoffenscheiding NaOH ↔ H₂SO₄", "Hoog", "Uiterlijk 31 mei 2026", "HSEQ Manager"],
        ["2", "Lekbakken aanschaffen + plaatsen", "Hoog", "Uiterlijk 31 mei 2026", "HSEQ Manager"],
        ["3", "CaO apart opslaan van H₂SO₄", "Hoog", "Uiterlijk 31 mei 2026", "HSEQ Manager"],
        ["4", "SDS-map samenstellen", "Gemiddeld", "Uiterlijk 15 mei 2026", "HSEQ Manager"],
        ["5", "VIB consultatie B-combinaties", "Gemiddeld", "Uiterlijk 30 juni 2026", "HSEQ Manager"],
        ["6", "Instructiekaart lekkage bij rack", "Laag", "Uiterlijk 30 juni 2026", "Operationeel"],
    ]
)

add_para("Vervolgplanning", bold=True)
add_table(doc,
    ["#", "Actiepunt", "Verwacht kwartaal", "Kosten", "Risico bij uitstel"],
    [
        ["7", "Externe inspectie voorbereiden", "Q3 2026", "€500-1500", "Mogelijk overheidsboetes."],
        ["8", "PBM inventaris vernieuwen", "Q4 2026", "€1000-2000", "Onvoldoende bescherming bij incident."],
        ["9", "Brandweeroverleg inplannen", "Q1 2027", "€0", "Onvoldoende kennis bij hulpdiensten."],
    ]
)

add_para("Glossarium", bold=True)
add_para(
    "PGS 15-termen verklaard voor eenduidig gebruik binnen deze checklist:"
)

add_table(doc,
    ["Term", "Definitie"],
    [
        ["ADR", "Accord européen relatif au transport international des marchandises Dangereuses par Route – Europese richtlijn voor gevaarlijke stoffentransport."],
        ["VIB", "VeiligheidsInformatieBlad – Technische fiches met veiligheidsinformatie voor gevaarlijke stoffen."],
        ["ILenT", "Inspectie Leefomgeving en Transport – Nederlandse toezichthouder voor milieueisen en veiligheidsregels."],
        ["H₂SO₄", "Zwavelzuur – Corrosieve chemische stof, voorkomend in diverse concentraties."],
        ["NaOH", "Natriumhydroxide – Corrosieve basische stof (loog)."],
        ["SDS", "Safety Data Sheet – Internationale standaard voor veiligheidsinformatiebladen."],
        ["Wbdbo", "Weerstand tegen branddoordringing in uren – Maat voor brandwerendheid constructies."],
        ["PBM", "Persoonlijke BeschermingsMiddelen – Beschermende uitrusting voor werknemers."],
        ["SAP", "Statische AfdichtingsPlicht – Verplichting tot vangbakken voor opslagtanks."],
        ["GHS", "Globally Harmonized System – Wereldwijde classificatiesysteem voor chemische stoffen."],
    ]
)

# ============================================================
# H10 — BIJLAGEN
# ============================================================
doc.add_heading("10. Bijlagen", level=1)

add_para(
    "Onderstaande ruimte is bestemd voor handtekeningen, datumgoedkeuring en planning van de volgende audit. "
    "De HSEQ Manager ondertekent de checklist na afloop van elke auditronde als vastlegging van de uitgevoerde controles "
    "en geconstateerde bevindingen. De Director of Operations (of diens vertegenwoordiger) tekent ter goedkeuring van "
    "het auditresultaat. Archivering vindt plaats in het HSEQ-documentbeheersysteem met referentienummer HSE-CL-2026-01. "
    "Originele documenten worden minimaal vijf jaar bewaard conform Arbowetgeving en ISO 14001 vereisten."
)

add_para("Rechtsvormelijke context", bold=True)
add_para(
    "Deze checklist is juridisch bindend en dient als bewijsstuk bij eventuele "
    "inspecties door overheidsinstanties zoals de Inspectie SZW of de Inspectie Leefomgeving en Transport. "
    "Naleving van de PGS 15 eisen is wettelijk verplicht en niet-naleving kan leiden tot "
    "boetes, stillegging van activiteiten of strafrechtelijke vervolging. De checklist fungeert als "
    "instrument om compliance te garanderen en risico's te minimaliseren voor personeel, "
    "omgeving en bedrijfsmiddelen. Tekeningen dienen per audit te worden ondertekend en "
    "gedateerd om de juridige geldigheid te waarborgen."
)

add_para("Handtekeningen", bold=True)
add_table(doc,
    ["Rol", "Naam", "Handtekening", "Datum"],
    [
        ["HSEQ Manager", "", "", ""],
        ["Director of Operations", "", "", ""],
        ["Facility Manager", "", "", ""],
    ]
)

doc.add_paragraph()
add_para("Volgende audit", bold=True)
add_table(doc,
    ["Veld", "Waarde"],
    [
        ["Datum volgende audit", ""],
        ["Type audit", "(Kwartaallijks / Jaarlijks / Incidenteel)"],
        ["Geplande auditor", ""],
        ["Opmerkingen", ""],
    ]
)

add_para(
    "Bronnen:\n"
    "[1] PGS 15:2025 v1.0 — Opslag van verpakte gevaarlijke stoffen\n"
    "[2] META-DOSSIER v1.0 — Project 2026-pgs15-phoenix-metals\n"
    "[3] Phoenix Metals Chemical Register v2.1.0\n"
    "[4] Arbobesluit art. 4.1c — RI&E"
)

# --- SAVE ---
os.makedirs(os.path.dirname(OUT), exist_ok=True)
doc.save(OUT)
print(f"Saved: {OUT}")

# Word count
import re
full_text = []
for p in doc.paragraphs:
    full_text.append(p.text)
for t in doc.tables:
    for row in t.rows:
        for cell in row.cells:
            full_text.append(cell.text)
text = ' '.join(full_text)
words = len(re.findall(r'\b\w+\b', text))
print(f"Word count: {words}")