#!/usr/bin/env python3
"""PGS-15 Compliance Kennisdossier Phoenix Metals — Generator v1.0
Output: deliverables/docx/PGS15_Kennisdossier_PhoenixMetals_v1.0.docx
"""

import os
from datetime import datetime
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.enum.section import WD_ORIENT
from docx.oxml.ns import qn, nsdecls
from docx.oxml import parse_xml

# ─── Constants ───
PRIMARY = RGBColor(0x00, 0x33, 0x66)
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
BLACK = RGBColor(0x00, 0x00, 0x00)
DATE_STR = "26 april 2026"
VERSION = "v1.0"
LOGO = "/root/projects/jg/2026-pgs15-phoenix-metals/assets/branding/jvg-consultancy-logo.jpg"
OUTPUT = "/root/projects/jg/2026-pgs15-phoenix-metals/deliverables/docx/PGS15_Kennisdossier_PhoenixMetals_v1.0.docx"

doc = Document()

# ─── Style Setup ───
style = doc.styles['Normal']
style.font.name = 'Calibri'
style.font.size = Pt(11)
style.paragraph_format.space_after = Pt(6)
style.paragraph_format.line_spacing = 1.15

for level in range(1, 4):
    hs = doc.styles[f'Heading {level}']
    hs.font.name = 'Calibri'
    hs.font.color.rgb = PRIMARY
    hs.font.bold = True
    if level == 1:
        hs.font.size = Pt(18)
        hs.paragraph_format.space_before = Pt(24)
        hs.paragraph_format.space_after = Pt(12)
    elif level == 2:
        hs.font.size = Pt(14)
        hs.paragraph_format.space_before = Pt(18)
        hs.paragraph_format.space_after = Pt(8)
    else:
        hs.font.size = Pt(12)
        hs.paragraph_format.space_before = Pt(12)
        hs.paragraph_format.space_after = Pt(6)

# ─── Helper Functions ───
def set_cell_shading(cell, color_hex):
    shading = parse_xml(f'<w:shd {nsdecls("w")} w:fill="{color_hex}"/>')
    cell._tc.get_or_add_tcPr().append(shading)

def make_header_row(table, texts, color_hex="003366"):
    row = table.rows[0]
    for i, txt in enumerate(texts):
        cell = row.cells[i]
        cell.text = ""
        p = cell.paragraphs[0]
        run = p.add_run(str(txt))
        run.bold = True
        run.font.color.rgb = WHITE
        run.font.size = Pt(10)
        run.font.name = 'Calibri'
        p.alignment = WD_ALIGN_PARAGRAPH.CENTER
        set_cell_shading(cell, color_hex)

def add_table_row(table, texts, bold_first=False):
    row = table.add_row()
    for i, txt in enumerate(texts):
        cell = row.cells[i]
        cell.text = ""
        p = cell.paragraphs[0]
        run = p.add_run(str(txt))
        run.font.size = Pt(10)
        run.font.name = 'Calibri'
        if bold_first and i == 0:
            run.bold = True
    return row

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

def add_ref(text):
    """Add paragraph with superscript reference handling — [1] style inline."""
    p = doc.add_paragraph()
    # Simple approach: add as normal text with bracketed refs
    run = p.add_run(text)
    run.font.name = 'Calibri'
    run.font.size = Pt(11)
    return p

# ─── Headers & Footers ───
section = doc.sections[0]
section.top_margin = Cm(2.5)
section.bottom_margin = Cm(2.5)
section.left_margin = Cm(2.5)
section.right_margin = Cm(2.5)

header = section.header
hp = header.paragraphs[0]
hp.alignment = WD_ALIGN_PARAGRAPH.RIGHT
run = hp.add_run("JvG Consultancy — PGS-15 Compliance Kennisdossier")
run.font.size = Pt(8)
run.font.color.rgb = RGBColor(0x99, 0x99, 0x99)
run.font.name = 'Calibri'

footer = section.footer
fp = footer.paragraphs[0]
fp.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = fp.add_run(f"© 2026 JvG Consultancy | HSEQ Divisie | {DATE_STR}")
run.font.size = Pt(8)
run.font.color.rgb = RGBColor(0x99, 0x99, 0x99)
run.font.name = 'Calibri'

# ════════════════════════════════════════════════════════════════════════
# VOORBLAD
# ════════════════════════════════════════════════════════════════════════
doc.add_paragraph()  # spacer

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

doc.add_paragraph()

p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run("PGS-15 COMPLIANCE\nKENNISDOSSIER")
run.bold = True
run.font.size = Pt(28)
run.font.color.rgb = PRIMARY
run.font.name = 'Calibri'

doc.add_paragraph()

p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run("Phoenix Metals IJmuiden\nOpslag van Gevaarlijke Stoffen — Basisveiligheidsniveau")
run.font.size = Pt(14)
run.font.color.rgb = PRIMARY
run.font.name = 'Calibri'

doc.add_paragraph()
doc.add_paragraph()

# Meta info table on cover
info = [
    ("Opdrachtgever:", "Phoenix Metals IJmuiden"),
    ("Adviseur:", "JvG Consultancy — HSEQ Divisie"),
    ("Documentversie:", VERSION),
    ("Datum:", DATE_STR),
    ("Classificatie:", "Vertrouwelijk"),
]
t = doc.add_table(rows=len(info), cols=2)
t.alignment = WD_TABLE_ALIGNMENT.CENTER
for i, (k, v) in enumerate(info):
    t.rows[i].cells[0].text = ""
    t.rows[i].cells[1].text = ""
    p0 = t.rows[i].cells[0].paragraphs[0]
    r0 = p0.add_run(k)
    r0.bold = True
    r0.font.size = Pt(11)
    r0.font.name = 'Calibri'
    p0.alignment = WD_ALIGN_PARAGRAPH.RIGHT
    p1 = t.rows[i].cells[1].paragraphs[0]
    r1 = p1.add_run(v)
    r1.font.size = Pt(11)
    r1.font.name = 'Calibri'

doc.add_paragraph()

p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run("Dit document is vertrouwelijk en uitsluitend bestemd voor\nPhoenix Metals IJmuiden en JvG Consultancy.")
run.italic = True
run.font.size = Pt(9)
run.font.color.rgb = RGBColor(0x99, 0x99, 0x99)
run.font.name = 'Calibri'

doc.add_page_break()

# ════════════════════════════════════════════════════════════════════════
# MANAGEMENT SAMENVATTING
# ════════════════════════════════════════════════════════════════════════
doc.add_heading("Management Samenvatting", level=1)

add_body("Dit kennisdossier biedt een volledige analyse van de PGS 15:2025 compliance-positie van Phoenix Metals IJmuiden. Het bedrijf is een pilotfaciliteit voor metaalverwerking en chemische procesvoering, gelegen in IJmuiden. De opslag van gevaarlijke stoffen omvat circa 300 liter ADR-klasse 8 (bijtende) stoffen en 15 kg niet-ADR-geclassificeerde stoffen, verdeeld over zes producten.")

add_body("Kernbevindingen", bold=True)

