#!/usr/bin/env python3
"""
PGS-15 Compliance Studiegids — Phoenix Metals IJmuiden
Document 2/12 — Studiegids voor non-experts (.docx)
Versie: 1.0 | Datum: 2026-04-26
"""

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

OUTPUT = "/root/projects/jg/2026-pgs15-phoenix-metals/deliverables/docx/PGS15_Studiegids_NonExperts_v1.0.docx"
LOGO = "/root/projects/jg/2026-pgs15-phoenix-metals/assets/branding/jvg-consultancy-logo.jpg"
PRIMARY = RGBColor(0x00, 0x33, 0x66)
TEXT_DARK = RGBColor(0x1F, 0x29, 0x37)
TEXT_SEC = RGBColor(0x37, 0x41, 0x51)
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
SUCCESS_C = RGBColor(0x00, 0xA8, 0x59)
WARNING_C = RGBColor(0xF5, 0x9E, 0x0B)
CRITICAL_C = RGBColor(0xFF, 0x6D, 0x00)

doc = Document()

# === STYLES ===
style = doc.styles['Normal']
style.font.name = 'Calibri'
style.font.size = Pt(11)
style.font.color.rgb = TEXT_DARK

for level in range(1, 4):
    h = doc.styles[f'Heading {level}']
    h.font.name = 'Calibri'
    h.font.color.rgb = PRIMARY
    h.font.bold = True
    h.font.size = Pt([0, 22, 16, 13][level])

def add_header_footer(doc):
    """Add running headers and footers to all sections."""
    from docx.oxml.ns import qn
    for section in doc.sections:
        # Header
        header = section.header
        header.is_linked_to_previous = False
        hp = header.paragraphs[0]
        hp.alignment = WD_ALIGN_PARAGRAPH.RIGHT
        run = hp.add_run("JvG Consultancy | PGS-15 Compliance Studiegids")
        run.font.size = Pt(9)
        run.font.color.rgb = TEXT_SEC
        run.font.name = 'Calibri'
        
        # Footer
        footer = section.footer
        footer.is_linked_to_previous = False
        fp = footer.paragraphs[0]
        fp.alignment = WD_ALIGN_PARAGRAPH.CENTER
        run = fp.add_run("© 2026 JvG Consultancy | HSEQ Divisie | 26 april 2026")
        run.font.size = Pt(8)
        run.font.color.rgb = TEXT_SEC
        run.font.name = 'Calibri'

def add_table(headers, rows):
    table = doc.add_table(rows=1+len(rows), cols=len(headers))
    table.style = 'Table Grid'
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    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 = WHITE
        run.font.size = Pt(10)
        run.font.name = 'Calibri'
        p.alignment = WD_ALIGN_PARAGRAPH.CENTER
        shading = parse_xml(f'<w:shd {nsdecls("w")} w:fill="003366"/>')
        cell._tc.get_or_add_tcPr().append(shading)
    for r_idx, row in enumerate(rows):
        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.name = 'Calibri'
            if r_idx % 2 == 1:
                shading = parse_xml(f'<w:shd {nsdecls("w")} w:fill="F8F9FA"/>')
                cell._tc.get_or_add_tcPr().append(shading)
    doc.add_paragraph()
    return table

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

def add_bullet(text):
    doc.add_paragraph(text, style='List Bullet')

def add_callout(title, text, color_hex="003366"):
    """Add a styled callout box."""
    p = doc.add_paragraph()
    run = p.add_run(f"▎ {title}")
    run.bold = True
    run.font.size = Pt(12)
    run.font.color.rgb = PRIMARY
    run.font.name = 'Calibri'
    # Add left border via paragraph formatting
    p2 = doc.add_paragraph()
    run2 = p2.add_run(text)
    run2.font.size = Pt(11)
    run2.font.name = 'Calibri'
    run2.font.color.rgb = TEXT_DARK
    p2.paragraph_format.left_indent = Cm(1)
    doc.add_paragraph()

