#!/usr/bin/env python3
"""Generate D5 — Management & Stakeholder Presentatie PPTX for Phoenix Metals."""

from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.enum.shapes import MSO_SHAPE
import os, datetime

# ── Brand colours ──
DARK_BLUE  = RGBColor(0x00, 0x33, 0x66)
ACCENT_BLUE = RGBColor(0x3B, 0x82, 0xF6)
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
LIGHT_GRAY = RGBColor(0xF0, 0xF4, 0xF8)
MED_GRAY = RGBColor(0x94, 0xA3, 0xB8)
DARK_TEXT = RGBColor(0x1E, 0x29, 0x3B)

SLIDE_W = Inches(13.333)
SLIDE_H = Inches(7.5)

prs = Presentation()
prs.slide_width = SLIDE_W
prs.slide_height = SLIDE_H

# Use blank layout
blank_layout = prs.slide_layouts[6]

def add_bg(slide, color=DARK_BLUE):
    """Fill slide background with solid color."""
    bg = slide.background
    fill = bg.fill
    fill.solid()
    fill.fore_color.rgb = color

def add_shape(slide, left, top, width, height, color):
    shape = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, left, top, width, height)
    shape.fill.solid()
    shape.fill.fore_color.rgb = color
    shape.line.fill.background()
    return shape

def add_textbox(slide, left, top, width, height, text, font_size=18, bold=False, color=DARK_TEXT, alignment=PP_ALIGN.LEFT, font_name='Calibri'):
    txBox = slide.shapes.add_textbox(left, top, width, height)
    tf = txBox.text_frame
    tf.word_wrap = True
    p = tf.paragraphs[0]
    p.text = text
    p.font.size = Pt(font_size)
    p.font.bold = bold
    p.font.color.rgb = color
    p.font.name = font_name
    p.alignment = alignment
    return txBox

def add_bullets(slide, left, top, width, height, items, font_size=14, color=DARK_TEXT, spacing=Pt(6)):
    txBox = slide.shapes.add_textbox(left, top, width, height)
    tf = txBox.text_frame
    tf.word_wrap = True
    for i, item in enumerate(items):
        if i == 0:
            p = tf.paragraphs[0]
        else:
            p = tf.add_paragraph()
        p.text = item
        p.font.size = Pt(font_size)
        p.font.color.rgb = color
        p.font.name = 'Calibri'
        p.space_after = spacing
        p.level = 0
    return txBox

def add_accent_bar(slide, top=Inches(1.35)):
    add_shape(slide, Inches(0.8), top, Inches(1.2), Pt(4), ACCENT_BLUE)

def slide_header(slide, title, subtitle=None, dark_bg=False):
    add_shape(slide, Inches(0), Inches(0), SLIDE_W, Inches(1.3), DARK_BLUE)
    add_textbox(slide, Inches(0.8), Inches(0.25), Inches(11), Inches(0.7), title, font_size=28, bold=True, color=WHITE)
    if subtitle:
        add_textbox(slide, Inches(0.8), Inches(0.75), Inches(11), Inches(0.4), subtitle, font_size=14, color=ACCENT_BLUE)
    add_accent_bar(slide)

def add_visual_box(slide, left, top, width, height, label):
    shape = add_shape(slide, left, top, width, height, LIGHT_GRAY)
    tf = shape.text_frame
    tf.word_wrap = True
    tf.paragraphs[0].alignment = PP_ALIGN.CENTER
    p = tf.paragraphs[0]
    p.text = f"📊 {label}"
    p.font.size = Pt(11)
    p.font.color.rgb = MED_GRAY
    p.font.italic = True
    p.font.name = 'Calibri'
    shape.text_frame.paragraphs[0].space_before = Pt(20)

# ══════════════════════════════════════════════════════════
# SLIDE 1 — Title
# ══════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank_layout)
add_bg(s, DARK_BLUE)
# Accent line
add_shape(s, Inches(0.8), Inches(2.7), Inches(2), Pt(4), ACCENT_BLUE)
add_textbox(s, Inches(0.8), Inches(2.0), Inches(11), Inches(0.8),
    "REACH Compliance & Chemische Veiligheid", font_size=36, bold=True, color=WHITE)
