#!/usr/bin/env python3
"""Genereer doc03_partB.docx — H7 t/m H12 + Bijlagen voor Phoenix Metals PGS-15 beleidsdocument."""

from docx import Document
from docx.shared import Pt, Cm, RGBColor
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.oxml.ns import qn

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)

for level in range(1, 4):
    hs = doc.styles[f'Heading {level}']
    hs.font.name = 'Calibri'
    hs.font.color.rgb = RGBColor(0x00, 0x33, 0x66)

def style_header_row(table):
    """Apply #003366 bg + white text to first row."""
    for cell in table.rows[0].cells:
        shading = cell._element.get_or_add_tcPr()
        bg = shading.makeelement(qn('w:shd'), {
            qn('w:fill'): '003366', qn('w:val'): 'clear'
        })
        shading.append(bg)
        for p in cell.paragraphs:
            for r in p.runs:
                r.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
                r.font.bold = True

def add_table(doc, headers, rows):
    t = doc.add_table(rows=1 + len(rows), cols=len(headers))
    t.style = 'Table Grid'
    t.alignment = WD_TABLE_ALIGNMENT.LEFT
    for i, h in enumerate(headers):
        t.rows[0].cells[i].text = h
    for ri, row in enumerate(rows):
        for ci, val in enumerate(row):
            t.rows[ri + 1].cells[ci].text = str(val)
    style_header_row(t)
    doc.add_paragraph()  # spacer

# ============================================================
# H7 Risicobeheersing
# ============================================================
doc.add_heading('7. Risicobeheersing', level=1)

doc.add_paragraph(
    'Dit hoofdstuk beschrijft het risicobeheerskader voor de opslag van gevaarlijke stoffen bij Phoenix Metals IJmuiden. '
    'De risicoanalyse is gebaseerd op het chemisch register (6 stoffen, totaal ~315 kg/l) en de eisen uit PGS 15:2025. '
    'Het kader volgt de methodiek van waarschijnlijkheid versus effect, conform de Arbowetgeving en de richtlijnen uit '
    'de RI&E. Alle risico\'s worden gekwantificeerd via een 5×5 risicomatrix, waarna per geïdentificeerd risico '
    'preventieve en repressieve maatregelen worden gedefinieerd. De focus ligt op de drie meest kritieke risico\'s '
    'die voortvloeien uit de huidige opslagsituatie: de interactie tussen NaOH en H₂SO₄, lekkage zonder adequate opvang, '
    'en onvoldoende personeelsinstructie.'
)

doc.add_heading('7.1 Risicomatrix', level=2)
doc.add_paragraph(
    'De risicomatrix classificeert risico\'s op basis van waarschijnlijkheid (1 = zeer onwaarschijnlijk tot 5 = frequent) '
    'en effect (1 = verwaarloosbaar tot 5 = catastrofaal). Het resulterende risicoprofiel bepaalt de prioriteit en '
    'intensiteit van beheersmaatregelen. Een risicoscore ≥12 vereist directe actie; een score van 6-11 vereist '
    'maatregelen op termijn; een score <6 is acceptabel met standaard controles.'
)

# 5×5 matrix
add_table(doc,
    ['Waarschijnlijkheid \\ Effect', '1 Verwaarloosbaar', '2 Gering', '3 Gemiddeld', '4 Ernstig', '5 Catastrofaal'],
    [
        ['5 Frequent',       '5','10','15','20','25'],
        ['4 Waarschijnlijk', '4','8','12','16','20'],
        ['3 Mogelijk',       '3','6','9','14','19'],
        ['2 Onwaarschijnlijk','2','4','6','8','10'],
        ['1 Zeldzaam',       '1','2','3','4','5'],
    ]
)

doc.add_paragraph(
    'Legenda: Groen (1-5) = acceptabel; Geel (6-11) = maatregelen op termijn; Oranje (12-15) = actie vereist; '
    'Rood (16-25) = onacceptabel, directe actie noodzakelijk.'
)

doc.add_heading('7.2 Top-3 Risico\'s Phoenix Metals', level=2)

doc.add_paragraph(
    'Op basis van de risicoanalyse zijn de volgende drie risico\'s geïdentificeerd als meest kritiek voor de huidige '
    'opslagsituatie. Per risico worden de kans, het effect, preventieve maatregelen en repressieve maatregelen '
    'gedocumenteerd in een gestructureerde tabel.'
)