p = add_body("")
p.clear()
run = p.add_run("Veiligheidsniveau: ")
run.bold = True
run.font.name = 'Calibri'
run = p.add_run("Met een totaal van circa 390 kg ADR 8 stoffen bevindt Phoenix Metals zich ver onder de drempelwaarde van 2.500 kg per ADR-klasse (Tabel 7, PGS 15). Het basisveiligheidsniveau volstaat. Geen verhoogd veiligheidsniveau (VN-B of VN-A) is vereist.")
run.font.name = 'Calibri'

p = add_body("")
p.clear()
run = p.add_run("Kritiek issue — Stoffenscheiding: ")
run.bold = True
run.font.name = 'Calibri'
run = p.add_run("Sodium hydroxide 50% (NaOH, base) en zwavelzuur (H₂SO₄, zuur) staan op hetzelfde opslagrack. Volgens PGS 15 Bijlage E, Tabel 9 vereist de combinatie ADR 8 ↔ ADR 8 een A-scheiding (apart brandcompartiment of 5 m vrije zone). Voor volumes onder 10.000 kg geldt een versoepeling: minimaal 2 m afstand en aparte lekbakken volstaan (E.3-uitzondering).")
run.font.name = 'Calibri'

p = add_body("")
p.clear()
run = p.add_run("Calcium oxide ↔ H₂SO₄: ")
run.bold = True
run.font.name = 'Calibri'
run = p.add_run("Eveneens een A-scheiding vereist in verband met exotherme reactie tussen zuur en sterk basisch oxide.")
run.font.name = 'Calibri'

add_body("Directe actiepunten", bold=True)

items = [
    "1. Plaats NaOH 50% en H₂SO₄ in aparte lekbakken met minimaal 2 m onderlinge afstand (M35 stoffenscheiding).",
    "2. Sla calcium oxide apart op van alle zwavelzuurproducten (A-scheiding).",
    "3. Documenteer vloeistofopvangcapaciteit: lekbakken moeten minimaal 110% van het grootste verpakkingsvolume per bak kunnen bevatten (M30)."
]
for item in items:
    p = doc.add_paragraph(item, style='List Bullet')
    for run in p.runs:
        run.font.name = 'Calibri'
        run.font.size = Pt(11)

add_body("De totale investering voor deze drie actiepunten bedraagt naar schatting €200–€500, voornamelijk voor lekbakken, vloermarkering en administratieve inrichting.")

doc.add_page_break()

# ════════════════════════════════════════════════════════════════════════
# HOOFDSTUK 1: INTRODUCTIE PGS 15:2025
# ════════════════════════════════════════════════════════════════════════
doc.add_heading("1. Introductie PGS 15:2025", level=1)

doc.add_heading("1.1 Doel en reikwijdte", level=2)
add_body("De Publicatiereeks Gevaarlijke Stoffen 15 (PGS 15) is de Nederlandse richtlijn voor de veilige opslag van verpakte gevaarlijke stoffen. De richtlijn is van toepassing op alle bedrijven die gevaarlijke stoffen opslaan in verpakkingen, waaronder jerrycans, vaten, IBC's en kleinere verpakkingen. PGS 15 behandelt de opslag in afgesloten ruimtes, in de open lucht en in voertuigen.[1]")
add_body("De huidige versie is PGS 15:2025 versie 1.0, gepubliceerd in januari 2025 door de sectie Publiek-Private Regelgeving (PPR) van het Ministerie van Infrastructuur en Waterstaat. Deze versie vervangt de eerdere PGS 15:2019 en bevat belangrijke actualisaties op het gebied van stoffenscheiding, veiligheidsniveaus en brandbeveiligingseisen.[1]")

doc.add_heading("1.2 Juridische status", level=2)
add_body("PGS 15 heeft een informatief juridisch karakter. De richtlijn is niet direct bindend, maar fungeert als nalevingsinstrument onder de Omgevingswet. Het Besluit bouwwerken leefomgeving (Bbl) en het Besluit kwaliteit leefomgeving (Bkl) refereren aan PGS 15 als maatgevende standaard voor de opslag van gevaarlijke stoffen. Bevoegd gezag (gemeente, provincie of omgevingsdienst) kan PGS 15 aanwenden als toetsingskader bij vergunningsverlening en handhaving.[2]")
add_body("Voor Phoenix Metals betekent dit dat naleving van PGS 15:2025 de meest efficiënte route is om te voldoen aan de eisen uit de Omgevingswet. Afwijkingen zijn mogelijk, maar vereisen een gemotiveerd alternatief dat een gelijkwaardig veiligheidsniveau waarborgt.")

doc.add_heading("1.3 Relatie met andere wetgeving", level=2)
add_body("PGS 15 staat niet op zichzelf. De richtlijn raakt aan meerdere wettelijke kaders:")

t = doc.add_table(rows=1, cols=3)
make_header_row(t, ["Wetgeving", "Relatie met PGS 15", "Relevantie Phoenix Metals"])
data = [
    ("Arbowet / Arbobesluit", "Art. 4.1c Arbobesluit vereist een Risico-Inventarisatie & -Evaluatie (RI&E) inclusief gevaarlijke stoffen. PGS 15 fungeert als invulling van de arbeidsomstandighedeneisen.", "Hoog — RI&E inclusief chemische risico's verplicht"),
    ("Omgevingswet (Bbl/Bkl)", "Bbl stelt eisen aan brandcompartimentering en externe veiligheidsafstanden. PGS 15 biedt het technische kader.", "Hoog — vergunningsplichtig"),
    ("ADR", "Classificatiesysteem voor transport. PGS 15 gebruikt ADR-klassen als basis voor opslagcategorieën.", "Hoog — alle opgeslagen stoffen zijn ADR-geclassificeerd"),
    ("CLP (EG 1272/2008)", "Classificatie, etikettering en verpakking van stoffen. Bepaalt H-zinnen en gevarenpictogrammen.", "Gemiddeld — etikettering verpakkingen"),
    ("REACH (EG 1907/2006)", "Registratie, evaluatie en autorisatie chemische stoffen. Voorziet in Veiligheidsinformatiebladen (VIB/SDS).", "Gemiddeld — SDS-beschikbaarheid verplicht"),
]
for row_data in data:
    add_table_row(t, row_data, bold_first=True)

add_body("[1] PGS 15:2025 v1.0, januari 2025, Sectie PPR, Ministerie van I&W.")
add_body("[2] Omgevingswet, Besluit bouwwerken leefomgeving (Bbl), art. 4.32 e.v.")

doc.add_page_break()

# ════════════════════════════════════════════════════════════════════════
# HOOFDSTUK 2: BEDRIJFSPROFIEL PHOENIX METALS
# ════════════════════════════════════════════════════════════════════════
doc.add_heading("2. Bedrijfsprofiel Phoenix Metals", level=1)

doc.add_heading("2.1 Algemeen", level=2)
add_body("Phoenix Metals is een pilotfaciliteit gevestigd in IJmuiden. Het bedrijf is actief in metaalverwerking en chemische procesvoering. De locatie fungeert als test- en ontwikkelingslocatie waar nieuwe chemische processen op kleine schaal worden uitgevoerd voordat eventuele opschaling plaatsvindt.")
add_body("De huidige opslag van gevaarlijke stoffen is kleinschalig: circa 315 kg/l verdeeld over zes producten, opgeslagen op een storage racking systeem (rack in front of lab). Het betreft één brandcompartiment.")

