#!/usr/bin/env python3
"""Generate D3 v3.0 and D4 v3.0 DOCX deliverables for Phoenix Metals REACH project."""

from docx import Document
from docx.shared import Inches, Pt, Cm, RGBColor
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
from docx.oxml import OxmlElement
import os
from datetime import datetime

LOGO_PATH = "/root/projects/jg/assets/branding/jvg-logo-white-medium.png"
OUTPUT_DIR = "/root/projects/jg/2026-reach-phoenix-metals/deliverables/docx"
TODAY = "2026-04-16"

# ─── Helper functions ───

def add_header_footer(doc, logo_path=LOGO_PATH):
    """Add JvG Consultancy header with logo and footer."""
    section = doc.sections[0]
    # Header
    header = section.header
    header.is_linked_to_previous = False
    if os.path.exists(logo_path):
        hp = header.paragraphs[0]
        hp.alignment = WD_ALIGN_PARAGRAPH.RIGHT
        run = hp.add_run()
        run.add_picture(logo_path, width=Inches(1.2))
    else:
        hp = header.paragraphs[0]
        hp.alignment = WD_ALIGN_PARAGRAPH.RIGHT
        run = hp.add_run("JvG Consultancy")
        run.font.size = Pt(9)
        run.font.color.rgb = RGBColor(0x44, 0x72, 0xC4)

    # Footer
    footer = section.footer
    footer.is_linked_to_previous = False
    fp = footer.paragraphs[0]
    fp.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = fp.add_run("JvG Consultancy | REACH Compliance Phoenix Metals | ")
    run.font.size = Pt(8)
    run.font.color.rgb = RGBColor(0x80, 0x80, 0x80)
    # 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)


def set_cell_shading(cell, color):
    shading_elm = OxmlElement('w:shd')
    shading_elm.set(qn('w:fill'), color)
    shading_elm.set(qn('w:val'), 'clear')
    cell._tc.get_or_add_tcPr().append(shading_elm)


def add_table(doc, headers, rows, col_widths=None):
    table = doc.add_table(rows=1 + len(rows), cols=len(headers))
    table.style = 'Table Grid'
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    # Header row
    for i, h in enumerate(headers):
        cell = table.rows[0].cells[i]
        cell.text = h
        for p in cell.paragraphs:
            for r in p.runs:
                r.bold = True
                r.font.size = Pt(9)
                r.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
        set_cell_shading(cell, '2E5090')
    # Data rows
    for ri, row in enumerate(rows):
        for ci, val in enumerate(row):
            cell = table.rows[ri + 1].cells[ci]
            cell.text = str(val)
            for p in cell.paragraphs:
                for r in p.runs:
                    r.font.size = Pt(9)
            if ri % 2 == 1:
                set_cell_shading(cell, 'E8EEF5')
    return table


def styled_heading(doc, text, level=1):
    h = doc.add_heading(text, level=level)
    for run in h.runs:
        run.font.color.rgb = RGBColor(0x1B, 0x3A, 0x5C)
    return h


def body(doc, text):
    p = doc.add_paragraph(text)
    for run in p.runs:
        run.font.size = Pt(10)
    return p


def bold_body(doc, text):
    p = doc.add_paragraph()
    run = p.add_run(text)
    run.bold = True
    run.font.size = Pt(10)
    return p


def ref_note(doc, text):
    """Small grey reference note."""
    p = doc.add_paragraph()
    run = p.add_run(text)
    run.font.size = Pt(8)
    run.font.color.rgb = RGBColor(0x80, 0x80, 0x80)
    run.italic = True
    return p


# ═══════════════════════════════════════════════════════════════
# D3: VIB/MSDS Strategie
# ═══════════════════════════════════════════════════════════════