# Risico 1
doc.add_heading('Risico 1: Menging NaOH + H₂SO₄ (Exotherme Reactie)', level=3)
doc.add_paragraph(
    'Natriumhydroxide (NaOH 50%) en zwavelzuur (H₂SO₄, diverse concentraties) kunnen een sterk exotherme reactie '
    'ondergaan bij menging. Dit resulteert in warmteontwikkeling, spatten van bijtende vloeistof en potentieel '
    'giftige dampvorming. De huidige opslag op hetzelfde rack zonder fysieke scheiding vormt een niet-acceptabel '
    'risico. PGS 15 Bijlage E, Tabel 9 classificeert ADR 8 ↔ ADR 8 als "A" (apart brandcompartiment of 5 m vrije zone) '
    'wanneer het zuur-base combinaties betreft.'
)

add_table(doc,
    ['Parameter', 'Beschrijving'],
    [
        ['Kans', '4 — Waarschijnlijk (stoffen staan opzelfde rack, handling zonder fysieke scheiding)'],
        ['Effect', '4 — Ernstig (chemische brandwonden, spatten, dampvorming)'],
        ['Risicoscore', '16 — ONACCEPTABEL'],
        ['Preventief', '1. Fysieke scheiding: aparte lekbakken met ≥2 m afstand (E.3 uitzondering)\n'
                       '2. Vakmarkering op vloer met kleurcode (blauw = base, rood = zuur)\n'
                       '3. Training personeel: nooit mengen, altijd gescheiden verplaatsen\n'
                       '4. PGS 15 Bijlage E conformiteit aantonen via Tabel 9'],
        ['Repressief', '1. Noodprocedure: bij menging → evacueren, ruimte ventileren\n'
                       '2. Blusmiddelen: CO₂ of droge zand (geen water op geconcentreerd H₂SO₄)\n'
                       '3. PPE altijd beschikbaar: zuurbestendige handschoenen, gezichtsscherm\n'
                       '4. Nooddouche en oogspoelstation binnen 10 seconden bereikbaar'],
    ]
)

# Risico 2
doc.add_heading('Risico 2: Lekkage zonder Adequate Opvang', level=3)
doc.add_paragraph(
    'Bij lekkage van jerrycans (25 l of 10 l) zonder lekbak kan bijtende vloeistof de bodem bereiken, wat leidt tot '
    'grondverontreiniging en mogelijke blootstelling van personeel. De huidige situatie toont geen gedocumenteerde '
    'lekbak-capaciteit. PGS 15 maatregel M30 vereist vloeistofopvang voor alle vloeibare gevaarlijke stoffen, '
    'met een capaciteit van minimaal 110% van het grootste enkelvoudige verpakkingsvolume.'
)

add_table(doc,
    ['Parameter', 'Beschrijving'],
    [
        ['Kans', '3 — Mogelijk (jerrycans op rack, geen lekbakken gedocumenteerd)'],
        ['Effect', '4 — Ernstig (grondverontreiniging, chemische blootstelling, milieuschade)'],
        ['Risicoscore', '12 — ACTIE VEREIST'],
        ['Preventief', '1. Lekbakken aanschaffen: min 110% van grootste verpakking (27,5 l per jerrycan van 25 l)\n'
                       '2. Wekelijkse visuele inspectie van verpakkingen en lekbakken\n'
                       '3. Verpakkingsintegriteitstoets bij ontvangst (M36/M45)\n'
                       '4. Vloerafvoer afsluiten of opvangkuip plaatsen'],
        ['Repressief', '1. Absorptiemateriaal (zand, chemisch absorbent) direct beschikbaar\n'
                       '2. Calamiteitenplan activeren bij grotere lekkage (>10 l)\n'
                       '3. Milieuteam informeren bij bodemcontact\n'
                       '4. Geëxposeerde container verwijderen per verpakkingsvoorschrift'],
    ]
)