add_textbox(s, Inches(0.8), Inches(3.0), Inches(11), Inches(0.6),
    "Phoenix Metals B.V.", font_size=24, color=ACCENT_BLUE)
add_textbox(s, Inches(0.8), Inches(3.7), Inches(11), Inches(0.5),
    "Roadmap voor regulatorische compliance in de circulaire economie", font_size=16, color=MED_GRAY)
add_textbox(s, Inches(0.8), Inches(5.5), Inches(4), Inches(0.4),
    "JvG Consultancy  |  16 april 2026", font_size=12, color=MED_GRAY)
add_textbox(s, Inches(0.8), Inches(5.9), Inches(4), Inches(0.4),
    "[Logo Phoenix Metals / JvG Consultancy]", font_size=10, color=MED_GRAY)

# ══════════════════════════════════════════════════════════
# SLIDE 2 — Agenda
# ══════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank_layout)
slide_header(s, "Agenda")
items = [
    "1.  Phoenix Metals — Wie zijn wij?",
    "2.  Het REACH-vraagstuk",
    "3.  Veiligheid & HSEQ Framework",
    "4.  Roadmap & Timeline",
    "5.  Vragen & Volgende Stappen",
]
add_bullets(s, Inches(1.2), Inches(2.0), Inches(10), Inches(4.5), items, font_size=22, spacing=Pt(18))

# ══════════════════════════════════════════════════════════
# SLIDE 3 — Wie zijn wij
# ══════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank_layout)
slide_header(s, "Phoenix Metals — Wie zijn wij?")
bullets = [
    "Circulaire economie startup — vanadium teruggewonnen uit staalslakken",
    "Product: vanadiumhalffabrikaat (geen elektrolyt) voor VRFB-industrie",
    "Keten: Staalslak → Terugwinning → Halffabrikaat → Elektrolytproducent → VRFB",
    "Locatie: Nederland (volledig EU-regelgevingsgebied)",
    "Kritiek overgangspunt: afvalwetgeving ↔ chemischestoffenwetgeving",
]
add_bullets(s, Inches(0.8), Inches(1.8), Inches(7), Inches(4.5), bullets, font_size=16, spacing=Pt(12))
# Process flow visual
add_visual_box(s, Inches(8.5), Inches(1.8), Inches(4.2), Inches(4.5),
    "Procesflow:\nStaalslak → Phoenix Metals →\nElektrolytproducent → VRFB")

# ══════════════════════════════════════════════════════════
# SLIDE 4 — REACH-vraagstuk
# ══════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank_layout)
slide_header(s, "Het REACH-vraagstuk")
bullets = [
    "REACH (EG 1907/2006): registratie, evaluatie, autorisatie chemische stoffen",
    "Van toepassing zodra vanadiumhalffabrikaat geen 'afval' meer is (EoW-moment)",
    "End-of-Waste (art. 6 KRA 2008/98/EG): 4 cumulatieve criteria — bestemd voor toepassing, markt/vraag, technische specificatie, geen nadelige effecten",
    "Art. 2(7)(d) REACH: vrijstelling indien stof identiek aan reeds geregistreerde stof",
    "Bewijslast ligt bij Phoenix Metals: SIP, analysecertificaten, afnemerscontracten",
]
add_bullets(s, Inches(0.8), Inches(1.8), Inches(7.2), Inches(5), bullets, font_size=15, spacing=Pt(10))
add_visual_box(s, Inches(8.5), Inches(1.8), Inches(4.2), Inches(4.5),
    "Timeline:\nAfval → EoW-moment →\nREACH-plicht → Registratie/Vrijstelling")

# ══════════════════════════════════════════════════════════
# SLIDE 5 — Registratiepad Opties
# ══════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank_layout)
slide_header(s, "Registratiepad — Opties vergeleken")

# Table
rows, cols = 4, 3
tbl_shape = s.shapes.add_table(rows, cols, Inches(0.8), Inches(1.8), Inches(11.5), Inches(3.5))
tbl = tbl_shape.table
tbl.columns[0].width = Inches(3.5)
tbl.columns[1].width = Inches(4)
tbl.columns[2].width = Inches(4)

