#!/usr/bin/env python3
"""
PGS 15:2025 DOCX Generator — Kennisdossier + Niveaubepaling Rapport
Phoenix Metals B.V.
"""

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

# ════ CONSTANTS ════
PRIMARY = RGBColor(0, 51, 102)  # #003366
TEXT_DARK = RGBColor(0x1F, 0x29, 0x37)  # #1F2937
TEXT_SEC = RGBColor(0x37, 0x41, 0x51)
ACCENT = RGBColor(0x3B, 0x82, 0xF6)
CRITICAL = RGBColor(0xEF, 0x44, 0x44)
WARNING = RGBColor(0xF5, 0x9E, 0x0B)
SUCCESS = RGBColor(0x00, 0xA8, 0x59)

LOGO_PATH = '/root/projects/jg/assets/branding/jvg-logo-white-medium.png'
BASE = '/root/projects/jg/2026-pgs15-2025-phoenix-metals/deliverables/docx'


# ════ HELPERS ════

def setup_styles(doc):
    """Configure document styles."""
    style = doc.styles['Normal']
    style.font.name = 'Calibri'
    style.font.size = Pt(11)
    style.font.color.rgb = TEXT_DARK
    style.paragraph_format.space_after = Pt(6)
    style.paragraph_format.line_spacing_rule = WD_LINE_SPACING.MULTIPLE

    for lvl, sz, clr in [(1, 16, PRIMARY), (2, 14, PRIMARY), (3, 12, ACCENT)]:
        hs = doc.styles[f'Heading {lvl}']
        hs.font.name = 'Calibri'
        hs.font.bold = True
        hs.font.size = Pt(sz)
        hs.font.color.rgb = clr


def add_logo_header(doc):
    """Add logo to document header."""
    section = doc.sections[0]
    header = section.header
    header.is_linked_to_previous = False
    hp = header.paragraphs[0]
    hp.alignment = WD_ALIGN_PARAGRAPH.RIGHT
    if os.path.exists(LOGO_PATH):
        run = hp.add_run()
        run.add_picture(LOGO_PATH, width=Cm(2.0), height=Cm(1.8))


def add_footer(doc, project_code, version, date_str):
    """Add footer with project info and page number."""
    section = doc.sections[0]
    footer = section.footer
    footer.is_linked_to_previous = False
    fp = footer.paragraphs[0]
    fp.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = fp.add_run(f'{project_code} | {version} | {date_str}  —  Pagina ')
    run.font.size = Pt(8)
    run.font.color.rgb = TEXT_SEC
    
    # Add page number field
    fldChar1 = OxmlElement('w:fldChar')
    fldChar1.set(qn('w:fldCharType'), 'begin')
    run2 = fp.add_run()
    run2._r.append(fldChar1)
    
    instrText = OxmlElement('w:instrText')
    instrText.set(qn('xml:space'), 'preserve')
    instrText.text = ' PAGE '
    run3 = fp.add_run()
    run3._r.append(instrText)
    
    fldChar2 = OxmlElement('w:fldChar')
    fldChar2.set(qn('w:fldCharType'), 'end')
    run4 = fp.add_run()
    run4._r.append(fldChar2)
    
    run2.font.size = Pt(8)
    run2.font.color.rgb = TEXT_SEC
    run3.font.size = Pt(8)
    run3.font.color.rgb = TEXT_SEC
    run4.font.size = Pt(8)
    run4.font.color.rgb = TEXT_SEC


def add_table(doc, headers, data, col_widths=None):
    """Add a styled table."""
    table = doc.add_table(rows=1 + len(data), cols=len(headers))
    table.style = 'Light Grid Accent 1'
    table.alignment = WD_TABLE_ALIGNMENT.LEFT
    
    # Headers
    for i, h in enumerate(headers):
        cell = table.rows[0].cells[i]
        cell.text = ''
        p = cell.paragraphs[0]
        run = p.add_run(h)
        run.bold = True
        run.font.color.rgb = PRIMARY
        run.font.size = Pt(10)
    
    # Data
    for r_idx, row in enumerate(data):
        for c_idx, val in enumerate(row):
            cell = table.rows[r_idx + 1].cells[c_idx]
            cell.text = ''
            p = cell.paragraphs[0]
            run = p.add_run(str(val))
            run.font.size = Pt(10)
            run.font.color.rgb = TEXT_DARK
    
    return table


def add_key_point(doc, text, icon='►'):
    p = doc.add_paragraph()
    run = p.add_run(f'{icon} {text}')
    run.bold = True
    run.font.color.rgb = PRIMARY


def add_warning(doc, text):
    p = doc.add_paragraph()
    p.paragraph_format.left_indent = Cm(0.5)
    run = p.add_run(f'⚠️ {text}')
    run.font.color.rgb = CRITICAL
    run.bold = True


def add_info(doc, text):
    p = doc.add_paragraph()
    p.paragraph_format.left_indent = Cm(0.5)
    run = p.add_run(f'ℹ️ {text}')
    run.font.color.rgb = ACCENT
    run.bold = True


# ════ DOC 5: KENNISDOSSIER ════