# Risico 3
doc.add_heading('Risico 3: Onvoldoende Personeelsinstructie', level=3)
doc.add_paragraph(
    'Onvoldoende kennis van de gevaren en juiste werkwijze bij het hanteren van gevaarlijke stoffen leidt tot '
    'verkeerde handling: verkeerde stoffen bij elkaar plaatsen, verkeerde PPE, of onjuiste reactie bij incidenten. '
    'PGS 15 maatregel M85/M86 stelt expliciete eisen aan de deskundigheid van personeel dat met gevaarlijke stoffen werkt.'
)

add_table(doc,
    ['Parameter', 'Beschrijving'],
    [
        ['Kans', '3 — Mogelijk (geen gedocumenteerd trainingsprogramma vastgesteld)'],
        ['Effect', '3 — Gemiddeld (verkeerde handling → incident, maar beperkt volume)'],
        ['Risicoscore', '9 — MAATREGELEN OP TERMJIN'],
        ['Preventief', '1. Training bij indiensttreding: gevaren stoffen, PPE, noodprocedures\n'
                       '2. Werkinstructiekaarten (WIK) per stof bij opslaglocatie\n'
                       '3. Jaarlijkse herhalingstraining met toetsing\n'
                       '4. Competentie-register bijhouden per medewerker'],
        ['Repressief', '1. Directe supervisie bij het verplaatsen van stoffen\n'
                       '2. Correctieprocedure bij waargenomen onveilig gedrag\n'
                       '3. Incidentregistratie en root-cause analyse\n'
                       '4. Bij herhaling: schriftelijke waarschuwing en verplichte hertraining'],
    ]
)

# ============================================================
# H8 Brandpreventie
# ============================================================
doc.add_heading('8. Brandpreventie', level=1)

doc.add_paragraph(
    'Dit hoofdstuk beschrijft de brandpreventiemaatregelen voor de opslag van gevaarlijke stoffen bij Phoenix Metals. '
    'Hoewel de opgeslagen stoffen (ADR-klasse 8, bijtend) primair onbrandbaar zijn, gelden toch brandpreventieve '
    'eisen vanuit het Bouwbesluit (Bbl) en PGS 15. De brandpreventie is gebaseerd op het basisveiligheidsniveau, '
    'aangezien de totale opslag (~390 kg) ver onder de drempelwaarden van Tabel 6 valt.'
)

doc.add_heading('8.1 Brandcompartimentering per Veiligheidsniveau', level=2)

doc.add_paragraph(
    'De eisen voor brandcompartimentering zijn afhankelijk van het veiligheidsniveau dat bepaald wordt door '
    'de opgeslagen hoeveelheid gevaarlijke stoffen. Onderstaande tabel toont de eisen per niveau.'
)

add_table(doc,
    ['Veiligheidsniveau', 'Wbdbo', 'Max. opp. brandcompartiment', 'Scheidingswand', 'Blussysteem'],
    [
        ['Basis (Bbl)', 'Bbl-eis, min. 30 min', '1.000 m² (<20 t) / 2.500 m² (>20 t)', 'Niet verplicht', 'Niet verplicht'],
        ['VN-B (60 min)', '60 min', '1.000 m²', 'Min. 60 min brandwerend', 'M103 (indien vereist)'],
        ['VN-A (D12)', '60-90 min', '2.500 m² (met VBB)', 'Min. 60 min brandwerend', 'VBB-installatie (M96)'],
    ]
)

doc.add_paragraph(
    'Phoenix Metals valt onder het basisveiligheidsniveau. De Bbl-eis voor wbdbo bedraagt minimaal 30 minuten. '
    'De huidige opslagruimte (storage rack in front of lab) moet worden getoetst op brandwerendheid van de '
    'omsluitende constructie conform het Bouwbesluit.'
)

doc.add_heading('8.2 Blusmiddelen', level=2)

doc.add_paragraph(
    'Voor de opslag van bijtende stoffen gelden de volgende blusmiddelvereisten. Bij voorkeur wordt CO₂ of droog '
    'poeder ingezet; water mag alleen worden gebruikt bij verdund zwavelzuur, niet bij geconcentreerd H₂SO₄ '
    '(exotherme reactie met water).'
)