headers = ["Criterium", "Art. 2(7)(d) Vrijstelling", "Volledige REACH-registratie"]
for i, h in enumerate(headers):
    cell = tbl.cell(0, i)
    cell.text = h
    for p in cell.text_frame.paragraphs:
        p.font.size = Pt(14); p.font.bold = True; p.font.color.rgb = WHITE; p.font.name = 'Calibri'
    cell.fill.solid(); cell.fill.fore_color.rgb = DARK_BLUE

data = [
    ["Kostenindicatie", "€40.000 – €100.000", "€90.000 – €300.000"],
    ["Data-eisen", "SIP + bewijs identiek aan geregistreerde stof", "Volledig IUCLID-dossier (Bijlage VII–X)"],
    ["Risico geen actie", "Boetes, marktuitsluiting, bestuursrechtelijke handhaving", "Idem + additionele registratieachterstand"],
]
for r, row_data in enumerate(data):
    for c, val in enumerate(row_data):
        cell = tbl.cell(r+1, c)
        cell.text = val
        for p in cell.text_frame.paragraphs:
            p.font.size = Pt(13); p.font.color.rgb = DARK_TEXT; p.font.name = 'Calibri'
        if r % 2 == 0:
            cell.fill.solid(); cell.fill.fore_color.rgb = LIGHT_GRAY
        else:
            cell.fill.solid(); cell.fill.fore_color.rgb = WHITE

add_textbox(s, Inches(0.8), Inches(5.6), Inches(11), Inches(0.5),
    "Advies: Start met art. 2(7)(d)-route. Valideer stofidentiteit (SIP) via ICP-OES, XRD, XRF. Daarna pas routebepaling.",
    font_size=13, bold=True, color=ACCENT_BLUE)

# ══════════════════════════════════════════════════════════
# SLIDE 6 — Veiligheid Risicobeheersing
# ══════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank_layout)
slide_header(s, "Veiligheid — Risicobeheersing")
bullets = [
    "6 processtappen: ontvangst → breken/malen → extractie → zuivering → drogen → opslag/transport",
    "V₂O₅ classificatie: Carc. 1B, Acute Tox. 2 (inhalatie), Mut. 2, Repr. 2, STOT RE 1, Aquatic Chronic 2",
    "MAC-waarde V₂O₅-stof: 0,05 mg/m³ (TGG-8h) — vereist gesloten systemen + LEV",
    "RMM-hiërarchie: eliminatie → technische maatregelen (LEV, gesloten systeem) → organisatorische maatregelen → PBM",
    "PBM: P3-masker, chemisch-bestendige handschoenen, veiligheidsbril, beschermende kleding — per processtap gedefinieerd",
    "CMR-regime (art. 4.1c Arbobesluit): vervangingsbeleid, blootstellingsregistratie, PAGO verplicht",
]
add_bullets(s, Inches(0.8), Inches(1.8), Inches(7.2), Inches(5), bullets, font_size=14, spacing=Pt(8))
add_visual_box(s, Inches(8.5), Inches(1.8), Inches(4.2), Inches(4.5),
    "RMM-Piramide:\nEliminatie ↑ Technisch ↑\nOrganisatorisch ↑ PBM")

# ══════════════════════════════════════════════════════════
# SLIDE 7 — CLP & Supply Chain
# ══════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank_layout)
slide_header(s, "CLP & Supply Chain Communicatie")
bullets = [
    "CLP-classificatie (EG 1272/2008): etikettering en verpakking volgens EU-harmonisatie",
    "H-zinnen: H330 (dodelijk bij inademing), H350 (kan kanker veroorzaken), H373 (schade organen), H411 (giftig voor waterorganismen)",
    "SDS-verplichting (REACH art. 31): verplicht bij levering gevaarlijke stof — ongeacht tonnage",
    "SDS bevat 16 secties: identificatie, gevaren, samenstelling, EHM, brandbestrijding, milieu, enz.",
    "Verplichtingen richting downstream users: SDS, blootstellingsscenario's, risicobeheersmaatregelen",
    "Distributie: automatisch bij eerste levering, actualisatie binnen 12 maanden bij wijzigingen",
    "Talen: Nederlands + officiële taal lidstaat afnemer",
]
add_bullets(s, Inches(0.8), Inches(1.8), Inches(7.2), Inches(5), bullets, font_size=14, spacing=Pt(8))
add_visual_box(s, Inches(8.5), Inches(1.8), Inches(4.2), Inches(4.5),
    "CLP-etiket voorbeeld:\n⚠️ Gevaar\nH330 H350 H373\nP260 P284 P304+P340")