doc.add_heading("2.2 Chemisch register", level=2)
add_body("Het volledige chemisch register van Phoenix Metals, zoals gedocumenteerd in het Registration Chemicals MASTER (versie 2.1.0), bevat de volgende zes stoffen:")

t = doc.add_table(rows=1, cols=9)
make_header_row(t, ["#", "Stof", "CAS-nummer", "ADR-klasse", "PG", "Volume", "Verpakking", "Locatie", "Status"])
chemicals = [
    ("1", "Sodium hydroxide 50%", "1310-73-2", "8", "II", "4×25 = 100 l", "Jerrycan", "Rack front of lab", "In stock"),
    ("2", "Sulfuric acid 75%", "7664-93-9", "8", "II", "3×10 = 30 l", "Jerrycan", "Rack front of lab", "In stock"),
    ("3", "Sulfuric acid 50%", "7664-93-9", "8", "II", "7×10 = 70 l", "Jerrycan", "Rack front of lab", "In stock"),
    ("4", "Sulfuric acid 25%", "7664-93-9", "8", "II", "4×25 = 100 l", "Jerrycan", "Rack front of lab", "In stock"),
    ("5", "Aluminum sulfate\noctadecahydrate", "7784-31-8", "N/A", "N/A", "2×2.5 = 5 kg", "Canister", "Rack front of lab", "In stock"),
    ("6", "Calcium oxide", "1305-78-8", "N/A", "N/A", "2×5 = 10 kg", "Canister", "Rack front of lab", "In stock"),
]
for c in chemicals:
    add_table_row(t, c)

doc.add_paragraph()
add_body("Samenvattend:")

items = [
    "Totaal ADR-klasse 8 (bijtend): 300 liter (NaOH + H₂SO₄)",
    "Totaal niet-ADR: 15 kg (aluminiumsulfaat + calciumoxide)",
    "SVHC (Zeer Zorgwekkende Stoffen): geen aanwezig",
    "CMR-stoffen: geen aanwezig",
    "Alle stoffen zijn unopened (in stock, niet geopend)",
    "Leverancier: Carl Roth (alle stoffen)",
    "VIB/MSDS beschikbaar: ja (hardcopy aanwezig)"
]
for item in items:
    p = doc.add_paragraph(item, style='List Bullet')
    for run in p.runs:
        run.font.name = 'Calibri'

doc.add_heading("2.3 Huidige opslagconfiguratie", level=2)
add_body("Alle zes stoffen staan op één storage racking systeem, geplaatst in front of lab. Dit betekent datNaOH (base) en H₂SO₄ (zuur) fysiek op hetzelfde rack staan zonder scheiding. Calcium oxide (sterk basisch) staat eveneens op hetzelfde rack als zwavelzuur. Deze configuratie is conform PGS 15 Bijlage E niet compliant en vereist directe correctie (zie Hoofdstuk 4).")

doc.add_page_break()

# ════════════════════════════════════════════════════════════════════════
# HOOFDSTUK 3: VEILIGHEIDSNIVEAUS EN DREMPELWAARDEN
# ════════════════════════════════════════════════════════════════════════
doc.add_heading("3. Veiligheidsniveaus en Drempelwaarden", level=1)

doc.add_heading("3.1 Systematiek veiligheidsniveaus", level=2)
add_body("PGS 15 hanteert een gelaagd systeem van veiligheidsniveaus, gebaseerd op de aard en hoeveelheid van de opgeslagen gevaarlijke stoffen. Het systeem kent drie hoofdiveau's:[1]")
add_body("Basisveiligheidsniveau (VN Basis): Het fundament. Van toepassing op alle opslagsituaties die boven de ondergrens van Tabel 7 uitkomen. Omvat zorgplicht, stoffenscheiding, vloeistofopvang, ventilatie, verpakkingsintegriteit en personeelsdeskundigheid.")
add_body("VN-B (Verhoogd Veiligheidsniveau B): Geactiveerd bij volumes tussen 10 en 20 ton (afhankelijk van ADR-klasse). Voegt brandwerende scheiding van minimaal 60 minuten toe, evenals aanvullende doelen D6, D10 en D11.")
add_body("VN-A (Verhoogd Veiligheidsniveau A): Het strengste niveau, van toepassing boven 20 ton. Vereist semi-automatische blusinstallatie (VBB), branddetectie met doormelding naar PAC/RAC, en compartimentering volgens D12.")

doc.add_heading("3.2 Analyse voor Phoenix Metals — ADR 8 VG II onbrandbaar", level=2)
add_body("De bij Phoenix Metals aanwezige ADR-klasse 8 stoffen zijn allemaal Packing Group II en onbrandbaar. Dit is de minst stringente categorie binnen ADR 8. De relevante drempelwaarden uit PGS 15 Tabel 6 en Tabel 7 zijn:")

t = doc.add_table(rows=1, cols=3)
make_header_row(t, ["Parameter", "Waarde", "Bron"])
thresholds = [
    ("ADR-klasse 8 VG II, onbrandbaar", "Geen brandbaarheid / brandonderhoudendheid", "Tabel 6"),
    ("Ondergrens Tabel 7 (Tabel 2)", "2.500 kg per ADR-klasse", "Tabel 7"),
    ("Huidig volume ADR 8", "~300 liter (~390 kg)", "Chemisch register"),
    ("Grens VN-B (60 min Wbdbo)", "10.000 kg", "Tabel 6"),
    ("Grens VN-A (D12)", "20.000 kg", "Tabel 6"),
    ("Vereist veiligheidsniveau", "Basisveiligheidsniveau", "Conclusie"),
]
for row_data in thresholds:
    add_table_row(t, row_data, bold_first=True)

doc.add_paragraph()
add_body("Conclusie: Met circa 390 kg ADR 8 stoffen bevindt Phoenix Metals zich ver onder de ondergrens van 2.500 kg (Tabel 7), ver onder de VN-B grens van 10.000 kg en ver onder de VN-A grens van 20.000 kg. Het basisveiligheidsniveau is derhalve voldoende. Geen verhoogd veiligheidsniveau is vereist.")

doc.add_heading("3.3 Volledige drempelwaarden tabel (PGS 15 Tabel 6 & 7)", level=2)
add_body("Onderstaande tabel toont de drempelwaarden voor alle relevante ADR-klassen, ter referentie bij toekomstige schaalbaarheid (zie Hoofdstuk 7):")

t = doc.add_table(rows=1, cols=6)
make_header_row(t, ["ADR-klasse", "Ondergrens Tabel 7", "VN Basis", "VN-B grens", "VN-A grens", "Relevantie PM"])
rows = [
    ("3 (brandbaar, VP≤60°C)", "400 kg (VGI)", "<10 ton", "10-20 ton", ">20 ton", "Niet aanwezig"),
    ("5.1 (oxiderend)", "2.500 kg", "<2,5 ton", "2,5 ton–?", ">2,5 ton", "Niet aanwezig"),
    ("6.1 VGI (giftig)", "1.000 kg", "<1 ton", "—", ">1 ton", "Niet aanwezig"),
    ("6.1 VGII/III", "2.500 kg", "<10 ton", "10-20 ton", ">20 ton", "Niet aanwezig"),
    ("8 VGI (bijtend)", "2.500 kg", "<10 ton", "10-20 ton", ">20 ton", "Niet aanwezig"),
    ("8 VGII/III onbrandbaar", "2.500 kg", "ALLES", "—", "—", "✓ PM categorie"),
    ("8 VGII/III brandbaar", "2.500 kg", "<10 ton", "10-20 ton", ">20 ton", "Niet van toepassing"),
    ("9 (milieugevaarlijk)", "2.500 kg", "ALLES", "—", "—", "Niet aanwezig"),
]
for row_data in rows:
    add_table_row(t, row_data, bold_first=True)