add_table(doc,
    ['Blusmiddel', 'Type', 'Plaatsing', 'Inspectie', 'Toepassing'],
    [
        ['CO₂', 'Koolzuursneeuw', 'Binnen 15 m van opslaglocatie', 'Jaarlijks (KEUR)', 'Elektrische en vloeistofbranden'],
        ['Droog poeder (ABC)', 'Poederblusser 6 kg', 'Bij uitgang opslagruimte', 'Jaarlijks (KEUR)', 'Algemene brandbestrijding'],
        ['Zand/Absorbent', 'Droog zand of chemisch absorbent', 'Direct naast opslagrack', 'Maandelijks (voorraadcheck)', 'Lekkage + kleine branden'],
        ['Nooddouche/Oogspoel', 'Gecombineerd unit', 'Binnen 10 sec loopafstand', 'Wekelijks (activering)', 'Blootstelling bijtend materiaal'],
    ]
)

doc.add_heading('8.3 Weerstand tegen Branddoorgang en Brandoverslag (Wbdbo)', level=2)

doc.add_paragraph(
    'Voor het basisveiligheidsniveau geldt de Bbl-eis als minimum voor de wbdbo van de omsluitende constructie '
    'van het opslagcompartiment. Dit betekent dat wanden, vloeren en daken waaraan de opslagruimte grenst '
    'minimaal moeten voldoen aan de brandwerendheid die het Bouwbesluit voorschrijft voor het betreffende '
    'gebruiksfunctie. Bij overschrijding van de Tabel 6-drempelwaarden (10 ton of 20 ton) stijgt de eis naar '
    'respectievelijk 60 minuten en 60-90 minuten.'
)

doc.add_heading('8.4 Normatieve Referenties', level=2)

doc.add_paragraph(
    'De brandpreventie is gebaseerd op de volgende normen: NEN 6060 (Bepaling van de brandwerendheid van '
    'bouwconstructiedelen), NEN 6069 (Brandwerendheid van constructiedelen — rekenmethode), en NEN 6079 '
    '(Brandbeheersingsinstallaties — blusinstallaties). Deze normen worden toegepast bij de bepaling van de '
    'wbdbo en de eventuele toekomstige uitbreiding van blussystemen bij schaalvergroting.'
)

doc.add_heading('8.5 Brandweerbereikbaarheid (M109)', level=2)

doc.add_paragraph(
    'PGS 15 maatregel M109 stelt eisen aan de bereikbaarheid van de opslaglocatie voor hulpdiensten. '
    'De opslagruimte dient bereikbaar te zijn voor brandweervoertuigen via een verhard en vrijgehouden '
    'toegangsweg van minimaal 3 meter breedte. Brandkraan of alternatieve watervoorziening dient binnen '
    '100 meter van de opslaglocatie beschikbaar te zijn. De locatiegegevens (adres, bereikbaarheid, '
    'aanwezige stoffen) worden jaarlijks doorgegeven aan de regionale brandweer via het digimeldplicht-systeem.'
)

# ============================================================
# H9 Opleiding en Instructie
# ============================================================
doc.add_heading('9. Opleiding en Instructie', level=1)

doc.add_paragraph(
    'Een adequaat opleidings- en instructieprogramma is essentieel voor veilige opslag en handling van gevaarlijke '
    'stoffen. PGS 15 maatregelen M85 en M86 definiëren de eisen aan de deskundigheid van alle betrokken personen. '
    'Dit hoofdstuk beschrijft de verantwoordelijkheden per rol, de opleidingsmatrix, herhalingstermijnen en '
    'competentie-eisen.'
)

doc.add_heading('9.1 Verantwoordelijkheden per Rol', level=2)

add_table(doc,
    ['Rol', 'Verantwoordelijkheid', 'Vereist niveau'],
    [
        ['Directie / Bedrijfsleider', 'Zorgplicht MW1: aantoonbaar veilige opslag', 'Basiswaanwezigheid + bewustzijn'],
        [' veiligheidscoördinator', 'Toezicht op naleving PGS 15, uitvoering inspecties', 'PGS 15 basiskennis + RI&E'],
        ['Magazijnmedewerker', 'Dagelijkse handling, opslag, inspectie verpakkingen', 'Stofspecifieke training + PPE'],
        ['Externe medewerkers / Aannemers', 'Gebonden aan huisregels bij betreding opslag', 'Instructie bij binnenkomst'],
    ]
)