# ══════════════════════════════════════════════════════════
# SLIDE 8 — Vergunningen & Compliance
# ══════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank_layout)
slide_header(s, "Vergunningen & Compliance Framework")
bullets = [
    "Omgevingsvergunning (Wm/Omw): verplicht voor milieubelastende activiteit — terugwinning van metalen",
    "BRZO/Seveso-III: V₂O₅ ≥5 ton opslag = lagere drempel (bijlage I, categorie E2) — veiligheidsrapportageplicht",
    "ADR-transport: vanadiumverbindingen klasse 6.1 / 9 — verpakte goederen met UN-nummer",
    "PGS 15: opslag van gevaarlijke stoffen —brandwerende opslag, ventilatie, in inventarisatie",
    "Arbowetgeving: RI&E, CMR-beleid, PAGO, grenswaarden (MAC 0,05 mg/m³)",
    "Master SOP als interne wetgeving: procedures, verantwoordelijkheden, kwaliteitsborging",
    "Jaarlijkse review SOP + periodieke EoW-herbevestiging",
]
add_bullets(s, Inches(0.8), Inches(1.8), Inches(7.2), Inches(5), bullets, font_size=14, spacing=Pt(8))
add_visual_box(s, Inches(8.5), Inches(1.8), Inches(4.2), Inches(4.5),
    "Compliance-ecosysteem:\nREACH • CLP • KRA\nOmw • BRZO • ADR\nPGS 15 • Arbo • SOP")

# ══════════════════════════════════════════════════════════
# SLIDE 9 — Roadmap & Timeline
# ══════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank_layout)
slide_header(s, "Roadmap & Timeline")

phases = [
    ("Fase 1  |  Maand 1–2", "Stofidentificatie & SIP", "ICP-OES, XRD, XRF analyses • SIP opstellen • Vergelijking ECHA-database"),
    ("Fase 2  |  Maand 2–4", "EoW-besluit & Registratiebeoordeling", "EoW-dossier met 4 criteria • Besluit: art. 2(7)(d) vs. volledige registratie"),
    ("Fase 3  |  Maand 3–5", "SDS, CLP-classificatie & Vergunningen", "SDS opstellen (16 secties) • CLP-etikettering • Omgevingsvergunning aanvragen"),
    ("Fase 4  |  Maand 4–6", "Implementatie, Training & Audit", "SOP implementatie • Medewerkertraining • Interne audit"),
    ("Fase 5  |  Doorlopend", "Monitoring & Actualisatie", "Jaarlijkse SOP-review • SDS-actualisatie • EoW-herbevestiging"),
]

y = Inches(1.7)
for i, (phase, title, desc) in enumerate(phases):
    bar_color = DARK_BLUE if i % 2 == 0 else ACCENT_BLUE
    add_shape(s, Inches(0.8), y, Inches(0.3), Inches(0.85), bar_color)
    add_textbox(s, Inches(1.3), y, Inches(3.5), Inches(0.4), phase, font_size=13, bold=True, color=DARK_BLUE)
    add_textbox(s, Inches(1.3), Emu(y + Inches(0.35)), Inches(3.5), Inches(0.3), title, font_size=12, color=ACCENT_BLUE)
    add_textbox(s, Inches(5.2), y, Inches(7.5), Inches(0.85), desc, font_size=12, color=DARK_TEXT)
    y += Inches(1.05)

# ══════════════════════════════════════════════════════════
# SLIDE 10 — Investering & ROI
# ══════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank_layout)
slide_header(s, "Investering & ROI")

# Table
rows2, cols2 = 5, 2
tbl2_shape = s.shapes.add_table(rows2, cols2, Inches(0.8), Inches(1.8), Inches(7), Inches(3.5))
tbl2 = tbl2_shape.table
tbl2.columns[0].width = Inches(3.5)
tbl2.columns[1].width = Inches(3.5)