add_body("[1] PGS 15:2025 v1.0, Hoofdstuk 4 — Veiligheidsniveaus en drempelwaarden.")

doc.add_page_break()

# ════════════════════════════════════════════════════════════════════════
# HOOFDSTUK 4: OPSLAG-COMPATIBILITEITSMATRIX
# ════════════════════════════════════════════════════════════════════════
doc.add_heading("4. Opslag-Compatibiliteitsmatrix", level=1)

doc.add_heading("4.1 Bijlage E — Tabel 9: Systeem onverenigbare combinaties", level=2)
add_body("PGS 15 Bijlage E (Tabel 9) definieert welke ADR-klassen niet samen mogen worden opgeslagen en welk scheidingstype vereist is. De volgende legenda geldt:[1]")
add_body("V = Opslag in aparte vakken (compartimenten binnen dezelfde opslagruimte).")
add_body("B = Beoordeel: gescheiden opslag tenzij een Veiligheidsinformatieblad (VIB) aantoont dat de stoffen niet reageren, of beide stoffen zijn vaste stoffen.")
add_body("A = Apart brandcompartiment of 5 meter vrije zone (strengste scheiding).")
add_body("– = Gescheiden opslag niet noodzakelijk.")

doc.add_paragraph()

# Full matrix
t = doc.add_table(rows=1, cols=7)
make_header_row(t, ["ADR-klasse ↓ / →", "3", "5.1", "6.1+CMR", "8", "9", "Overig"])
matrix = [
    ("3 (brandbaar)", "–", "V", "B of V", "B", "B", "–"),
    ("5.1 (oxiderend)", "V", "–", "B of V", "A of V", "B", "–"),
    ("6.1 + CMR", "B of V", "B of V", "B", "A", "B", "–"),
    ("8 (bijtend)", "B", "B", "B", "A", "B", "–"),
    ("9 (milieu)", "B", "B", "B", "A", "B", "–"),
    ("Overig", "–", "–", "–", "A", "–", "–"),
]
for row_data in matrix:
    r = add_table_row(t, row_data, bold_first=True)
    # Highlight A cells
    for i, val in enumerate(row_data):
        if 'A' in val and i > 0:
            set_cell_shading(r.cells[i], "FFE0E0")

doc.add_heading("4.2 Phoenix Metals — Specifieke matrix", level=2)
add_body("Aangezien Phoenix Metals uitsluitend ADR-klasse 8 stoffen en niet-ADR stoffen opslaat, zijn de volgende combinaties relevant:")

t = doc.add_table(rows=1, cols=4)
make_header_row(t, ["Stofcombinatie", "Scheiding?", "Niveau", "Toelichting"])
pm_matrix = [
    ("NaOH 50% ↔ H₂SO₄\n(alle concentraties)", "JA", "A\n(apart brand-\ncompartiment)", "Zuur + Base = exotherme neutralisatiereactie.\nTabel 9: ADR 8 ↔ ADR 8 = A"),
    ("NaOH 50% ↔\nAluminiumsulfaat", "JA", "B\n(beoordelen)", "Base + zout. VIB-consultatie vereist."),
    ("NaOH 50% ↔\nCalciumoxide", "JA", "B\n(beoordelen)", "Beide basisch. Reactiepotentieel laag maar\nbeoordeling vereist."),
    ("H₂SO₄ ↔ H₂SO₄\n(andere concentraties)", "NEE", "–", "Zelfde stof, zelfde gevarenklasse.\nGeen scheiding vereist."),
    ("H₂SO₄ ↔\nAluminiumsulfaat", "BEOORDEEL", "B", "Zuur + zout. Potentiële reactie.\nVIB-consultatie aanbevolen."),
    ("H₂SO₄ ↔\nCalciumoxide", "JA", "A\n(apart brand-\ncompartiment)", "Zuur + sterk basisch oxide = exotherm.\nStrengste scheiding vereist."),
]
for row_data in pm_matrix:
    add_table_row(t, row_data, bold_first=True)

doc.add_heading("4.3 Kritieke bevinding: ADR 8 ↔ ADR 8 conflict", level=2)
add_body("Tabel 9 geeft A als vereist scheiding voor ADR 8 ↔ ADR 8. Dit is het strengste niveau en betekent dat NaOH (base) en H₂SO₄ (zuur) niet in hetzelfde vak mogen worden opgeslagen. De vereiste scheiding is:")
items = [
    "Apart brandcompartiment, óf",
    "Apart deel van het brandcompartiment (3 zijden muur, ≥30 min brandwerendheid), óf",
    "5 meter vrije zone, óf",
    "Aparte vakken indien opslaghoopte ≤1,80 m en UN-goedgekeurde verpakking"
]
for item in items:
    p = doc.add_paragraph(item, style='List Bullet')
    for run in p.runs:
        run.font.name = 'Calibri'

doc.add_heading("4.4 E.3-uitzondering: Praktische oplossing voor Phoenix Metals", level=2)
add_body("PGS 15 Bijlage E, paragraaf E.3 biedt een versoepeling voor opslag onder 10.000 kg. Bij een totaalvolume onder deze grens kan de A-scheiding binnen een vak worden gerealiseerd via:[1]")
items = [
    "2 meter vrije afstand tussen de stofgroepen, of",
    "2 meter buffer met een goedgekeurde combinatiestof, of",
    "Aparte lekbakken (vloeistofopvang) als fysieke scheiding"
]
for item in items:
    p = doc.add_paragraph(item, style='List Bullet')
    for run in p.runs:
        run.font.name = 'Calibri'

add_body("Aanbevolen oplossing voor Phoenix Metals:", bold=True)
items = [
    "NaOH 50% (4 jerrycans à 25 l) → aparte lekbak, gemarkeerd vak op vloer",
    "H₂SO₄ alle concentraties (14 jerrycans) → aparte lekbak, gemarkeerd vak op vloer",
    "Minimaal 2 m afstand tussen beide vakken",
    "Calcium oxide apart opslaan van alle zwavelzuurproducten (A-scheiding)",
    "Aluminiumsulfaat: VIB-consultatie bepalen of scheiding van NaOH nodig is"
]
for item in items:
    p = doc.add_paragraph(item, style='List Bullet')
    for run in p.runs:
        run.font.name = 'Calibri'

add_body("[1] PGS 15:2025 v1.0, Bijlage E — Stoffenscheiding, paragraaf E.3.")

doc.add_page_break()