doc.add_heading('9.2 Opleidingsmatrix', level=2)

doc.add_paragraph(
    'Onderstaande matrix toont de vereiste opleidingsonderwerpen per doelgroep. Een "V" betekent volledige '
    'training vereist; "B" betekent basiskennis/briefing; "-" betekent niet van toepassing.'
)

add_table(doc,
    ['Onderwerp', 'Directie', 'Veiligheids-coördinator', 'Magazijn-medewerker', 'Externe'],
    [
        ['PGS 15 basisprincipes', 'B', 'V', 'B', '-'],
        ['Chemische gevaren stoffenregister', 'B', 'V', 'V', 'B'],
        ['Stoffenscheiding (Tabel 9)', '-', 'V', 'V', '-'],
        ['PPE gebruik en onderhoud', '-', 'V', 'V', 'B'],
        ['Noodprocedures en evacuatie', 'B', 'V', 'V', 'B'],
        ['Inspectie- en controleprocedures', '-', 'V', 'V', '-'],
        ['Brandpreventie en blusmiddelen', 'B', 'V', 'V', 'B'],
        ['Wetgeving (Arbowet, Omgevingswet)', 'V', 'V', 'B', '-'],
    ]
)

doc.add_heading('9.3 Herhalingstermijnen', level=2)

add_table(doc,
    ['Trigger', 'Frequentie', 'Scope'],
    [
        ['Regulier', 'Jaarlijks', 'Alle opleidingsonderwerpen voor betreffende rol'],
        ['Na incident', 'Binnen 1 week na incident', 'Stofspecifieke training + root-cause bespreking'],
        ['Bij wijziging', 'Voorafgaand aan wijziging', 'Nieuwe stoffen, gewijzigde procedures, nieuwe apparatuur'],
        ['Bij indiensttreding', 'Voorafgaand aan werkzaamheden', 'Volledige opleiding per rol'],
    ]
)

doc.add_heading('9.4 Competentie-eisen', level=2)

doc.add_paragraph(
    'Alle medewerkers die in aanraking komen met gevaarlijke stoffen moeten aantoonbaar competent zijn. '
    'Competentie wordt aangetoond door: (1) succesvolle afronding van de verplichte training, (2) praktijktoets '
    'onder supervisie van de veiligheidscoördinator, en (3) ondertekening van een competentieverklaring. '
    'De competentieverklaring wordt jaarlijks herzien en bijgehouden in het personeelsdossier. '
    'Externe medewerkers ontvangen een specifieke inwerkbriefing bij elke betreding van de opslagruimte.'
)

# ============================================================
# H10 Toezicht en Handhaving
# ============================================================
doc.add_heading('10. Toezicht en Handhaving', level=1)

doc.add_paragraph(
    'Structureel toezicht en handhaving waarborgen de continue naleving van de PGS 15-maatregelen. '
    'Dit hoofdstuk definieert het audit- en inspectieregime, de frequentie van controles en de procedure '
    'bij non-compliance.'
)

doc.add_heading('10.1 Interne Audits', level=2)

doc.add_paragraph(
    'Jaarlijks wordt een interne audit uitgevoerd op de volledige PGS 15-compliance. De audit wordt '
    'uitgevoerd door de veiligheidscoördinator of een aangewezen interne auditor. De scope omvat: '
    'stofregisters, stoffenscheiding, lekbakken, ventilatie, brandpreventie, PPE, opleidingsstatus, '
    'en documentbeheer. Criteria zijn afgeleid van de PGS 15:2025 maatregelenlijst (M2 t/m M109). '
    'Bevindingen worden gecategoriseerd als: conform, afwijking (verbeteractie binnen 30 dagen), '
    'of non-conformiteit (directe actie vereist). Het auditrapport wordt besproken met de directie.'
)

doc.add_heading('10.2 Inspectieschema', level=2)