# =============================================
# VOORBLAD
# =============================================
for _ in range(3):
    doc.add_paragraph()

if os.path.exists(LOGO):
    doc.add_picture(LOGO, width=Inches(2.0))
    doc.paragraphs[-1].alignment = WD_ALIGN_PARAGRAPH.CENTER

doc.add_paragraph()
add_para("STUDIEGIDS", bold=True, size=28, align=WD_ALIGN_PARAGRAPH.CENTER, color=PRIMARY)
add_para("PGS-15 Compliance voor Non-Experts", bold=True, size=16, align=WD_ALIGN_PARAGRAPH.CENTER, color=TEXT_SEC)
doc.add_paragraph()
add_para("Phoenix Metals IJmuiden", size=14, align=WD_ALIGN_PARAGRAPH.CENTER, color=TEXT_SEC)
doc.add_paragraph()
add_para("Wat u MOET weten over veilige opslag van gevaarlijke stoffen", size=12, align=WD_ALIGN_PARAGRAPH.CENTER, color=TEXT_SEC)

doc.add_paragraph()
meta = [("Versie", "1.0"), ("Datum", "26 april 2026"), ("Doelgroep", "Alle medewerkers Phoenix Metals"), ("Adviseur", "JvG Consultancy — HSEQ Divisie")]
for label, value in meta:
    p = doc.add_paragraph()
    p.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run_l = p.add_run(f"{label}: ")
    run_l.bold = True
    run_l.font.name = 'Calibri'
    run_v = p.add_run(value)
    run_v.font.name = 'Calibri'

doc.add_page_break()

# =============================================
# INHOUD
# =============================================
doc.add_heading('Inhoudsopgave', level=1)
toc_items = [
    "1. Waarom deze studiegids?",
    "2. Wat is PGS 15?",
    "3. Welke stoffen heeft Phoenix Metals?",
    "4. Wat zijn ADR-klassen?",
    "5. Veiligheidsniveaus uitgelegd",
    "6. De belangrijkste regel: Stoffenscheiding",
    "7. Wat moet er op de werkvloer?",
    "8. Brandveiligheid",
    "9. Wat als we groeien?",
    "10. Uw persoonlijke checklist",
    "11. Woordenlijst (begrippen)",
]
for item in toc_items:
    add_bullet(item)

doc.add_page_break()

# =============================================
# HOOFDSTUK 1
# =============================================
doc.add_heading('1. Waarom deze studiegids?', level=1)

add_para("U werkt met chemische stoffen. Zuren, basen, chemicaliën. Deze stoffen zijn nodig voor het productieproces van Phoenix Metals. Maar ze brengen ook risico's mee.")

add_para("De overheid stelt eisen aan hoe u deze stoffen opslaat. Deze eisen staan in de PGS 15-richtlijn. Deze studiegids legt uit wat die eisen inhouden — in gewone taal, zonder juridisch jargon.")

add_callout("Doel van deze gids", "Na het lezen begrijpt u:\n• Welke regels gelden voor de opslag bij Phoenix Metals\n• Waarom zuren en basen NIET bij elkaar mogen staan\n• Welke veiligheidsmaatregelen op de werkvloer nodig zijn\n• Wat u persoonlijk kunt doen om veilig te werken")

# =============================================
# HOOFDSTUK 2
# =============================================
doc.add_heading('2. Wat is PGS 15?', level=1)

add_para("PGS 15 is een richtlijn voor het veilig opslaan van gevaarlijke stoffen in verpakkingen (jerrycans, flessen, canisters, etc.).")

add_para("Belangrijke feiten:", bold=True)
add_bullet("PGS 15 is geen wet, maar een richtlijn die door de overheid wordt erkend")
add_bullet("De letters PGS staan voor Publicatiereeks Gevaarlijke Stoffen")
add_bullet("De huidige versie dateert uit januari 2025 (PGS 15:2025)")
add_bullet("De richtlijn geldt voor ALLE bedrijven die gevaarlijke stoffen opslaan")
add_bullet("Naleving is in de praktijk verplicht via de Omgevingswet en Arbowet")