# ════════════════════════════════════════════════════════════════════════
# HOOFDSTUK 5: BASISVEILIGHEIDSNIVEAU MAATREGELEN
# ════════════════════════════════════════════════════════════════════════
doc.add_heading("5. Basisveiligheidsniveau — Maatregelen", level=1)
add_body("Het basisveiligheidsniveau is het fundament van PGS 15 en geldt voor alle opslagsituaties, ongeacht het volume. Zelfs bij een kleine voorraad van 300 liter zijn deze maatregelen verplicht. Onderstaand worden de voor Phoenix Metals relevante maatregelen geanalyseerd.")

measures = [
    ("5.1", "MW1 — Zorgplicht", "MW1",
     "De opslaghoudende organisatie is verantwoordelijk voor de veiligheid van de opslag van gevaarlijke stoffen en neemt alle maatregelen die redelijkerwijs kunnen worden geëist om risico's voor mens en milieu te voorkomen of te beperken.",
     "De zorgplicht is de paraplu-maatregel. Phoenix Metals moet aantoonbaar in control zijn over de opslag. Dit omvat een RI&E, proceduredocumentatie en een functie-huiswerk voor de opslaglocatie.",
     "⚠️ Toetsen", "Documenteer de zorgplicht in een RI&E met specifieke paragraaf over gevaarlijke stoffen. Stel een verantwoordelijke aan (opslagcoördinator)."),

    ("5.2", "M2 — Opslag in daarvoor bestemde voorziening",
     "M2",
     "Gevaarlijke stoffen worden opgeslagen in een daarvoor bestemde en ingerichte voorziening die voldoet aan de eisen van PGS 15.",
     "Het rack in front of lab moet geschikt zijn voor de opslag van bijtende stoffen. Dit omvat corrosiebestendigheid van het rek, adequate vloerafwerking en toegankelijkheid voor noodsituaties.",
     "⚠️ Toetsen", "Controleer of het racking corrosiebestendig is (gecoat of roestvaststaal). Verifieer vloerdichting en afwatering."),

    ("5.3", "M14 — Werkvoorraad regeling",
     "M14",
     "De werkvoorraad gevaarlijke stoffen mag niet groter zijn dan noodzakelijk voor een ongestoorde bedrijfsvoering over een bepaalde periode.",
     "Met 300 liter aan 6 stoffen is de werkvoorraad beperkt. De vraag is of de huidige hoeveelheid in verhouding staat tot het daadwerkelijke gebruikspatroon van de pilotfaciliteit.",
     "⚠️ Toetsen", "Bepaal het jaarlijkse verbruik per stof. Als de voorraad >6 maanden bedraagt, overweeg voorraadreductie."),

    ("5.4", "M15 — Maximum oppervlakte brandcompartiment",
     "M15",
     "De oppervlakte van het brandcompartiment waarin gevaarlijke stoffen worden opgeslagen is beperkt. Zonder VBB-installatie: maximaal 1.000 m². Met VBB: maximaal 2.500 m².",
     "Phoenix Metals slaat op in één rack in front of lab. De oppervlakte van dit compartiment zal naar alle waarschijnlijkheid ver onder de 1.000 m² liggen.",
     "✅ Compliant", "Geen actie vereist. De oppervlakte is ruim binnen de limiet."),

    ("5.5", "M30 — Vloeistofopvang",
     "M30",
     "Vloeibare gevaarlijke stoffen moeten worden opgeslagen in een voorziening die uitlekkende vloeistof opvangt en voorkomt dat deze in het milieu terechtkomt. De opvangcapaciteit bedraagt minimaal 110% van het volume van de grootste verpakking per lekbak.",
     "De grootste verpakking is een jerrycan van 25 liter. De lekbak moet minimaal 27,5 liter kunnen bevatten (110% van 25 l). Voor meerdere jerrycans in één bak geldt de som van alle volumes of een vergunningspte berekening.",
     "❌ Niet gedocumenteerd", "Plaats lekbakken: minimaal één bak voor NaOH (4×25 l = 100 l → bak ≥110 l) en één bak voor H₂SO₄ (14 jerrycans totaal 200 l → bak ≥220 l of meerdere bakken)."),

    ("5.6", "M35 — Stoffenscheiding",
     "M35",
     "Onverenigbare gevaarlijke stoffen worden gescheiden opgeslagen overeenkomstig Bijlage E (Tabel 9).",
     "NaOH en H₂SO₄ staan op hetzelfde rack zonder scheiding. Dit is niet compliant. Zie Hoofdstuk 4 voor de volledige analyse en aanbevolen oplossing.",
     "❌ Niet compliant", "Directe actie: plaats NaOH en H₂SO₄ in aparte lekbakken met minimaal 2 m afstand. Sla CaO apart van H₂SO₄."),

    ("5.7", "M36/M45 — Verpakking en etikettering",
     "M36/M45",
     "Gevaarlijke stoffen worden opgeslagen in goedgekeurde, onbeschadigde verpakkingen met correcte etikettering conform CLP/ADR.",
     "Alle stoffen zijn geleverd in originele jerrycans/canisters van Carl Roth. Etikettering is fabrieksgarandeerd. Status: unopened.",
     "✅ Compliant", "Periodieke inspectie van verpakkingen bij openen. Beschadigde verpakkingen direct vervangen of verwijderen."),

    ("5.8", "M77/M78 — Fysieke bescherming",
     "M77/M78",
     "De opslagvoorziening is beschermd tegen aanrijding door voertuigen en tegen onbevoegde toegang (M77: botsbeveiliging, M78: fysieke afscherming).",
     "Het rack staat in front of lab. De locatie moet beoordeeld worden op risico van aanrijding (heftrucks, palletwagens) en onbevoegde toegang.",
     "⚠️ Toetsen", "Plaats botsbeveiliging (stootblokken of hekwerk) indien vorkheftruckverkeer in de nabijheid. Beoordeel toegangscontrole."),

    ("5.9", "M85/M86 — Personeelsdeskundigheid",
     "M85/M86",
     "Personen die werken met of toezicht houden op gevaarlijke stoffen beschikken over voldoende deskundigheid. Dit omvat kennis van de stoffen, de risico's, de maatregelen en de noodprocedures (M85: instructie, M86: opleiding).",
     "Alle medewerkers die toegang hebben tot de opslaglocatie moeten instructie hebben ontvangen over de aanwezige stoffen, de gevaren en de te volgen procedures bij incidenten.",
     "⚠️ Toetsen", "Stel een instructiekaart op bij het rack met: stofnamen, gevaren, H-zinnen, P-zinnen, en te volgen acties bij lekkage/brand. Documenteer personeelsinstructie."),
]

for num, title, m_nr, desc, pm_context, status, action in measures:
    doc.add_heading(f"{num} {title}", level=2)
    add_body(desc)
    add_body(f"Situatie Phoenix Metals: {pm_context}")
    p = add_body("")
    p.clear()
    run = p.add_run(f"Status: {status}")
    run.bold = True
    run.font.name = 'Calibri'
    if "❌" in status:
        run.font.color.rgb = RGBColor(0xCC, 0x00, 0x00)
    elif "⚠️" in status:
        run.font.color.rgb = RGBColor(0xCC, 0x88, 0x00)
    else:
        run.font.color.rgb = RGBColor(0x00, 0x88, 0x00)
    add_body(f"Actie: {action}")

doc.add_page_break()