add_table(doc,
    ['Frequentie', 'Inspectieonderwerp', 'Uitvoerder', 'Registratie'],
    [
        ['Dagelijks', 'Visuele check verpakkingen, lekbakken, vakmarkering', 'Magazijnmedewerker', 'Checklist (digitaal)'],
        ['Wekelijks', 'Lekbak-capaciteit, PPE-voorraad, absorbent-voorraad', 'Veiligheidscoördinator', 'Inspectierapport'],
        ['Maandelijks', 'Ventilatie, blusmiddelen KEUR-status, SDS-beschikbaarheid', 'Veiligheidscoördinator', 'Maandrapportage'],
        ['Kwartaallijks', 'Opleidingsstatus, competentie-verklaringen, incidentenanalyse', 'Directie + VG-coördinator', 'Kwartaalreview'],
        ['Jaarlijks', 'Volledige PGS 15-audit, RI&E-herziening, noodplanoefening', 'Interne auditor', 'Auditrapport'],
    ]
)

doc.add_heading('10.3 Non-Compliance Procedure', level=2)

doc.add_paragraph(
    'Bij constatering van non-compliance wordt de volgende trapsgewijze procedure gevolgd: '
    '(1) Mondelinge waarschuwing door de veiligheidscoördinator met directe herstelverplichting; '
    '(2) Schriftelijke waarschuwing bij herhaling binnen 3 maanden, met verbeterplan en deadline; '
    '(3) Sanctie bij structurele non-compliance: schorsing van bevoegdheid tot aantoonbare herstelling, '
    'of — bij ernstig gevaar — onmiddellijke stillegging van de betreffende werkzaamheden. '
    'Alle non-conformiteiten worden geregistreerd in het verbeterregister en besproken tijdens de '
    'kwartaalreview met de directie.'
)

# ============================================================
# H11 Documentbeheer
# ============================================================
doc.add_heading('11. Documentbeheer', level=1)

doc.add_paragraph(
    'Dit hoofdstuk beschrijft het versiebeheer, de herzieningstermijnen en de distributie van alle documenten '
    'die behoren tot het PGS 15-veiligheidsbeheerssysteem van Phoenix Metals.'
)

doc.add_heading('11.1 Versiebeheer', level=2)

add_table(doc,
    ['Document', 'Huidige versie', 'Laatste herziening', 'Volgende herziening'],
    [
        ['PGS 15 Beleidsdocument (Part A + B)', 'v1.0', '26 april 2026', '26 april 2027'],
        ['Chemisch Register', 'v2.1.0', '26 april 2026', 'Bij wijziging'],
        ['Calamiteitenplan', 'v1.0', '26 april 2026', '26 april 2027'],
        ['Inspectieformulieren', 'v1.0', '26 april 2026', '26 april 2027'],
        ['Opleidingsmatrix', 'v1.0', '26 april 2026', 'Bij wijziging'],
        ['RI&E', 'v1.0', '26 april 2026', '26 april 2027'],
    ]
)

doc.add_heading('11.2 Herzieningstermijnen', level=2)

doc.add_paragraph(
    'Alle documenten worden minimaal jaarlijks herzien. Tussentijdse herziening is verplicht bij: '
    '(1) wijziging van wet- of regelgeving, (2) wijziging van het stoffenpakket (toevoeging of verwijdering '
    'van stoffen), (3) wijziging van de opslagconfiguratie, (4) na een incident of bijna-ongeval, of '
    '(5) na een audit met substantiële bevindingen. De verantwoordelijkheid voor herziening ligt bij de '
    'veiligheidscoördinator, met goedkeuring door de directie.'
)

doc.add_heading('11.3 Distributielijst', level=2)

add_table(doc,
    ['Document', 'Directie', 'Veiligheids-coördinator', 'Magazijn', 'Externe (brandweer)'],
    [
        ['Beleidsdocument', 'V', 'V', 'Samenvatting', '-'],
        ['Chemisch Register', 'V', 'V', 'V (bij opslag)', 'Raadpleegbaar'],
        ['Calamiteitenplan', 'V', 'V', 'V', 'V'],
        ['SDS / VIB per stof', 'Digitaal', 'V', 'V (bij opslag)', 'Op aanvraag'],
        ['Inspectieformulieren', 'Inzage', 'V', 'Uitvoering', '-'],
    ]
)

# ============================================================
# H12 Bijlagen
# ============================================================
doc.add_heading('12. Bijlagen', level=1)

doc.add_heading('Bijlage A: Chemisch Register Phoenix Metals', level=2)