add_callout("Kortom", "PGS 15 vertelt u HOE u gevaarlijke stoffen veilig moet opslaan. Het is uw handleiding voor een veilig magazijn.")

# =============================================
# HOOFDSTUK 3
# =============================================
doc.add_heading('3. Welke stoffen heeft Phoenix Metals?', level=1)

add_para("Phoenix Metals heeft momenteel 6 stoffen op voorraad. Hier is het overzicht:")

headers = ["Stof", "Gevaar", "Hoeveelheid", "Verpakking"]
rows = [
    ["Natriumhydroxide (NaOH) 50%", "Bijtend (base/loog)", "100 liter", "4 jerrycans"],
    ["Zwavelzuur (H₂SO₄) 75%", "Bijtend (zuur)", "30 liter", "3 jerrycans"],
    ["Zwavelzuur (H₂SO₄) 50%", "Bijtend (zuur)", "70 liter", "7 jerrycans"],
    ["Zwavelzuur (H₂SO₄) 25%", "Bijtend (zuur)", "100 liter", "4 jerrycans"],
    ["Aluminiumsulfaat", "Niet-gevaarlijk", "5 kg", "2 canisters"],
    ["Calciumoxide (CaO)", "Niet-ADR", "10 kg", "2 canisters"],
]
add_table(headers, rows)

add_callout("⚠️ Let op", "Totaal gaat het om 300 liter bijtende stoffen. Dat is niet veel, maar de regels gelden altijd — ook bij kleine hoeveelheden.")

# =============================================
# HOOFDSTUK 4
# =============================================
doc.add_heading('4. Wat zijn ADR-klassen?', level=1)

add_para("ADR is het Europese systeem om gevaarlijke stoffen in te delen. Elk type gevaar krijgt een eigen klasse met een nummer:")

headers = ["ADR-klasse", "Type gevaar", "Voorbeeld", "Herkenning"]
rows = [
    ["2", "Gassen", "Propaan, zuurstof", "Gasfles-etiket"],
    ["3", "Brandbare vloeistoffen", "Benzine, aceton", "Vlam-symbool"],
    ["5.1", "Oxiderende stoffen", "Waterstofperoxide", "Vlam boven cirkel"],
    ["6.1", "Giftige stoffen", "Cyanide", "Doodshoofd-symbool"],
    ["8", "Bijtende stoffen", "Zwavelzuur, loog", "Reageerbuis-symbool"],
    ["9", "Milieugevaarlijk", "Verschillende", "Dode boom/vis-symbool"],
]
add_table(headers, rows)

add_callout("Phoenix Metals", "Al onze stoffen vallen onder ADR-klasse 8 (bijtend) of zijn niet-ADR. Dat betekent: bijtend materiaal, maar niet brandbaar, niet giftig en niet explosief.")

# =============================================
# HOOFDSTUK 5
# =============================================
doc.add_heading('5. Veiligheidsniveaus uitgelegd', level=1)

add_para("PGS 15 werkt met een systeem van oplopende veiligheidseisen. Hoe meer u opslaat, hoe strenger de regels:")

headers = ["Niveau", "Wanneer?", "Wat moet u doen?"]
rows = [
    ["Basis", "Altijd — ook bij 1 jerrycan", "Lekbakken, scheiding, registratie, instructie"],
    ["Niveau B", "Vanaf ~10.000 kg", "Extra: brandwerende muren (60 min)"],
    ["Niveau A", "Vanaf ~20.000 kg", "Extra: automatisch blussysteem + detectie"],
]
add_table(headers, rows)