# ════════════════════════════════════════════════════════════════════════
# HOOFDSTUK 6: BRANDPREVENTIE EN COMPARTIMENTERING
# ════════════════════════════════════════════════════════════════════════
doc.add_heading("6. Brandpreventie en Compartimentering", level=1)

doc.add_heading("6.1 Doelen D8, D9, D10", level=2)
add_body("PGS 15 definieert een systeem van veiligheidsdoelen (D-doelen) die de brandpreventie en -bestrijding structureren:[1]")
add_body("D8 — Brandcompartimentering: Voorkom dat brand zich uitbreidt buiten het compartiment waar de opslag zich bevindt. Dit doel is altijd van toepassing, ongeacht het veiligheidsniveau.", bold=False)
add_body("D9 — Voorbehoeding: Voorkom het ontstaan van brand door brandbare en brandonderhoudende stoffen gescheiden te houden van ontstekingsbronnen. Bij Phoenix Metals zijn alle ADR 8 stoffen onbrandbaar, waardoor D9 beperkt relevant is.")
add_body("D10 — Branddetectie en brandbestrijding: Bij verhoogde veiligheidsniveaus (VN-B en VN-A) worden specifieke detectie- en blussystemen vereist. Voor het basisniveau gelden de algemene Bbl-eisen.")

doc.add_heading("6.2 Wbdbo-eisen per veiligheidsniveau", level=2)
add_body("De Weerstand tegen Branddoordoorbraak (Wbdbo) geeft aan hoe lang een constructie-element standhoudt tegen branddoorslag en brandoverslag:")

t = doc.add_table(rows=1, cols=3)
make_header_row(t, ["Veiligheidsniveau", "Wbdbo-eis", "Toepassing Phoenix Metals"])
wbdbo = [
    ("Basisniveau", "Volgens Bbl (Omgevingswet)", "PM valt onder basisniveau.\nStandaard Bouwbesluit-eisen volstaan."),
    ("VN-B (60 min)", "Minimaal 60 minuten\nbrandwerende scheiding", "Niet van toepassing (<10 ton ADR 8)"),
    ("VN-A (D12)", "60-90 minuten\nafhankelijk van constructie", "Niet van toepassing (<20 ton ADR 8)"),
]
for row_data in wbdbo:
    add_table_row(t, row_data, bold_first=True)

doc.add_heading("6.3 M15 — Oppervlaktelimieten", level=2)
add_body("Maatregel M15 beperkt de maximale oppervlakte van het brandcompartiment waarin gevaarlijke stoffen worden opgeslagen:[1]")
add_body("Zonder VBB-installatie: maximaal 1.000 m² per brandcompartiment.")
add_body("Met VBB-installatie: maximaal 2.500 m² per brandcompartiment.")
add_body("Voor Phoenix Metals is de oppervlakte van het rack in front of lab naar alle waarschijnlijkheid minder dan 50 m². De M15-limiet is derhalve ruim overschreden in positieve zin: de oppervlakte is ver onder de maximale grens.")

add_body("[1] PGS 15:2025 v1.0, Hoofdstuk 5 — Brandpreventie en compartimentering.")

doc.add_page_break()

# ════════════════════════════════════════════════════════════════════════
# HOOFDSTUK 7: SCHAALBAARHEIDS-SCENARIO'S
# ════════════════════════════════════════════════════════════════════════
doc.add_heading("7. Schaalbaarheids-Scenario's", level=1)
add_body("Phoenix Metals is een pilotfaciliteit. Bij succesvolle procesontwikkeling kan de opslag van gevaarlijke stoffen toenemen. Dit hoofdstuk schetst de veiligheidseisen en bijbehorende investeringen voor drie groeiscenario's.")

doc.add_heading("7.1 Fase 1: <10.000 kg — Basis + 60 min Wbdbo", level=2)
add_body("Volume: tot 10 ton ADR 8 stoffen.")
add_body("Vereist niveau: Basisveiligheidsniveau, met Wbdbo-eisen conform Bbl.")
add_body("Maatregelen: Alle basismaatregelen uit Hoofdstuk 5 blijven van toepassing. Brandwerende constructie van opslagruimte volgens Bbl. Geen VBB-installatie vereist. Maximaal 1.000 m² brandcompartiment.")
add_body("Investeringsraming: €2.000–€10.000, voornamelijk voor brandwerende deuren, vloerafdichting, ventilatie en administratieve inrichting.")

doc.add_heading("7.2 Fase 2: 10.000–20.000 kg — VN-B (D6, D10, D11)", level=2)
add_body("Volume: 10 tot 20 ton ADR 8 stoffen.")
add_body("Vereist niveau: VN-B (verhoogd veiligheidsniveau B).")
add_body("Maatregelen: Alle basismaatregelen plus: brandwerende scheiding van minimaal 60 minuten (D6), branddetectiesysteem (D10), en aanvullende blusvoorzieningen (D11). Maximaal 1.000 m² brandcompartiment.")
add_body("Investeringsraming: €15.000–€50.000, inclusief branddetectiesysteem, brandwerende wanden/deuren, blusinstallatie en technische documentatie.")

doc.add_heading("7.3 Fase 3: >20.000 kg — VN-A (D12, VBB-installatie)", level=2)
add_body("Volume: meer dan 20 ton ADR 8 stoffen.")
add_body("Vereist niveau: VN-A (verhoogd veiligheidsniveau A, strengste categorie).")
add_body("Maatregelen: Alle VN-B maatregelen plus: semi-automatische blusinstallatie / VBB (M96), branddetectie met doormelding naar PAC/RAC (M97), en compartimentering volgens D12. Maximaal 2.500 m² met VBB.")
add_body("Investeringsraming: €75.000–€200.000, inclusief VBB-installatie, detectie- en alarmsysteem, PAC-doormelding, brandwerende compartimentering en uitgebreide documentatie.")

doc.add_heading("7.4 Overzicht schaalbaarheid", level=2)

t = doc.add_table(rows=1, cols=5)
make_header_row(t, ["Fase", "Volume ADR 8", "Vereist niveau", "Kernmaatregelen", "Investeringsraming"])
scale = [
    ("Huidig", "~390 kg", "Basis", "Lekbakken + stoffenscheiding", "€200–€500"),
    ("Fase 1", "<10 ton", "Basis + Bbl", "Brandwerende constructie,\nventilatie, RI&E", "€2.000–€10.000"),
    ("Fase 2", "10–20 ton", "VN-B", "D6 + D10 + D11,\nblusinstallatie", "€15.000–€50.000"),
    ("Fase 3", ">20 ton", "VN-A", "D12, VBB, PAC-doormelding", "€75.000–€200.000"),
]
for row_data in scale:
    add_table_row(t, row_data, bold_first=True)

doc.add_page_break()

# ════════════════════════════════════════════════════════════════════════
# HOOFDSTUK 8: COMPLIANCE CHECKLIST
# ════════════════════════════════════════════════════════════════════════
doc.add_heading("8. Compliance Checklist", level=1)
add_body("Onderstaande checklist toont de compliance-status per M-maatregel voor Phoenix Metals. De statussen zijn: ✅ Compliant, ❌ Niet compliant, ⚠️ Te toetsen (onvoldoende informatie om status te bepalen).")