def generate_kennisdossier():
    doc = Document()
    setup_styles(doc)
    add_logo_header(doc)
    add_footer(doc, 'PGS15-PM', 'v1.0', '27 april 2026')
    
    doc.core_properties.title = 'PGS15-PM Kennisdossier PGS 15:2025 v1.0'
    doc.core_properties.author = 'HQ_04 Technical Writer via Kas'
    doc.core_properties.keywords = 'PGS 15; opslag; gevaarlijke stoffen; niveaubepaling; Phoenix Metals'
    doc.core_properties.category = 'HSEQ Intelligence'
    
    # === COVER ===
    for _ in range(4):
        doc.add_paragraph()
    
    t = doc.add_paragraph()
    t.alignment = WD_ALIGN_PARAGRAPH.CENTER
    r = t.add_run('KENNISDOSSIER')
    r.bold = True
    r.font.size = Pt(28)
    r.font.color.rgb = PRIMARY
    
    t2 = doc.add_paragraph()
    t2.alignment = WD_ALIGN_PARAGRAPH.CENTER
    r2 = t2.add_run('PGS 15:2025 — Opslag Gevaarlijke Stoffen')
    r2.font.size = Pt(18)
    r2.font.color.rgb = TEXT_SEC
    
    doc.add_paragraph()
    
    t3 = doc.add_paragraph()
    t3.alignment = WD_ALIGN_PARAGRAPH.CENTER
    r3 = t3.add_run('Werkvoorbeeld: Phoenix Metals B.V.')
    r3.font.size = Pt(14)
    r3.font.color.rgb = ACCENT
    
    for _ in range(4):
        doc.add_paragraph()
    
    meta_lines = [
        'Project: PGS15-PM',
        'Versie: 1.0',
        'Datum: 27 april 2026',
        'Locatie: Tata Steel terrein, IJmuiden',
        'Doelgroep: HSE professionals, management, operators',
    ]
    for line in meta_lines:
        p = doc.add_paragraph()
        p.alignment = WD_ALIGN_PARAGRAPH.CENTER
        run = p.add_run(line)
        run.font.size = Pt(11)
        run.font.color.rgb = TEXT_SEC
    
    doc.add_page_break()
    
    # === 1. MANAGEMENT SAMENVATTING ===
    doc.add_heading('1. Management Samenvatting', level=1)
    
    doc.add_paragraph(
        'Dit kennisdossier biedt een uitgebreide uitleg van het PGS 15:2025 systeem voor de veilige '
        'opslag van verpakte gevaarlijke stoffen, met Phoenix Metals B.V. als werkvoorbeeld. '
        'Phoenix Metals produceert vanadium(V)oxide (V₂O₅) uit staalslakken via een hydrometallurgisch '
        'proces op het Tata Steel terrein in IJmuiden.'
    )
    
    add_key_point(doc, 'Bepaald opslagniveau: C-NIVEAU (Wbdbo 60 minuten)')
    add_key_point(doc, 'Bepalende factor: V₂O₅ — Carc. 1B (H350i), Acute Tox. 2 (H330), ADR 6.1 VG II')
    add_key_point(doc, 'Drempel A-niveau: >10.000 kg V₂O₅ (via CLP Acute Tox. 2)')
    add_key_point(doc, 'ADR 8 bijtende stoffen (~410 kg): Basisveiligheidsniveau (onbrandbaar, voetnoot c)')
    
    doc.add_paragraph()
    add_warning(doc, 'V₂O₅ hoeveelheid moet structureel worden gemonitord. Bij >10 ton opschaling naar A-niveau (automatische blussing) verplicht.')
    
    doc.add_paragraph(
        'Het dossier behandelt: (1) het wettelijk kader van PGS 15:2025, (2) het niveaubepalingssysteem '
        'met ADR- en CLP-routes, (3) de scheidingstabel, (4) CMR-stoffen, (5) V₂O₅ specifieke aandachtspunten, '
        'en (6) de casus Phoenix Metals als praktijkvoorbeeld.'
    )
    
    doc.add_page_break()
    
    # === 2. ACHTERGROND PGS 15:2025 ===
    doc.add_heading('2. Achtergrond PGS 15:2025', level=1)
    
    doc.add_heading('2.1 Wat is PGS 15?', level=2)
    doc.add_paragraph(
        'PGS 15 (Publicatie 565) is de Nederlandse richtlijn voor de veilige opslag van verpakte '
        'gevaarlijke stoffen. Versie 1.0 is gepubliceerd in januari 2025 en vervangt de eerdere '
        'versie (PGS 15:2019). De richtlijn wordt gehanteerd als stand van techniek door '
        'toezichthouders (Inspectie SZW, omgevingsdiensten).'
    )
    
    doc.add_heading('2.2 Wettelijk kader', level=2)
    doc.add_paragraph('De belangrijkste wettelijke grondslagen:')
    
    add_table(doc,
        ['Wetgeving', 'Artikel', 'Relevantie'],
        [
            ['Arbowet', 'Art. 4.1c', 'Preventiemaatregelen gevaarlijke stoffen'],
            ['Arbowet', 'Art. 4.1d', 'Register gevaarlijke stoffen'],
            ['Omgevingswet', 'Art. 4.1012 Bal', 'Opslag gevaarlijke stoffen'],
            ['CLP (EG 1272/2008)', 'Bijlage VI', 'Geharmoniseerde classificatie'],
            ['ADR', 'Deel 2-4', 'Transportclassificatie'],
        ]
    )
    
    doc.add_paragraph()
    doc.add_paragraph(
        'PGS 15 is een richtlijn (niet wettelijk bindend), maar wordt gehanteerd als stand van techniek. '
        'Het niet opvolgen van PGS 15 kan worden beschouwd als een overtreding van de zorgplicht uit '
        'de Arbowet.'
    )
    
    doc.add_heading('2.3 Toepassingsgebied', level=2)
    doc.add_paragraph('PGS 15 is van toepassing op opslag van verpakte gevaarlijke stoffen die vallen onder:')
    
    items = [
        'ADR-klassen 2, 3, 4.1, 4.2, 4.3, 5.1, 5.2, 6.1, 6.2, 8, 9 (met uitzonderingen, zie Tabel 1)',
        'CMR-stoffen (behalve metalen in vaste vorm)',
        'CLP-stoffen met Acute Toxiciteit cat. 1/2/3',
        'Gewasbeschermingsmiddelen en biociden ≥400 kg',
    ]
    for item in items:
        doc.add_paragraph(item, style='List Bullet')
    
    doc.add_page_break()
    
    # === 3. NIVEAUBEPALING SYSTEEM ===
    doc.add_heading('3. Niveaubepaling Systeem (ADR + CLP)', level=1)
    
    doc.add_heading('3.1 Twee onafhankelijke routes', level=2)
    doc.add_paragraph(
        'PGS 15:2025 kent twee onafhankelijke classificatieroutes. Voor elke stof worden beide '
        'routes berekend. Het hoogste (strengste) veiligheidsniveau geldt.'
    )
    
    doc.add_heading('ADR-route', level=3)
    doc.add_paragraph(
        'Bepaald op basis van ADR-klasse en Verpakkingsgroep (VG). '
        'VG I: hoogste gevaar → laagste ondergrens (1 kg). '
        'VG II: middelhoge gevaar. '
        'VG III: lagere gevaar.'
    )
    
    doc.add_heading('CLP-route', level=3)
    doc.add_paragraph(
        'Bepaald op basis van CLP-classificatie (H-zinnen). '
        'Acute Tox. Cat. 1: ondergrens 1 kg. '
        'Acute Tox. Cat. 2/3: ondergrens 1 kg. '
        'CMR Cat. 1A/1B: ondergrens 25 kg (poeder/vloeistof).'
    )
    
    doc.add_heading('3.2 Niveaus', level=2)
    add_table(doc,
        ['Niveau', 'Betekenis', 'Constructieve eisen'],
        [
            ['Basisveiligheidsniveau', 'Minimale eisen, altijd van toepassing', 'Zorgplicht, stellingen, productopvang'],
            ['C-niveau', 'Brandwerende constructie', 'Wbdbo 60/90 min, branddetectie'],
            ['B-niveau', 'Compartimentering', '+ detectie + doormelding'],
            ['A-niveau', 'Automatische blussing', '+ VBB-installatie'],
        ]
    )
    
    doc.add_paragraph()
    doc.add_paragraph(
        'De strengste route prevaleert. Als de ADR-route C-niveau oplevert en de CLP-route eveneens '
        'C-niveau, dan is het bepaalde opslagniveau C.'
    )
    
    doc.add_heading('3.3 Tabel 6 — Drempelwaarden (uitleg)', level=2)
    add_table(doc,
        ['Stofklasse', 'VG', 'Hoeveelheid', 'Niveau', 'Wbdbo'],
        [
            ['ADR 6.1', 'I', '<1 ton', 'C', '60 min'],
            ['ADR 6.1', 'I', '>1 ton', 'A', '—'],
            ['ADR 6.1', 'II', '<10 ton', 'C', '60 min'],
            ['ADR 6.1', 'II', '<20 ton', 'C', '90 min'],
            ['ADR 6.1', 'II', '>20 ton', 'A', '—'],
            ['ADR 8 VG II+III onbrandbaar', '—', 'Elke hoeveelheid', 'Basis¹', '—'],
            ['CLP Acute Tox. 1', '—', '<1 ton', 'C', '60 min'],
            ['CLP Acute Tox. 1', '—', '>1 ton', 'A', '—'],
            ['CLP Acute Tox. 2/3', '—', '<10 ton', 'C', '60 min'],
            ['CLP Acute Tox. 2/3', '—', '>10 ton', 'A', '—'],
        ]
    )
    
    doc.add_paragraph()
    p = doc.add_paragraph()
    run = p.add_run('¹ Voetnoot c: Onbrandbaar/niet brandonderhoudend in dedicated opslag → alleen basisveiligheidsniveau.')
    run.font.size = Pt(9)
    run.font.italic = True
    run.font.color.rgb = TEXT_SEC
    
    doc.add_page_break()
    
    # === 4. TABEL 8 SCHEIDINGSTABEL ===
    doc.add_heading('4. Tabel 8 — Scheidingstabel', level=1)
    
    doc.add_heading('4.1 Doel', level=2)
    doc.add_paragraph(
        'Tabel 8 / Bijlage E voorkomt dat onverenigbare stoffen samen worden opgeslagen, '
        'wat kan leiden tot ongecontroleerde reacties.'
    )
    
    doc.add_heading('4.2 Scheidingmethoden', level=2)
    methods = [
        'Afstand: Minimaal 2,4 meter tussen onverenigbare stoffen',
        'Constructieve scheiding: Wand of schot met brandwerendheid ≥30 minuten',
        'Aparte opslagvoorziening: Verschillende ruimtes of gebouwen',
    ]
    for i, m in enumerate(methods, 1):
        doc.add_paragraph(f'{i}. {m}')
    
    doc.add_heading('4.3 Belangrijke combinaties voor Phoenix Metals', level=2)
    add_table(doc,
        ['Combinatie', 'Risico', 'Vereiste scheiding'],
        [
            ['Zuur ↔ Base (H₂SO₄ ↔ NaOH)', 'Heftige reactie, hitteontwikkeling', '2,4 m of ≥30 min constructie'],
            ['Giftig ↔ Bijtend (V₂O₅ ↔ ADR 8)', 'Onverenigbaar', '2,4 m of constructieve scheiding'],
        ]
    )
    
    doc.add_page_break()
    
    # === 5. CMR-STOFFEN ===
    doc.add_heading('5. CMR-stoffen en Opslag', level=1)
    
    doc.add_heading('5.1 Definitie', level=2)
    doc.add_paragraph('CMR-stoffen zijn stoffen die:')
    cmr_items = [
        'Carcinogeen (kankerverwekkend) — Cat. 1A, 1B, 2',
        'Mutageen (erfelijk materiaal beschadigend) — Cat. 1A, 1B, 2',
        'Reprotoxisch (schadelijk voor voortplanting) — Cat. 1A, 1B, 2',
    ]
    for item in cmr_items:
        doc.add_paragraph(item, style='List Bullet')
    
    doc.add_heading('5.2 PGS 15:2025 behandeling', level=2)
    doc.add_paragraph(
        'CMR-stoffen met ADR-classificatie → via ADR-route in Tabel 6. '
        'CMR-stoffen zonder ADR-classificatie → basisveiligheidsniveau + zorgplicht (Arbowet). '
        'Ondergrens: 25 kg (poeder/vloeistof), metalen vaste vorm uitgezonderd.'
    )
    
    doc.add_heading('5.3 Aanvullende arbo-eisen', level=2)
    arbo_items = [
        'Werkplekinventarisatie (Arbobesluit art. 4.1c)',
        'Blootstellingsregister (Arbobesluit art. 4.1d)',
        'Arbeidsgezondheidskundig onderzoek (AGO)',
        'Vervangingsplicht: vervang waar mogelijk door minder gevaarlijk alternatief',
    ]
    for item in arbo_items:
        doc.add_paragraph(item, style='List Bullet')
    
    doc.add_page_break()
    
    # === 6. V₂O₅ SPECIFIEK ===
    doc.add_heading('6. Specifieke Aandacht voor V₂O₅', level=1)
    
    doc.add_heading('6.1 Waarom V₂O₅ kritiek is', level=2)
    doc.add_paragraph(
        'Vanadium(V) oxide combineert de volgende gevaren in één stof:'
    )
    
    add_table(doc,
        ['Gevaarklasse', 'H-zin', 'Betekenis'],
        [
            ['Carc. 1B', 'H350i', 'Kankerverwekkend bij inademing'],
            ['Acute Tox. 2', 'H330', 'Dodelijk bij inademing'],
            ['Repr. 2', 'H361fd', 'Vermoedelijk schadelijk voor voortplanting'],
            ['ADR 6.1 VG II', '—', 'Giftig transportgevaar (UN 2862)'],
        ]
    )
    
    doc.add_paragraph()
    doc.add_heading('6.2 Impact op Phoenix Metals', level=2)
    add_key_point(doc, 'Vanaf 1 kg → C-niveau verplicht (via CLP Acute Tox. 2)')
    add_key_point(doc, 'Vanaf 10.000 kg → A-niveau verplicht (automatische blussing)')
    add_key_point(doc, 'Vanaf 50.000 kg → Seveso lagedrempel (H2) bereikt')
    
    doc.add_heading('6.3 Beheersmaatregelen', level=2)
    measures = [
        'Stofvrije, gesloten opslag',
        'P3-ademhalingsbescherming bij handling',
        'Lokale afzuiging bij overslag',
        'Afzonderlijk opslagvak, gescheiden van ADR 8 stoffen',
        'Blootstellingsregister en AGO',
    ]
    for i, m in enumerate(measures, 1):
        doc.add_paragraph(f'{i}. {m}')
    
    doc.add_page_break()
    
    # === 7. CASUS PHOENIX METALS ===
    doc.add_heading('7. Casus Phoenix Metals — Werkvoorbeeld', level=1)
    
    doc.add_heading('7.1 Situatie', level=2)
    doc.add_paragraph(
        'Phoenix Metals is een startup die vanadium oxide (V₂O₅) produceert uit staalslakken '
        'via een hydrometallurgisch proces. De locatie bevindt zich op het Tata Steel terrein in IJmuiden.'
    )
    
    doc.add_heading('7.2 Stap 1: Stoffeninventarisatie', level=2)
    doc.add_paragraph('Gevaarlijke stoffen op de locatie:')
    
    add_table(doc,
        ['Stof', 'ADR', 'VG', 'Hoeveelheid', 'CLP extra'],
        [
            ['Sodium hydroxide 50%', '8', 'II', '100 L (~120 kg)', 'Skin Corr. 1A'],
            ['Zwavelzuur 75%', '8', 'II', '30 L (~50 kg)', 'Skin Corr. 1A'],
            ['Zwavelzuur 50%', '8', 'II', '70 L (~110 kg)', 'Skin Corr. 1A'],
            ['Zwavelzuur 25%', '8', 'II', '100 L (~120 kg)', 'Skin Corr. 1A'],
            ['Calcium oxide', '8', 'III', '10 kg', 'Skin Corr. 1B'],
            ['Vanadium(V) oxide', '6.1', 'II', 'TBV', 'Carc. 1B, Acute Tox. 2'],
        ]
    )
    
    doc.add_paragraph()
    doc.add_heading('7.3 Stap 2: Ondergrenscontrole', level=2)
    
    add_table(doc,
        ['Stof / aggregatie', 'Ondergrens Tabel 2', 'Boven ondergrens?'],
        [
            ['NaOH 50% (120 kg)', '250 kg', 'Nee (individueel)'],
            ['H₂SO₄ totaal (~280 kg)', '250 kg (individueel)', 'Nee (individueel)'],
            ['ADR 8 geaggregeerd (~410 kg)', '250 kg', 'Ja'],
            ['V₂O₅', '1 kg (CLP) / 50 kg (ADR)', 'Ja (verwacht)'],
        ]
    )
    
    doc.add_paragraph()
    doc.add_heading('7.4 Stap 3: Niveaubepaling', level=2)
    
    items = [
        'ADR 8 onbrandbaar → Basisveiligheidsniveau (voetnoot c)',
        'V₂O₅ via ADR 6.1 VG II → C-niveau (<10 ton)',
        'V₂O₅ via CLP Acute Tox. 2 → C-niveau (<10 ton)',
    ]
    for item in items:
        doc.add_paragraph(item, style='List Bullet')
    
    p = doc.add_paragraph()
    run = p.add_run('Strengste: C-NIVEAU')
    run.bold = True
    run.font.color.rgb = PRIMARY
    run.font.size = Pt(14)
    
    doc.add_heading('7.5 Stap 4: Maatregelen C-niveau', level=2)
    add_table(doc,
        ['Eis', 'Vereiste', 'PGS 15 referentie'],
        [
            ['Wbdbo', '60 minuten', 'Tabel 6'],
            ['Branddetectiesysteem', 'NEN 2535', 'M103'],
            ['Brandwerende constructie', 'Wanden ≥60 min Wbdbo', 'Doel D7'],
            ['Productopvang', 'Grootste individuele vak', 'Tabel 8'],
            ['Scheiding', 'Zuur/base, giftig/bijtend', 'Tabel 8'],
            ['CMR-maatregelen', 'V₂O₅ specifiek', 'Arbobesluit'],
        ]
    )
    
    doc.add_paragraph()
    doc.add_heading('7.6 Stap 5: Compliance beoordeling', level=2)
    doc.add_paragraph(
        'Zie Compliance Toets v1.0 — 18% voldoet, 31% gedeeltelijk, 51% niet te toetsen. '
        'Dit is conform verwachting voor een startup in ontwikkelingsfase.'
    )
    
    doc.add_page_break()
    
    # === 8. BRONNENLIJST ===
    doc.add_heading('8. Bronnenlijst', level=1)
    
    sources = [
        '[1] PGS 15:2025 — Opslag van verpakte gevaarlijke stoffen, Publicatie 565, versie 1.0, januari 2025',
        '[2] ADR 2025 — Accord européen relatif au transport international des marchandises Dangereuses par Route',
        '[3] CLP Verordening (EG) 1272/2008 — Classification, Labelling and Packaging',
        '[4] Arbowet / Arbobesluit — Artikel 4.1c, 4.1d (gevaarlijke stoffen)',
        '[5] Omgevingswet — Artikel 4.1012 Bal (opslag gevaarlijke stoffen)',
        '[6] SDS Vanadium(V) oxide (CAS 1314-62-1) — leverancier informatie',
        '[7] NEN 2535 — Branddetectiesystemen, rookmelders',
        '[8] ECHA — V₂O₅ SVHC-kandidaatlijst (2023)',
    ]
    for s in sources:
        doc.add_paragraph(s)
    
    # Begrippenlijst
    doc.add_page_break()
    doc.add_heading('Begrippenlijst', level=1)
    
    add_table(doc,
        ['Begrip', 'Uitleg'],
        [
            ['ADR', 'Accord européen relatif au transport international des marchandises Dangereuses par Route'],
            ['CLP', 'Classification, Labelling and Packaging (EG 1272/2008)'],
            ['CMR', 'Carcinogeen, Mutageen, Reprotoxisch'],
            ['SDS', 'Safety Data Sheet (veiligheidsinformatieblad)'],
            ['VG', 'Verpakkingsgroep (I, II, III) — mate van gevaar'],
            ['Wbdbo', 'Weerstand tegen branddoorgang en brandoverslag'],
            ['PBM', 'Persoonlijk Beschermingsmiddel'],
            ['RI&E', 'Risico-Inventarisatie en -Evaluatie'],
            ['NEN 2535', 'Nederlandse norm voor branddetectie'],
        ]
    )
    
    # SAVE
    path = os.path.join(BASE, 'PGS15_Kennisdossier_v1.0.docx')
    doc.save(path)
    size = os.path.getsize(path)
    print(f'✓ Kennisdossier saved: {path} ({size:,} bytes)')
    return path