for i, (h) in enumerate(["Post", "Bedrag / Impact"]):
    cell = tbl2.cell(0, i)
    cell.text = h
    for p in cell.text_frame.paragraphs:
        p.font.size = Pt(14); p.font.bold = True; p.font.color.rgb = WHITE; p.font.name = 'Calibri'
    cell.fill.solid(); cell.fill.fore_color.rgb = DARK_BLUE

roi_data = [
    ["Art. 2(7)(d) route", "€40.000 – €100.000"],
    ["Volledige registratie", "€90.000 – €300.000"],
    ["Risico bij niet-naleving", "Boetes €10K–€900K + marktuitsluiting"],
    ["ROI", "Markttoegang + investeerdersvertrouwen + boetes voorkomen"],
]
for r, (a, b) in enumerate(roi_data):
    for c, val in enumerate([a, b]):
        cell = tbl2.cell(r+1, c)
        cell.text = val
        for p in cell.text_frame.paragraphs:
            p.font.size = Pt(13); p.font.color.rgb = DARK_TEXT; p.font.name = 'Calibri'
        cell.fill.solid()
        cell.fill.fore_color.rgb = LIGHT_GRAY if r % 2 == 0 else WHITE

add_textbox(s, Inches(8.5), Inches(1.8), Inches(4.2), Inches(0.5),
    "Waarom nu investeren?", font_size=16, bold=True, color=DARK_BLUE)
roi_bullets = [
    "REACH-naleving is voorwaarde voor markttoegang EU",
    "Downstream users eisen conform SDS en registratiebewijs",
    "Investeerders eisen compliance-aldus vóór financiering",
    "Proactieve compliance = concurrentievoordeel",
]
add_bullets(s, Inches(8.5), Inches(2.5), Inches(4.2), Inches(3.5), roi_bullets, font_size=13, spacing=Pt(8))

# ══════════════════════════════════════════════════════════
# SLIDE 11 — Volgende Stappen
# ══════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank_layout)
slide_header(s, "Volgende Stappen — Komende 4 weken")

steps = [
    ("Actie 1", "Start stofidentificatie (SIP)", "Verzamel analytische data: ICP-OES, XRD, XRF. Stel SIP op conform ECHA-richtsnoeren.", "HSEQ-Manager + extern lab"),
    ("Actie 2", "EoW-dossier opstellen", "Documenteer 4 cumulatieve EoW-criteria. Verzamel afnemerscontracten, productsheets, emissiedata.", "HSEQ-Manager + Directie"),
    ("Actie 3", "REACH-adviseur aanstellen", "Selecteer REACH/CLP-specialist voor routebepaling (art. 2(7)(d) vs. volledige registratie).", "Directie + Procurement"),
]

y = Inches(1.8)
for num, title, desc, who in steps:
    add_shape(s, Inches(0.8), y, Inches(0.4), Inches(1.2), ACCENT_BLUE)
    add_textbox(s, Inches(0.85), y + Inches(0.2), Inches(0.35), Inches(0.4), "▸", font_size=20, bold=True, color=WHITE)
    add_textbox(s, Inches(1.5), y, Inches(3), Inches(0.4), f"{num}: {title}", font_size=16, bold=True, color=DARK_BLUE)
    add_textbox(s, Inches(1.5), y + Inches(0.45), Inches(7), Inches(0.5), desc, font_size=13, color=DARK_TEXT)
    add_textbox(s, Inches(9), y + Inches(0.1), Inches(3.5), Inches(0.4), f"👤 {who}", font_size=12, color=MED_GRAY)
    y += Inches(1.5)

# Vragen
add_shape(s, Inches(3.5), Inches(6.0), Inches(6.3), Inches(0.9), DARK_BLUE)
add_textbox(s, Inches(3.5), Inches(6.1), Inches(6.3), Inches(0.7),
    "Vragen?", font_size=28, bold=True, color=WHITE, alignment=PP_ALIGN.CENTER)

# ── Save ──
out_dir = "/root/projects/jg/2026-reach-phoenix-metals/deliverables/pptx"
os.makedirs(out_dir, exist_ok=True)
fname = "REACH_Management_Presentatie_Phoenix_Metals_D5_v1.0.pptx"
fpath = os.path.join(out_dir, fname)
prs.save(fpath)
print(f"✅ Saved: {fpath}")