t = doc.add_table(rows=1, cols=4)
make_header_row(t, ["M-nr", "Maatregel", "PM Status", "Actie vereist"])
checklist = [
    ("MW1", "Zorgplicht", "⚠️", "RI&E gevaarlijke stoffen opstellen"),
    ("M2", "Opslag in bestemde voorziening", "⚠️", "Racking inspecteren op corrosiebestendigheid"),
    ("M14", "Werkvoorraad regeling", "⚠️", "Jaarverbruik bepalen, voorraad afstemmen"),
    ("M15", "Maximum oppervlakte brandcompartiment", "✅", "Geen actie (ruim binnen limiet)"),
    ("M30", "Vloeistofopvang", "❌", "Lekbakken aanschaffen en plaatsen"),
    ("M35", "Stoffenscheiding", "❌", "NaOH en H₂SO₄ scheiden (aparte lekbakken + 2 m)"),
    ("M36", "Verpakkingsintegriteit", "✅", "Periodieke inspectie bij openen"),
    ("M45", "Etikettering", "✅", "Controle bij ontvangst, behoud origineel etiket"),
    ("M77", "Fysieke bescherming (botsbeveiliging)", "⚠️", "Risico-analyse aanrijding uitvoeren"),
    ("M78", "Fysieke afscherming (toegang)", "⚠️", "Toegangscontrole beoordelen"),
    ("M85", "Personeelsinstructie", "⚠️", "Instructiekaart opstellen, instructie documenteren"),
    ("M86", "Personeelsopleiding", "⚠️", "Bepalen welke opleiding vereist is"),
    ("M89", "Noodplan", "⚠️", "Calamiteitenplan opstellen inclusief lekkageprocedure"),
    ("M96", "VBB-installatie", "✅ NVT", "Niet vereist bij basisniveau"),
    ("M97", "Branddetectie + doormelding", "✅ NVT", "Niet vereist bij basisniveau"),
    ("M103", "Blusinstallatie (VN-B)", "✅ NVT", "Niet vereist bij basisniveau"),
    ("M109", "Toegankelijkheid hulpdiensten", "⚠️", "Bereikbaarheid en routeplan beoordelen"),
]
for row_data in checklist:
    r = add_table_row(t, row_data)
    # Color code status
    status_cell = r.cells[2]
    status_text = row_data[2]
    if "❌" in status_text:
        set_cell_shading(status_cell, "FFE0E0")
    elif "⚠️" in status_text:
        set_cell_shading(status_cell, "FFF3CD")
    elif "✅" in status_text:
        set_cell_shading(status_cell, "D4EDDA")

doc.add_paragraph()
add_body("Samenvatting: 4 maatregelen zijn compliant (✅), 2 maatregelen zijn niet compliant (❌) en 9 maatregelen vereisen nadere toetsing (⚠️). De twee ❌-statussen (M30 en M35) vereisen directe actie.")

doc.add_page_break()

# ════════════════════════════════════════════════════════════════════════
# HOOFDSTUK 9: WETTELIJKE KADERS
# ════════════════════════════════════════════════════════════════════════
doc.add_heading("9. Wettelijke Kaders", level=1)
add_body("Dit hoofdstuk geeft een overzicht van de wettelijke kaders die relevant zijn voor de opslag van gevaarlijke stoffen door Phoenix Metals IJmuiden.")

frameworks = [
    ("9.1", "PGS 15:2025",
     "De Publicatiereeks Gevaarlijke Stoffen 15 (PGS 15) is de primaire richtlijn voor opslag van verpakte gevaarlijke stoffen in Nederland. Versie 1.0, gepubliceerd in januari 2025, bevat de meest actuele eisen voor veiligheidsniveaus, stoffenscheiding, brandpreventie en personeelsdeskundigheid. PGS 15 heeft een informatief juridisch karakter maar fungeert als maatgevend kader onder de Omgevingswet.",
     "Primaire leidraad voor alle opslag- en compliance-activiteiten van Phoenix Metals."),

    ("9.2", "Omgevingswet (Bbl / Bkl)",
     "De Omgevingswet (in werking sinds 1 januari 2024) integreert vergunningseisen voor bouw, milieu en ruimte. Het Besluit bouwwerken leefomgeving (Bbl) stelt eisen aan brandcompartimentering, externe veiligheidsafstanden en constructieve veiligheid. Het Besluit kwaliteit leefomgeving (Bkl) bevat milieukwaliteitseisen. Bevoegd gezag toetst PGS 15 als invulling van Bbl-eisen.",
     "Vergunningsplichtig. PGS 15 naleving is de efficiëntste route om aan Bbl/Bkl te voldoen."),

    ("9.3", "Arbowet / Arbobesluit",
     "De Arbeidsomstandighedenwet (Arbowet) en het Arbobesluit stellen eisen aan veilige werkomstandigheden. Artikel 4.1c Arbobesluit verplicht een Risico-Inventarisatie & -Evaluatie (RI&E) inclusief de risico's van gevaarlijke stoffen. De Arbowet vereist tevens dat werknemers adequaat geïnformeerd en geïnstrueerd worden over de risico's.",
     "RI&E met paragraaf gevaarlijke stoffen verplicht. Personeelsinstructie (M85/M86) is een Arbowet-verplichting."),

    ("9.4", "ADR (Accord européen relatif au transport international des marchandises Dangereuses par Route)",
     "Het ADR is het Europese verdrag voor het vervoer van gevaarlijke stoffen over de weg. Hoewel ADR primair gericht is op transport, gebruikt PGS 15 de ADR-classificatie als basis voor opslagcategorieën. De ADR-klasse, het packing group (PG) en het UN-nummer van een stof bepalen welke PGS 15-eisen van toepassing zijn.",
     "Alle zes stoffen zijn ADR-geclassificeerd (klasse 8, PG II) of niet-ADR. Classificatie bepaalt het PGS 15-regime."),

    ("9.5", "CLP-Verordening (EG 1272/2008)",
     "De CLP-verordening (Classification, Labelling and Packaging) harmoniseert de classificatie, etikettering en verpakking van stoffen en mengsels in de EU. CLP bepaalt de H-zinnen (hazard statements), P-zinnen (precautionary statements) en gevarenpictogrammen op de verpakking.",
     "Relevant voor etikettering van verpakkingen (M36/M45). Alle stoffen zijn geëtiketteerd door leverancier Carl Roth."),

    ("9.6", "REACH (EG 1907/2006)",
     "REACH (Registration, Evaluation, Authorisation and Restriction of Chemicals) is de Europese verordening voor de registratie en beheersing van chemische stoffen. REACH verplicht leveranciers om Veiligheidsinformatiebladen (VIB/SDS) beschikbaar te stellen voor gevaarlijke stoffen.",
     "VIB/SDS beschikbaarheid is vereist (M85). Phoenix Metals beschikt over hardcopy MSDS voor alle stoffen."),
]

for num, title, desc, relevance in frameworks:
    doc.add_heading(f"{num} {title}", level=2)
    add_body(desc)
    add_body(f"Relevantie voor Phoenix Metals: {relevance}", bold=False)

doc.add_page_break()

# ════════════════════════════════════════════════════════════════════════
# BIJLAGEN
# ════════════════════════════════════════════════════════════════════════
doc.add_heading("Bijlagen", level=1)