p = doc.add_paragraph()
run = p.add_run("ONZE SITUATIE: ")
run.bold = True
run.font.color.rgb = SUCCESS_C
p.add_run("Met 300 liter (±390 kg) zitten wij ruim in het basisniveau. Geen brandwerende muren of blussystemen nodig. Maar de basisregels gelden WEL.")

# =============================================
# HOOFDSTUK 6
# =============================================
doc.add_heading('6. De belangrijkste regel: Stoffenscheiding', level=1)

add_para("Dit is het belangrijkste hoofdstuk van deze gids.")

p = doc.add_paragraph()
run = p.add_run("⛔ NEVER MIX ZUUR EN BASE")
run.bold = True
run.font.size = Pt(16)
run.font.color.rgb = RGBColor(0xEF, 0x44, 0x44)
p.alignment = WD_ALIGN_PARAGRAPH.CENTER

doc.add_paragraph()
add_para("Zuren (zoals zwavelzuur) en basen (zoals natriumhydroxide/loog) mogen NOOIT in dezelfde lekbak of hetzelfde vak worden opgeslagen. Waarom?")

add_bullet("Als ze mengen ontstaat een heftige, exotherme reactie (hitte, spatten, giftige dampen)")
add_bullet("De reactie kan zo heftig zijn dat verpakkingen scheuren en de stoffen ongecontroleerd vrijkomen")
add_bullet("PGS 15 Tabel 9 classificeert dit als 'A-scheiding': de strengste vorm van scheiding")

add_callout("Wat betekent dit op de werkvloer?", 
    "• Natriumhydroxide (NaOH) → EIGEN lekbak, apart vak\n"
    "• Zwavelzuur (H₂SO₄) → EIGEN lekbak, apart vak\n"
    "• Minimaal 2 meter afstand tussen beide\n"
    "• Calciumoxide apart van zwavelzuur (reageert ook!)")

add_para("De simpele regel:", bold=True)
add_bullet("ZUREN bij zuren")
add_bullet("BASEN bij basen")
add_bullet("Nooit mengen, altijd scheiden")

# =============================================
# HOOFDSTUK 7
# =============================================
doc.add_heading('7. Wat moet er op de werkvloer?', level=1)

add_para("De volgende maatregelen zijn ALTIJD verplicht, ongeacht de hoeveelheid:")

headers = ["#","Maatregel", "Wat houdt het in?", "Klaar bij PM?"]
rows = [
    ["1","Lekbakken", "Elke jerrycan staat in een lekbak die minstens 110% van de inhoud kan opvangen","❌ Nog niet"],
    ["2","Stoffenscheiding", "Zuren en basen in aparte bakken met 2 m afstand","❌ Nog niet"],
    ["3","Registratie", "Elke stof is geregistreerd met naam, CAS-nr, hoeveelheid, locatie","✅ Ja"],
    ["4","VIB/SDS beschikbaar", "Veiligheidsinformatieblad van elke stof binnen handbereik","⚠️ Checken"],
    ["5","Verpakking heel", "Geen beschadigde, verroeste of lekkende verpakkingen","✅ Ja"],
    ["6","Botsbeveiliging", "Rack is beschermd tegen aanrijding door heftruck","⚠️ Checken"],
    ["7","Instructie personeel", "Iedereen weet wat te doen bij lekkage","⚠️ Checken"],
    ["8","Noodplan", "Procedure voor lekkage, brand, ongeval","⚠️ Checken"],
]
add_table(headers, rows)

# =============================================
# HOOFDSTUK 8
# =============================================
doc.add_heading('8. Brandveiligheid', level=1)

add_para("Bijtende stoffen zijn niet brandbaar. Dat is goed nieuws. Maar PGS 15 stelt toch brandveiligheidseisen omdat:")

add_bullet("Een brand in de buurt kan verpakkingen doen bezwijken, waardoor bijtende stoffen vrijkomen")
add_bullet("De combinatie van hitte en bijtende stoffen is extra gevaarlijk")
add_bullet("Bluswater in contact met bepaalde stoffen kan reacties veroorzaken")