doc.add_paragraph(
    'Overzicht van alle opgeslagen gevaarlijke stoffen, gebaseerd op het chemisch register v2.1.0.'
)

add_table(doc,
    ['#', 'Stof', 'CAS-nummer', 'ADR-klasse', 'Verpakkingsgroep', 'Volume', 'Verpakking'],
    [
        ['1', 'Sodium hydroxide 50%', '1310-73-2', '8', 'II', '100 l (4×25 l)', 'Jerrycan'],
        ['2', 'Sulfuric acid 75%', '7664-93-9', '8', 'II', '30 l (3×10 l)', 'Jerrycan'],
        ['3', 'Sulfuric acid 50%', '7664-93-9', '8', 'II', '70 l (7×10 l)', 'Jerrycan'],
        ['4', 'Sulfuric acid 25%', '7664-93-9', '8', 'II', '100 l (4×25 l)', 'Jerrycan'],
        ['5', 'Aluminum sulfate octadecahydrate', '7784-31-8', 'N/A', 'N/A', '5 kg (2×2,5 kg)', 'Canister'],
        ['6', 'Calcium oxide', '1305-78-8', 'N/A', 'N/A', '10 kg (2×5 kg)', 'Canister'],
    ]
)

doc.add_heading('Bijlage B: Compatibiliteitsmatrix', level=2)

doc.add_paragraph(
    'Scheidingseisen voor alle combinaties van de 6 opgeslagen stoffen, gebaseerd op PGS 15 Bijlage E, Tabel 9. '
    'A = apart brandcompartiment of 5 m vrije zone; B = beoordelen; - = geen scheiding vereist.'
)

add_table(doc,
    ['', 'NaOH 50%', 'H₂SO₄ 75%', 'H₂SO₄ 50%', 'H₂SO₄ 25%', 'Al₂(SO₄)₃', 'CaO'],
    [
        ['NaOH 50%', '-', 'A', 'A', 'A', 'B', 'B'],
        ['H₂SO₄ 75%', 'A', '-', '-', '-', 'B', 'A'],
        ['H₂SO₄ 50%', 'A', '-', '-', '-', 'B', 'A'],
        ['H₂SO₄ 25%', 'A', '-', '-', '-', 'B', 'A'],
        ['Al₂(SO₄)₃', 'B', 'B', 'B', 'B', '-', '-'],
        ['CaO', 'B', 'A', 'A', 'A', '-', '-'],
    ]
)

doc.add_heading('Bijlage C: Referenties PGS 15:2025', level=2)

doc.add_paragraph(
    'Overzicht van de in dit document gehanteerde referenties uit PGS 15:2025 en gerelateerde normen.'
)

add_table(doc,
    ['#', 'Referentie', 'Omschrijving'],
    [
        ['1', 'PGS 15:2025', 'Publicatiereeks Gevaarlijke Stoffen 15 — Opslag van verpakte gevaarlijke stoffen'],
        ['2', 'Tabel 6', 'Drempelwaarden veiligheidsniveaus'],
        ['3', 'Tabel 7', 'Ondergrenzen per ADR-klasse'],
        ['4', 'Tabel 9 / Bijlage E', 'Compatibiliteitsmatrix en scheidingseisen'],
        ['5', 'M2', 'Opslag in daarvoor bestemde voorziening'],
        ['6', 'M14', 'Werkvoorraadregeling'],
        ['7', 'M15', 'Maximum oppervlakte brandcompartiment'],
        ['8', 'M30', 'Ventilatie en vloeistofopvang'],
        ['9', 'M35', 'Stoffenscheiding'],
        ['10', 'M36/M45', 'Verpakkingsintegriteit'],
        ['11', 'M77/M78', 'Fysieke bescherming (botsbeveiliging)'],
        ['12', 'M85/M86', 'Deskundigheid personeel en opleiding'],
        ['13', 'M89', 'Noodplan'],
        ['14', 'M96', 'VBB-installatie'],
        ['15', 'M97', 'Branddetectie en doormelding'],
        ['16', 'M103', 'Blussysteem (VN-B)'],
        ['17', 'M109', 'Brandweerbereikbaarheid'],
    ]
)

# Save
out = '/root/projects/jg/2026-pgs15-phoenix-metals/working/map/doc03_partB.docx'
doc.save(out)

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