# Bijlage A
doc.add_heading("Bijlage A: Chemisch Register Phoenix Metals", level=2)
add_body("Volledig overzicht van het chemisch register, gebaseerd op Registration Chemicals MASTER versie 2.1.0.")

t = doc.add_table(rows=1, cols=10)
make_header_row(t, ["#", "Stof", "CAS", "ADR", "PG", "EURAL", "SVHC", "Verpakking", "Volume", "Eenheid"])
chem = [
    ("1", "Sodium hydroxide, 50% in water", "1310-73-2", "8", "II", "060204", "Nee", "Jerrycan", "4 × 25 = 100", "l"),
    ("2", "Sulfuric acid, 75% in water", "7664-93-9", "8", "II", "060101", "Nee", "Jerrycan", "3 × 10 = 30", "l"),
    ("3", "Sulfuric acid, 50% in water", "7664-93-9", "8", "II", "060101", "Nee", "Jerrycan", "7 × 10 = 70", "l"),
    ("4", "Sulfuric acid, 25% in water", "7664-93-9", "8", "II", "060101", "Nee", "Jerrycan", "4 × 25 = 100", "l"),
    ("5", "Aluminum sulfate octadecahydrate", "7784-31-8", "N/A", "N/A", "030614", "Nee", "Canister", "2 × 2,5 = 5", "kg"),
    ("6", "Calcium oxide", "1305-78-8", "N/A", "N/A", "030614", "Nee", "Canister", "2 × 5 = 10", "kg"),
]
for row_data in chem:
    add_table_row(t, row_data)

add_body("Leverancier: Carl Roth (alle stoffen)")
add_body("MSDS beschikbaar: Ja (hardcopy)")
add_body("Locatie: Storage racking — Rack in front of lab")
add_body("Status: In stock (unopened)")

doc.add_page_break()

# Bijlage B
doc.add_heading("Bijlage B: Tabel 6 — Criteria Vereist Veiligheidsniveau", level=2)
add_body("Overzicht van de criteria die bepalen welk veiligheidsniveau vereist is, ontleend aan PGS 15:2025 Tabel 6.")

t = doc.add_table(rows=1, cols=6)
make_header_row(t, ["ADR-klasse", "Subcategorie", "VN Basis", "VN-B\n(60 min Wbdbo)", "VN-A\n(D12)", "Opmerking"])
t6 = [
    ("3", "Brandbaar, VP≤60°C", "<10 ton", "10-20 ton", ">20 ton", "Ondergrens 400 kg (VGI)"),
    ("5.1", "Oxiderend", "<2,5 ton", "2,5–?", ">2,5 ton", "Ondergrens 2.500 kg"),
    ("6.1", "VGI (giftig)", "<1 ton", "—", ">1 ton", "Ondergrens 1.000 kg"),
    ("6.1", "VGII/III", "<10 ton", "10-20 ton", ">20 ton", "Ondergrens 2.500 kg"),
    ("8", "VGI (bijtend)", "<10 ton", "10-20 ton", ">20 ton", "Ondergrens 2.500 kg"),
    ("8", "VGII/III onbrandbaar", "ALLES", "—", "—", "PM: deze categorie"),
    ("8", "VGII/III brandbaar", "<10 ton", "10-20 ton", ">20 ton", "Ondergrens 2.500 kg"),
    ("9", "Milieugevaarlijk", "ALLES", "—", "—", "Ondergrens 2.500 kg"),
    ("CMR", "Acuut toxisch cat 1", "<1 ton", "—", ">1 ton", "Geen ondergrens"),
    ("CMR", "Acuut toxisch cat 2/3", "<10 ton", "10-20 ton", ">20 ton", "Geen ondergrens"),
]
for row_data in t6:
    add_table_row(t, row_data, bold_first=True)

doc.add_page_break()

# Bijlage C
doc.add_heading("Bijlage C: Tabel 9 — Combinaties ADR-klassen", level=2)
add_body("Volledige compatibiliteitsmatrix ontleend aan PGS 15:2025 Bijlage E, Tabel 9.")

t = doc.add_table(rows=1, cols=7)
make_header_row(t, ["ADR ↓ / →", "3 (brandbaar)", "5.1 (oxiderend)", "6.1 + CMR", "8 (bijtend)", "9 (milieu)", "Overig"])
matrix_full = [
    ("3 (brandbaar)", "–", "V", "B of V", "B", "B", "–"),
    ("5.1 (oxiderend)", "V", "–", "B of V", "A of V", "B", "–"),
    ("6.1 + CMR", "B of V", "B of V", "B", "A", "B", "–"),
    ("8 (bijtend)", "B", "B", "B", "A", "B", "–"),
    ("9 (milieu)", "B", "B", "B", "A", "B", "–"),
    ("Overig", "–", "–", "–", "A", "–", "–"),
]
for row_data in matrix_full:
    add_table_row(t, row_data, bold_first=True)

add_body("Legenda: V = apart vak | B = beoordelen | A = apart brandcompartiment / 5 m zone | – = geen scheiding nodig")

doc.add_page_break()

# Bijlage D
doc.add_heading("Bijlage D: Bronnenlijst", level=2)

sources = [
    "[1] PGS 15:2025 versie 1.0, januari 2025. Publicatiereeks Gevaarlijke Stoffen 15 — Opslag van verpakte gevaarlijke stoffen. Sectie Publiek-Private Regelgeving (PPR), Ministerie van Infrastructuur en Waterstaat.",
    "[2] Omgevingswet, in werking getreden 1 januari 2024. Besluit bouwwerken leefomgeving (Bbl) en Besluit kwaliteit leefomgeving (Bkl). Overheid.nl.",
    "[3] Arbeidsomstandighedenwet (Arbowet) en Arbobesluit, artikel 4.1c. Risico-Inventarisatie & -Evaluatie. Overheid.nl.",
    "[4] ADR 2025 — Accord européen relatif au transport international des marchandises Dangereuses par Route. UNECE.",
    "[5] CLP-Verordening (EG) nr. 1272/2008 betreffende classificatie, etikettering en verpakking van stoffen en mengsels. Europese Unie.",
    "[6] REACH-Verordening (EG) nr. 1907/2006 betreffende registratie, evaluatie en autorisatie van chemische stoffen. Europese Unie.",
    "[7] Phoenix Metals — Registration Chemicals MASTER, versie 2.1.0, november 2024. Intern document Phoenix Metals IJmuiden.",
    "[8] JvG Consultancy — META-DOSSIER PGS-15 Compliance Phoenix Metals IJmuiden, versie 1.0, 26 april 2026. Intern werkdocument.",
]

for src in sources:
    p = doc.add_paragraph(src)
    for run in p.runs:
        run.font.name = 'Calibri'
        run.font.size = Pt(10)

# ════════════════════════════════════════════════════════════════════════
# SAVE
# ════════════════════════════════════════════════════════════════════════
os.makedirs(os.path.dirname(OUTPUT), exist_ok=True)
doc.save(OUTPUT)
print(f"✅ Document opgeslagen: {OUTPUT}")
print(f"   Bestandsgrootte: {os.path.getsize(OUTPUT):,} bytes")