add_para("Wat is vereist op basisniveau:", bold=True)
add_bullet("Brandblusser in de nabijheid van de opslag")
add_bullet("Geen brandbare materialen in de directe omgeving van de stoffen")
add_bullet("Toegankelijkheid voor de brandweer gewaarborgd")

# =============================================
# HOOFDSTUK 9
# =============================================
doc.add_heading('9. Wat als we groeien?', level=1)

add_para("Als Phoenix Metals in de toekomst meer gaat opslaan, veranderen de eisen:")

headers = ["Fase", "Volume", "Extra eisen", "Investering"]
rows = [
    ["Nu (basis)", "~390 kg", "Lekbakken + scheiding", "€ 500 - 1.500"],
    ["Fase 1", "< 10.000 kg", "+ Brandwerende constructie (60 min)", "€ 5.000 - 15.000"],
    ["Fase 2", "10-20.000 kg", "+ Blussysteem + detectie", "€ 25.000 - 75.000"],
    ["Fase 3", "> 20.000 kg", "+ Automatische blussing + alarm", "€ 100.000 - 300.000"],
]
add_table(headers, rows)

add_callout("Praktisch", "De investering voor de huidige situatie is beperkt: lekbakken en markeringen volstaan. Dit is te regelen binnen één werkdag.")

# =============================================
# HOOFDSTUK 10
# =============================================
doc.add_heading('10. Uw persoonlijke checklist', level=1)

add_para("Wat u vandaag kunt controleren:")

checklist = [
    "Staan zuren en basen in aparte lekbakken?",
    "Is er minimaal 2 meter afstand tussen de zuur-lekbak en de base-lekbak?",
    "Staat calciumoxide apart van zwavelzuur?",
    "Zijn alle verpakkingen heel en gesloten?",
    "Is er een blusser in de buurt?",
    "Weet u waar de VIB/SDS van elke stof ligt?",
    "Weet u wat u moet doen bij een lekkage?",
    "Is het rack beschermd tegen aanrijding?",
]
for i, item in enumerate(checklist, 1):
    add_para(f"☐ {i}. {item}")

# =============================================
# HOOFDSTUK 11
# =============================================
doc.add_heading('11. Woordenlijst (begrippen)', level=1)

headers = ["Term", "Betekenis"]
rows = [
    ["ADR", "Accord européen — Europees verdrag voor vervoer gevaarlijke stoffen"],
    ["Bbl", "Bouwbesluit leefomgeving — regels voor bouwen en brandveiligheid"],
    ["Brandcompartiment", "Een ruimte die brand een bepaalde tijd kan tegenhouden"],
    ["CAS-nummer", "Uniek nummer voor elke chemische stof"],
    ["CMR", "Carcinogeen, Mutageen, Reprotoxisch — kankerverwekkend, erfelijkheid-beschadigend, vruchtbaarheid-aantastend"],
    ["CLP", "Classification, Labelling and Packaging — EU-regel voor etikettering"],
    ["Lekbak", "Bak die vloeistoffen opvangt bij lekkage (min 110% grootste verpakking)"],
    ["PGS", "Publicatiereeks Gevaarlijke Stoffen — Nederlandse richtlijnen"],
    ["SDS / VIB", "Safety Data Sheet / Veiligheidsinformatieblad — document met alle veiligheidsinfo van een stof"],
    ["SVHC", "Substance of Very High Concern — zeer zorgwekkende stof (REACH)"],
    ["Wbdbo", "Weerstand tegen branddoorgang en brandvoortplanting van bouwconstructies"],
]
add_table(headers, rows)

# Add footer
add_header_footer(doc)

# === SAVE ===
os.makedirs(os.path.dirname(OUTPUT), exist_ok=True)
doc.save(OUTPUT)
print(f"✅ STUDIEGIDS OPGESLAGEN: {OUTPUT}")
print(f"   Grootte: {os.path.getsize(OUTPUT):,} bytes")