# ════ DOC 6: NIVEAUBEPALING RAPPORT ════

def generate_niveaubepaling():
    doc = Document()
    setup_styles(doc)
    add_logo_header(doc)
    add_footer(doc, 'PGS15-PM-NB', 'v1.0', '27 april 2026')
    
    doc.core_properties.title = 'PGS15-PM Niveaubepaling Rapport v1.0'
    doc.core_properties.author = 'HQ_04 Technical Writer via Kas'
    doc.core_properties.keywords = 'PGS 15; niveaubepaling; Phoenix Metals; V₂O₅; ADR; CLP'
    doc.core_properties.category = 'HSEQ Intelligence'
    
    # === COVER ===
    for _ in range(4):
        doc.add_paragraph()
    
    t = doc.add_paragraph()
    t.alignment = WD_ALIGN_PARAGRAPH.CENTER
    r = t.add_run('NIVEAUBEPALING RAPPORT')
    r.bold = True
    r.font.size = Pt(28)
    r.font.color.rgb = PRIMARY
    
    t2 = doc.add_paragraph()
    t2.alignment = WD_ALIGN_PARAGRAPH.CENTER
    r2 = t2.add_run('PGS 15:2025 — Tabel 6 Toetsing')
    r2.font.size = Pt(18)
    r2.font.color.rgb = TEXT_SEC
    
    doc.add_paragraph()
    
    t3 = doc.add_paragraph()
    t3.alignment = WD_ALIGN_PARAGRAPH.CENTER
    r3 = t3.add_run('Phoenix Metals B.V. — Tata Steel IJmuiden')
    r3.font.size = Pt(14)
    r3.font.color.rgb = ACCENT
    
    for _ in range(4):
        doc.add_paragraph()
    
    meta_lines = [
        'Project: PGS15-PM-NB',
        'Versie: 1.0',
        'Datum: 27 april 2026',
        'Gebaseerd op: Niveaubepaling v2.0',
        'Status: CONCEPT — vereist bevestiging hoeveelheden door Phoenix Metals',
    ]
    for line in meta_lines:
        p = doc.add_paragraph()
        p.alignment = WD_ALIGN_PARAGRAPH.CENTER
        run = p.add_run(line)
        run.font.size = Pt(11)
        run.font.color.rgb = TEXT_SEC
    
    doc.add_page_break()
    
    # === 1. INLEIDING ===
    doc.add_heading('1. Inleiding', level=1)
    
    doc.add_heading('1.1 Doel', level=2)
    doc.add_paragraph(
        'Dit rapport documenteert de niveaubepaling conform PGS 15:2025 Tabel 6 voor de opslag '
        'van gevaarlijke stoffen bij Phoenix Metals, locatie Tata Steel terrein, IJmuiden.'
    )
    
    doc.add_heading('1.2 Methodiek', level=2)
    items = [
        'Per stof: ADR-route en CLP-route onafhankelijk bepalen',
        'Per ADR-klasse: aggregatie van hoeveelheden',
        'Strengste niveau over alle routes is het bepaalde opslagniveau',
    ]
    for item in items:
        doc.add_paragraph(item, style='List Bullet')
    
    doc.add_page_break()
    
    # === 2. STOFFENLIJST ===
    doc.add_heading('2. Stoffenlijst met Classificatie', level=1)
    
    doc.add_heading('2.1 ADR-geclassificeerde stoffen', level=2)
    add_table(doc,
        ['#', 'Stof', 'CAS', 'ADR', 'VG', 'Vorm', 'Hoeveelheid', 'Gewicht', 'CLP extra'],
        [
            ['1', 'Sodium hydroxide 50%', '1310-73-2', '8', 'II', 'Vloeistof', '100 L', '~120 kg', 'Skin Corr. 1A'],
            ['2', 'Sulfuric acid 75%', '7664-93-9', '8', 'II', 'Vloeistof', '30 L', '~50 kg', 'Skin Corr. 1A'],
            ['3', 'Sulfuric acid 50%', '7664-93-9', '8', 'II', 'Vloeistof', '70 L', '~110 kg', 'Skin Corr. 1A'],
            ['4', 'Sulfuric acid 25%', '7664-93-9', '8', 'II', 'Vloeistof', '100 L', '~120 kg', 'Skin Corr. 1A'],
            ['5', 'Calcium oxide', '1305-78-8', '8', 'III¹', 'Vast', '10 kg', '10 kg', 'Skin Corr. 1B'],
            ['6', 'Vanadium(V) oxide', '1314-62-1', '6.1', 'II', 'Vast', 'TBV', 'TBV', 'Carc. 1B, Acute Tox. 2, Repr. 2'],
        ]
    )
    
    doc.add_paragraph()
    p = doc.add_paragraph()
    run = p.add_run('¹ CaO: in registratie als N/A, aangenomen ADR 8 VG III (UN 1910).')
    run.font.size = Pt(9)
    run.font.italic = True
    run.font.color.rgb = TEXT_SEC
    
    doc.add_heading('2.2 Niet-ADR-geclassificeerde stoffen', level=2)
    add_table(doc,
        ['#', 'Stof', 'CAS', 'CLP', 'PGS 15 relevantie'],
        [
            ['7', 'Aluminiumsulfaat octadecahydraat', '7784-31-8', 'H319', 'Geen'],
            ['8', 'Vanadium(IV) sulfaat oplossing', 'N/A', 'TBV', 'TBV — mogelijk ADR 6.1'],
            ['9', 'Vanadium elektrolyt (V³·⁵⁺)', 'N/A', 'TBV', 'TBV — mogelijk ADR 6.1'],
        ]
    )
    
    doc.add_page_break()
    
    # === 3. ADR-ROUTE BEREKENINGEN ===
    doc.add_heading('3. ADR-route Berekeningen', level=1)
    
    doc.add_heading('3.1 ADR-klasse 8 — Bijtende stoffen', level=2)
    
    doc.add_paragraph('Stoffen:')
    add_table(doc,
        ['Stof', 'VG', 'Gewicht (kg)', 'Onbrandbaar'],
        [
            ['NaOH 50%', 'II', '120', 'Ja'],
            ['H₂SO₄ 75%', 'II', '50', 'Ja'],
            ['H₂SO₄ 50%', 'II', '110', 'Ja'],
            ['H₂SO₄ 25%', 'II', '120', 'Ja'],
            ['CaO', 'III', '10', 'Ja'],
            ['Totaal', '', '410', ''],
        ]
    )
    
    doc.add_paragraph()
    doc.add_paragraph(
        'Toetsing Tabel 6: ADR 8 VG II+III, onbrandbaar, geen Acute Tox. → Basisveiligheidsniveau (voetnoot c).'
    )
    doc.add_paragraph(
        'Ondergrens Tabel 2: ADR 8 VG II/III → 250 kg. Geaggregeerd 410 kg > 250 kg → boven ondergrens, '
        'maar voetnoot c blijft van toepassing (onbrandbaar).'
    )
    
    p = doc.add_paragraph()
    run = p.add_run('Conclusie ADR 8: Basisveiligheidsniveau')
    run.bold = True
    run.font.color.rgb = SUCCESS
    
    doc.add_heading('3.2 ADR-klasse 6.1 — Giftige stoffen', level=2)
    
    add_table(doc,
        ['Stof', 'VG', 'Gewicht (kg)'],
        [
            ['V₂O₅', 'II', 'TBV (verwacht: >1 kg)'],
        ]
    )
    
    doc.add_paragraph()
    doc.add_paragraph('Toetsing Tabel 6:')
    items = [
        'ADR 6.1 VG II, <10 ton → C-niveau (Wbdbo 60 min)',
        'ADR 6.1 VG II, <20 ton → C-niveau (Wbdbo 90 min)',
        'ADR 6.1 VG II, >20 ton → A-niveau',
    ]
    for item in items:
        doc.add_paragraph(item, style='List Bullet')
    
    doc.add_paragraph('Ondergrens Tabel 2: ADR 6.1 VG II → 50 kg')
    
    p = doc.add_paragraph()
    run = p.add_run('Conclusie ADR 6.1: C-niveau (bij <10 ton V₂O₅)')
    run.bold = True
    run.font.color.rgb = WARNING
    
    doc.add_page_break()
    
    # === 4. CLP-ROUTE BEREKENINGEN ===
    doc.add_heading('4. CLP-route Berekeningen', level=1)
    
    doc.add_heading('4.1 Acute Toxiciteit Cat. 2 — V₂O₅ (H330)', level=2)
    
    add_table(doc,
        ['Parameter', 'Waarde'],
        [
            ['Stof', 'Vanadium(V) oxide'],
            ['H-zin', 'H330 — Dodelijk bij inademing'],
            ['Categorie', 'Acute Tox. Cat. 2'],
            ['Ondergrens Tabel 2', '1 kg'],
            ['Verwachte opslag', '>1 kg'],
            ['Tabel 6 CLP Acute Tox. 2, <10 ton', 'C-niveau (Wbdbo 60 min)'],
            ['Tabel 6 CLP Acute Tox. 2, >10 ton', 'A-niveau'],
        ]
    )
    
    doc.add_paragraph()
    p = doc.add_paragraph()
    run = p.add_run('Conclusie CLP Acute Tox. 2: C-niveau (bij <10 ton V₂O₅). Drempel A-niveau bij 10 ton.')
    run.bold = True
    run.font.color.rgb = WARNING
    
    doc.add_heading('4.2 CMR Cat. 1B — V₂O₅ (H350i)', level=2)
    
    add_table(doc,
        ['Parameter', 'Waarde'],
        [
            ['Stof', 'Vanadium(V) oxide'],
            ['H-zin', 'H350i — Kan kanker veroorzaken bij inademing'],
            ['Categorie', 'Carc. 1B'],
            ['Ondergrens Tabel 2', '25 kg (poeder)'],
            ['Heeft ADR-classificatie?', 'Ja (6.1 VG II) → ADR-route prevaleert'],
        ]
    )
    
    doc.add_paragraph()
    doc.add_paragraph(
        'Conclusie CMR: V₂O₅ wordt via de ADR-route beoordeeld (Tabel 6). '
        'Aanvullende arbo-maatregelen (AI-06) verplicht.'
    )
    
    doc.add_heading('4.3 Acute Toxiciteit Cat. 4 — V₂O₅ (H302+H312)', level=2)
    doc.add_paragraph(
        'Niet van toepassing — Cat. 4 valt buiten PGS 15 Tabel 2 ondergrenzen.'
    )
    
    doc.add_page_break()
    
    # === 5. AGGREGATIE ===
    doc.add_heading('5. Aggregatie per Klasse', level=1)
    
    add_table(doc,
        ['Route', 'Stofklasse', 'Resultaat'],
        [
            ['ADR 8', 'Bijtend, onbrandbaar', 'Basisveiligheidsniveau'],
            ['ADR 6.1', 'Giftig (V₂O₅)', 'C-niveau'],
            ['CLP Acute Tox. 2', 'V₂O₅ (H330)', 'C-niveau'],
            ['CLP CMR 1B', 'V₂O₅ (H350i)', 'Via ADR 6.1 route'],
            ['Catch-all (~415 kg)', '<1.000 kg', 'Niet van toepassing'],
        ]
    )
    
    doc.add_paragraph()
    doc.add_heading('5.1 Catch-all controle', level=2)
    doc.add_paragraph(
        'Totaal bekende gevaarlijke stoffen: ~415 kg (+ V₂O₅ TBV). '
        'Catch-all drempel: 1.000 kg. '
        'Bij <585 kg V₂O₅: catch-all niet van toepassing (maar C-niveau al vereist via CLP/AOA 6.1).'
    )
    
    doc.add_page_break()
    
    # === 6. CONCLUSIE ===
    doc.add_heading('6. Conclusie: C-niveau', level=1)
    
    doc.add_heading('6.1 Bepaald Opslagniveau', level=2)
    
    p = doc.add_paragraph()
    p.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = p.add_run('C-NIVEAU (Wbdbo 60 minuten)')
    run.bold = True
    run.font.size = Pt(20)
    run.font.color.rgb = PRIMARY
    
    doc.add_heading('6.2 Argumentatie', level=2)
    doc.add_paragraph(
        'V₂O₅ is de dominante factor. Onafhankelijke routes leiden beiden tot C-niveau:'
    )
    items = [
        'ADR-route: ADR 6.1 VG II → C-niveau bij <10 ton',
        'CLP-route: Acute Tox. Cat. 2 (H330) → C-niveau bij <10 ton',
    ]
    for i, item in enumerate(items, 1):
        doc.add_paragraph(f'{i}. {item}')
    
    doc.add_paragraph(
        'Beide routes zijn onafhankelijk en beiden resulteren in C-niveau. '
        'Het strengste niveau (C) is het bepaalde opslagniveau.'
    )
    
    doc.add_heading('6.3 Verplichte constructieve eisen C-niveau', level=2)
    add_table(doc,
        ['Eis', 'Vereiste', 'PGS 15 referentie'],
        [
            ['Weerstand branddoorgang/overslag', '60 minuten', 'Tabel 6'],
            ['Branddetectiesysteem', 'NEN 2535', 'M103'],
            ['Brandwerende constructie', 'Wanden ≥60 min Wbdbo', 'Doel D7'],
            ['Productopvang', 'Grootste individuele vak', 'Tabel 8'],
            ['Basisveiligheidsniveau', 'Volledig van toepassing', '§7'],
        ]
    )
    
    doc.add_page_break()
    
    # === 7. SCHAALNIVEAUS ===
    doc.add_heading('7. Schaalniveaus', level=1)
    
    doc.add_heading('7.1 Wanneer naar A-niveau?', level=2)
    
    add_table(doc,
        ['V₂O₅ opslag', 'ADR 6.1 VG II', 'CLP Acute Tox. 2', 'Resultaat'],
        [
            ['0 kg', 'N.v.t.', 'N.v.t.', 'Basis¹'],
            ['1 – 1.000 kg', 'C (60 min)', 'C (60 min)', 'C'],
            ['1.000 – 10.000 kg', 'C (60 min)', 'C (60 min)', 'C'],
            ['10.000 – 20.000 kg', 'C (90 min)', 'A (aut. blussing)', 'A'],
            ['>20.000 kg', 'A', 'A', 'A'],
        ]
    )
    
    doc.add_paragraph()
    p = doc.add_paragraph()
    run = p.add_run('¹ Alleen als V₂O₅ NIET op locatie wordt opgeslagen.')
    run.font.size = Pt(9)
    run.font.italic = True
    run.font.color.rgb = TEXT_SEC
    
    doc.add_heading('7.2 Monitoring', level=2)
    doc.add_paragraph(
        'Phoenix Metals dient de V₂O₅ opslaghoeveelheid structureel te monitoren. '
        'Bij overschrijding van 10.000 kg moet worden opgeschaald naar A-niveau (automatische blussing).'
    )
    
    add_warning(doc, 'Monitoring van V₂O₅ opslaghoeveelheid is KRITIEK. Bij >10 ton onmiddellijke opschaling naar A-niveau vereist.')
    
    doc.add_page_break()
    
    # === 8. AANNAMES ===
    doc.add_heading('8. Aannames en Onzekerheden', level=1)
    
    add_table(doc,
        ['#', 'Aanname', 'Impact', 'Actie'],
        [
            ['1', 'V₂O₅ wordt opgeslagen op locatie', 'HOOG — bepaalt C vs Basis', 'Bevestig opslag ja/nee'],
            ['2', 'V₂O₅ hoeveelheid <10 ton', 'HOOG — bepaalt C vs A', 'Bevestig maximale hoeveelheid'],
            ['3', 'Geen brandstoffen op locatie', 'HOOG — ADR 3 verandert niveau', 'Inventariseer brandstoffen'],
            ['4', 'CaO = ADR 8 VG III', 'LAAG — 10 kg', 'Verifieer SDS'],
            ['5', 'V(IV) sulfaat = geen significant ADR', 'MIDDEN — bij ADR 6.1 versterkt C', 'Verkrijg SDS'],
        ]
    )
    
    # SAVE
    path = os.path.join(BASE, 'PGS15_Niveaubepaling_Rapport_v1.0.docx')
    doc.save(path)
    size = os.path.getsize(path)
    print(f'✓ Niveaubepaling Rapport saved: {path} ({size:,} bytes)')
    return path


# ════ MAIN ════
if __name__ == '__main__':
    print('=== PGS 15:2025 DOCX Generator ===')
    print()
    
    p1 = generate_kennisdossier()
    print()
    p2 = generate_niveaubepaling()
    print()
    
    s1 = os.path.getsize(p1)
    s2 = os.path.getsize(p2)
    print(f'--- Verification ---')
    print(f'Kennisdossier: {s1:,} bytes {"✓ >10KB" if s1 > 10240 else "✗ <10KB"}')
    print(f'Niveaubepaling: {s2:,} bytes {"✓ >10KB" if s2 > 10240 else "✗ <10KB"}')
    print('Done.')