def generate_d3():
    doc = Document()
    add_header_footer(doc)

    # Cover
    doc.add_paragraph()
    doc.add_paragraph()
    p = doc.add_paragraph()
    p.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = p.add_run("VIB/SDS STRATEGIE")
    run.bold = True
    run.font.size = Pt(28)
    run.font.color.rgb = RGBColor(0x1B, 0x3A, 0x5C)

    p2 = doc.add_paragraph()
    p2.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run2 = p2.add_run("Phoenix Metals B.V. — Vanadiumhalffabrikaat\nREACH Compliance D3 v3.0")
    run2.font.size = Pt(16)
    run2.font.color.rgb = RGBColor(0x44, 0x72, 0xC4)

    p3 = doc.add_paragraph()
    p3.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run3 = p3.add_run(f"\nJvG Consultancy\n{TODAY}\nVertrouwelijk")
    run3.font.size = Pt(11)
    run3.font.color.rgb = RGBColor(0x60, 0x60, 0x60)

    doc.add_page_break()

    # TOC placeholder
    styled_heading(doc, "Inhoudsopgave", 1)
    toc_items = [
        "1. Executive Summary",
        "2. VIB/SDS Stappenplan",
        "3. Wanneer is een SDS verplicht?",
        "4. 16-Secties Tabel — Vanadiumhalffabrikaat",
        "5. Exposure Scenarios & Safe Use Conditions",
        "6. e-SDS vs Papieren SDS",
        "7. UVCB-problematiek",
        "8. Downstream User Communicatie",
        "9. Datadeling — SIEF & Consortium",
        "10. Actualisatieprocedure",
        "11. Referenties",
    ]
    for item in toc_items:
        p = doc.add_paragraph(item)
        p.paragraph_format.space_after = Pt(2)

    doc.add_page_break()

    # 1. Executive Summary
    styled_heading(doc, "1. Executive Summary", 1)
    body(doc, (
        "Dit document (D3 v3.0) beschrijft de strategie voor het opstellen, beheren, distribueren en actualiseren "
        "van Veiligheidsinformatiebladen (VIB/SDS) voor Phoenix Metals B.V. (PM), specifiek gericht op het "
        "vanadiumhalffabrikaat dat wordt geproduceerd uit olievergisting-as (SARU ash) via een hydrometallurgisch proces."
    ))
    body(doc, (
        "Phoenix Metals hanteert een selectieve hydrometallurgische extractie van vanadium uit SARU ash — een reststroom "
        "uit de aardolieraffinage die bestaat uit natriummetavanaad, trinatriumorthovanaad en nikkeloxide [Bron 42]. "
        "Het demo-proces omvat alkalische uitlogging met NaOH, ionenuitwisseling en elektroreductie tot een vanadium(IV) "
        "sulfaatoplossing [Bron 23]."
    ))
    body(doc, (
        "Kernuitdagingen zijn: (1) de UVCB-classificatie van het halffabrikaat door variabele slaksamenstelling [Bron 03, 11], "
        "(2) de aanwezigheid van vanadiumpentoxide (V₂O₅) als gevaarlijk verbrandingsproduct [Bron 27], "
        "(3) de naleving van de 16-secties SDS-structuur volgens REACH Bijlage II [Bron 05], en "
        "(4) de integratie van blootstellingsscenario's in een extended SDS (e-SDS) [Bron 05, 06]."
    ))
    ref_note(doc, "Bronnen: 05 (SDS-richtsnoer), 03 (stofidentificatie), 06 (chemische veiligheid MKB), 23 (proces), 27 (vanadium SDS), 42 (ash factsheet)")

    doc.add_page_break()

    # 2. VIB/SDS Stappenplan
    styled_heading(doc, "2. VIB/SDS Stappenplan — Opstellen, Beheer, Distributie, Actualisatie", 1)
    body(doc, (
        "Op basis van het ECHA-Richtsnoer voor het samenstellen van veiligheidsinformatiebladen (v4.0, december 2020) "
        "wordt het volgende stappenplan voorgesteld voor Phoenix Metals [Bron 05]."
    ))

    styled_heading(doc, "2.1 Opstellen van het SDS", 2)
    steps = [
        ("Stap 1", "Stofidentificatie — Bepaal de exacte stofidentiteit via een SIP (Stofidentiteitsprofiel). Classificeer als UVCB indien van toepassing [Bron 03, 07]."),
        ("Stap 2", "CLP-classificatie — Bepaal de gevarenklassen, H/P-zinnen en signalwoord op basis van tox/ecotox data [Bron 08, 15]."),
        ("Stap 3", "Chemische veiligheidsbeoordeling (CSA) — Voer een CSA uit indien ≥10 ton/jaar. Stel DNEL/DMEL vast [Bron 06, 10]."),
        ("Stap 4", "SDS-opstelling — Vul alle 16 secties conform REACH Bijlage II [Bron 05]."),
        ("Stap 5", "Exposure Scenarios — Voeg blootstellingsscenario's toe indien een CSA vereist is [Bron 05, 06]."),
        ("Stap 6", "Kwaliteitscontrole — Interne review door HSE Manager en externe validatie [Bron 32]."),
    ]
    add_table(doc, ["Stap", "Beschrijving"], steps)

    styled_heading(doc, "2.2 Beheer & Distributie", 2)
    body(doc, (
        "Het SDS-beheerssysteem omvat: (a) een centraal register in de Chemicals Master [Bron 26], "
        "(b) elektronische distributie via het documentbeheersysteem PE-210-04 [Bron 49], "
        "(c) hardcopy beschikbaarheid op de werkvloer conform de PBM-matrix [Bron 34]."
    ))
    body(doc, (
        "Distributieverplichtingen: Het SDS moet kosteloos worden verstrekt aan elke downstreamgebruiker bij "
        "eerste levering en bij herziening [REACH Art. 31; Bron 05]. Voor PM betekent dit dat elke afnemer van "
        "het vanadiumhalffabrikaat een actueel SDS ontvangt in de landstaal van bestemming."
    ))

    styled_heading(doc, "2.3 Actualisatie", 2)
    body(doc, (
        "Actualisatie is verplicht bij: (1) nieuwe classificatiegegevens, (2) wijziging in samenstelling, "
        "(3) nieuwe blootstellingsroutes, (4) herziening van MAC-waarden, (5) wijzigingen in de kandidaatlijst SVHC [Bron 05]. "
        "PM hanteert een jaarlijkse actualisatiecyclus, gekoppeld aan de Management of Change-procedure [Bron 48]."
    ))
    ref_note(doc, "Bronnen: 05 (SDS-richtsnoer §3.22-3.23), 26 (Chemicals Master), 49 (Document Control), 48 (MoC)")

    doc.add_page_break()

    # 3. Wanneer is een SDS verplicht?
    styled_heading(doc, "3. Wanneer is een SDS verplicht?", 1)
    body(doc, (
        "Volgens REACH Artikel 31 is een SDS verplicht voor stoffen en mengsels die voldoen aan de classificatiecriteria "
        "als gevaarlijk overeenkomstig CLP (Verordening (EG) nr. 1272/2008) [Bron 05, 15]."
    ))

    sds_req = [
        ("Gevaarlijke stoffen", "Ja", "Altijd verplicht — CLP-classificatie als gevaarlijk"),
        ("PBT/vPvB-stoffen", "Ja", "Verplicht ongeacht tonnage [Bron 04]"),
        ("SVHC (kandidaatlijst)", "Ja", "Verplicht + mededelingsplicht [Bron 04]"),
        ("Niet-gevaarlijke mengsels", "Nee*", "Alleen op verzoek downstreamgebruiker (*behalve indien SVHC ≥0.1%)"),
        ("Onderzoekschemicaliën", "Uitzondering", "Niet verplicht mits onder gecontroleerde omstandigheden [Bron 02]"),
        ("Tonnage <1 ton/jaar", "Nee*", "Geen registratieplicht, maar SDS verplicht indien gevaarlijk"),
    ]
    add_table(doc, ["Stof/Mengselcategorie", "SDS Verplicht?", "Toelichting"], sds_req)

    body(doc, "")
    body(doc, (
        "Voor Phoenix Metals is het vanadiumhalffabrikaat een UVCB-stof met gevaarlijke eigenschappen "
        "(acute toxiciteit, specifieke orgaantoxiciteit bij herhaalde blootstelling). Een SDS is derhalve "
        "verplicht bij elke levering aan downstreamgebruikers [Bron 03, 05]."
    ))
    ref_note(doc, "Bronnen: 02 (Registratiegids), 04 (SVHC), 05 (SDS-richtsnoer), 15 (CLP-basisgids)")

    doc.add_page_break()

    # 4. 16-Secties Tabel
    styled_heading(doc, "4. 16-Secties SDS — Vanadiumhalffabrikaat Phoenix Metals", 1)
    body(doc, (
        "Onderstaande tabel bevat de voorgestelde invulling van alle 16 SDS-secties voor het PM-vanadiumhalffabrikaat, "
        "gebaseerd op de beschikbare brondata. Dit is een strategisch kader — definitieve invulling vereist "
        "laboratoriumanalyse en CSA-output [Bron 05]."
    ))

    sds_sections = [
        ("Sectie 1:\nIdentificatie", 
         "Productnaam: Vanadium(IV) sulfaatoplossing (PM halffabrikaat)\n"
         "Leverancier: Phoenix Metals B.V., Plant One Rotterdam\n"
         "CAS: Meerdere componenten (UVCB)\n"
         "EG: N.v.t. (UVCB)\n"
         "REACH registratienummer: In aanvraag\n"
         "Noodtelefoon: Conform BNP [Bron 33]",
         "05, 23, 26, 33, 42"),
        
        ("Sectie 2:\nGevaarsidentificatie",
         "CLP-classificatie:\n"
         "• Acute toxiciteit oraal Cat. 4 (H302)\n"
         "• Huidcorrosie Cat. 1B (H314) — zuurtraject\n"
         "• Ernstige oogschade Cat. 1 (H318)\n"
         "• Specifieke orgaantoxiciteit herhaald Cat. 1 (H372) — longen\n"
         "• Gevaarlijk voor het aquatisch milieu, chronisch Cat. 3 (H412)\n"
         "Signalwoord: GEVAAR\n"
         "Pictogrammen: GHS05, GHS07, GHS08",
         "05, 08, 27, 42"),
        
        ("Sectie 3:\nSamenstelling",
         "Hoofdbestanddelen:\n"
         "• Vanadium(IV) sulfaat hydrate — variabel % (UVCB)\n"
         "• Natriummetavanaad — residu uit as [Bron 42]\n"
         "• Nikkelverbindingen — onzuiverheid uit SARU ash\n"
         "• Natriumsulfaat — procesrest\n"
         "Onzuiverheden: V₂O₅, Fe, Cr, Mn (sporen uit staalslak)\n"
         "UVCB-classificatie: Variabele samenstelling afhankelijk van as-herkomst [Bron 03]",
         "03, 11, 23, 42"),

        ("Sectie 4:\nEerste hulp",
         "Inhalatie: Verplaatsen naar frisse lucht. Bij aanhoudende klachten arts raadplegen.\n"
         "Huid: Onmiddellijk met veel water spoelen (≥15 min). Verontreinigde kleding uittrekken.\n"
         "Ogen: Onmiddellijk spoelen met water (≥15 min). Oogarts raadplegen.\n"
         "Inslikken: Mond spoelen met water. NIET braken opwekken.\n"
         "Vanadium-specifieke symptomen: Groene tong, hoesten, longirritatie, buikpijn.\n"
         "Speciale instructies: Symptomatische behandeling; monitor nierfunctie [Bron 27]",
         "05, 27"),

        ("Sectie 5:\nBrandbestrijding",
         "Geschikte blusmiddelen: Waterstraal, schuim, droog chemisch poeder, CO₂.\n"
         "Ongeschikte blusmiddelen: Geen specifieke beperking.\n"
         "Gevaarlijke verbrandingsproducten:\n"
         "• Vanadiumpentoxide (V₂O₅) — zeer toxisch bij inademing\n"
         "• Zwaveloxiden (SO₂, SO₃)\n"
         "• Natriumoxide\n"
         "PBM voor brandweer: Zelfstandig ademhalingsapparaat + volledige bescherming [Bron 27]",
         "27, 33"),

        ("Sectie 6:\nMaatregelen bij vrijgifte",
         "Persoonlijke voorzorgen: PBM dragen (zuurbestendige handschoenen, veiligheidsbril, halfgelaatsmasker FFP3).\n"
         "Milieumaatregelen: Uitstroming naar riolering/bodem voorkomen.\n"
         "Opschoonmethoden: Absorberen met inert materiaal (vermiculiet). Vaste stof verzamelen in afgesloten containers.\n"
         "Vloeistof: Neutraliseren met NaHCO₃ of Ca(OH)₂ voor afvoer.\n"
         "Radiologisch: Let op beperkingen Besluit basisveiligheidsnormen [Bron 42]",
         "05, 33, 34, 42"),

        ("Sectie 7:\nHantering en opslag",
         "Hantering: Werken in afzuigkap/was cabinet. Stofvorming minimaliseren.\n"
         "Opslagcondities: Koel, droog, goed geventileerd. Uit de buurt van zuren en oxidatiemiddelen.\n"
         "Compatibele materialen: HDPE, PP, glas. Incompatibel: metaal (corrosie).\n"
         "Opslagklasse: Conform PGS-15 richtlijnen\n"
         "Maximale hoeveelheid: Demo ≤60 kg as → beperkt volume halffabrikaat [Bron 42]",
         "05, 23, 26"),

        ("Sectie 8:\nBlootstellingsbeheersing",
         "MAC-waarden:\n"
         "• Vanadiumpentoxide (V₂O₅, stof): 0.25 mg/m³ (TWA) [SER]\n"
         "• Vanadium, respirable fractie: 0.04 mg/m³ (TWA)\n"
         "• Zwavelzuur mist: 0.1 mg/m³ (TWA)\n"
         "Technische maatregelen: Lokale afzuiging, gesloten systeem.\n"
         "PBM:\n"
         "• Handen: Nitrilhandschoenen (EN 374)\n"
         "• Ogen: Veiligheidsbril + gezichtsscherm\n"
         "• Luchtwegen: FFP3 masker bij stofvorming\n"
         "• Lichaam: Zuurbestendig schort [Bron 34, 35]",
         "05, 06, 10, 34, 35"),

        ("Sectie 9:\nFysische eigenschappen",
         "Uiterlijk: Gele tot groene vloeistoplossing (V⁴⁺) / kristallijne vaste stof\n"
         "Geur: Geen kenmerkende geur\n"
         "pH: Sterk zuur (< 1) in geconcentreerde vorm\n"
         "Kookpunt: >100°C (waterig)\n"
         "Smeltpunt: N.v.t. (oplossing)\n"
         "Dichtheid: ~1.2-1.5 g/cm³ (afhankelijk van concentratie)\n"
         "Wateroplosbaarheid: Volledig oplosbaar\n"
         "Verdampingsdruk: Verwaarloosbaar bij kamertemperatuur\n"
         "Opmerking: Exacte waarden vereisen laboratoriumbepaling",
         "05, 23, 42"),

        ("Sectie 10:\nStabiliteit en reactiviteit",
         "Stabiliteit: Stabiel onder normale omstandigheden.\n"
         "Te vermijden omstandigheden: Hoge temperaturen (>200°C) → V₂O₅-vorming.\n"
         "Te vermijden materialen: Sterke oxidatoren, sterke basen (exotherme reactie).\n"
         "Gevaarlijke ontledingsproducten: V₂O₅, SO₂, SO₃ bij verhitting.\n"
         "Polymeergevaar: Niet van toepassing.",
         "05, 27, 42"),

        ("Sectie 11:\nToxicologische data",
         "Acute toxiciteit:\n"
         "• VOS (oral rat) LD₅₀: ~580 mg/kg (VOSO₄) — Cat. 4\n"
         "• V₂O₅ (oral rat) LD₅₀: ~350 mg/kg — Cat. 3\n"
         "Huidirritatie: Corrosief (zuurcomponent)\n"
         "Oogirritatie: Ernstige schade\n"
         "Sensibilisatie: Geen data — voorzorgshalve screenen\n"
         "CMR-classificatie:\n"
         "• Mutageniteit: V₂O₅ Cat. 2 (H341) vermoed — nader onderzoek vereist\n"
         "• Kankerverwekkend: V₂O₅ Cat. 2 (H351) vermoed\n"
         "• Reproductietoxiciteit: Niet geclassificeerd\n"
         "STOT RE: Luchtwegen (H372) — longfibrose bij chronische blootstelling\n"
         "Opmerking: (Q)SAR en read-across toepasbaar voor data-gaps [Bron 11]",
         "05, 10, 11, 27, 42"),

        ("Sectie 12:\nEcologische data",
         "Toxiciteit:\n"
         "• Aquatisch: V⁴⁺ matig toxisch voor vissen (LC₅₀ 96u: ~10-100 mg/L)\n"
         "• V₂O₅ toxischer dan VOSO₄\n"
         "Persistentie: Vanadiumionen zijn niet persistent; neigen tot precipitatie.\n"
         "Bioaccumulatie: BC