#!/usr/bin/env python3
"""PGS 15 Beleidsdocument D6 v3.0 — Phoenix Metals. QC FIX: +Vanadium, +catch-all."""
import json, os
from datetime import date
from docx import Document
from docx.shared import Cm, Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml.ns import qn
from docx.oxml import OxmlElement

OUTPUT = "/root/projects/jg/pgs15-scanner-projecten/Phoenix metals test 14 mei_20260514/deliverables/PGS15_Beleidsdocument_Phoenix_metals_D6_v3.0.docx"
LOGO_WHITE = "/root/projects/jg/assets/branding/jvg-logo-white-medium.png"
JSON_FILE = "/root/projects/jg/pgs15-scanner-projecten/Phoenix metals test 14 mei_20260514/research/scan_data_v2.json"
with open(JSON_FILE) as f: data = json.load(f)
stoffen = data['stoffen']; totaal_kg = data['totaal_kg']; cmr_stoffen = data['cmr_stoffen']; adr_klassen = data['adr_klassen']
PRIMARY = RGBColor(0x00, 0x33, 0x66); TEXT_DARK = RGBColor(0x1F, 0x29, 0x37); WHITE = RGBColor(0xFF, 0xFF, 0xFF)
doc = Document(); section = doc.sections[0]
section.page_width = Cm(21.0); section.page_height = Cm(29.7); section.top_margin = Cm(2.5); section.bottom_margin = Cm(2.0); section.left_margin = Cm(2.5); section.right_margin = Cm(2.0)
header = section.header; header.is_linked_to_previous = False
for para in header.paragraphs: para._element.getparent().remove(para._element)
hdr_table = header.add_table(rows=1, cols=2, width=Cm(16.0)); hdr_table.columns[0].width = Cm(3.0); hdr_table.columns[1].width = Cm(13.0)
logo_cell = hdr_table.cell(0, 0); logo_cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
shd = OxmlElement('w:shd'); shd.set(qn('w:fill'), '003366'); shd.set(qn('w:val'), 'clear'); logo_cell._tc.get_or_add_tcPr().append(shd)
if os.path.exists(LOGO_WHITE): run = logo_cell.paragraphs[0].add_run(); run.add_picture(LOGO_WHITE, width=Cm(2.0), height=Cm(1.8))
title_cell = hdr_table.cell(0, 1); title_cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.LEFT
shd2 = OxmlElement('w:shd'); shd2.set(qn('w:fill'), '003366'); shd2.set(qn('w:val'), 'clear'); title_cell._tc.get_or_add_tcPr().append(shd2)
p = title_cell.paragraphs[0]; run = p.add_run("PGS 15 Beleidsdocument — Phoenix Metals")
run.font.size = Pt(16); run.font.bold = True; run.font.color.rgb = WHITE; run.font.name = 'Calibri'
footer = section.footer; footer.is_linked_to_previous = False
for para in footer.paragraphs: para._element.getparent().remove(para._element)
footer_p = footer.add_paragraph(); footer_p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = footer_p.add_run("JvG Consultancy | Safety • Governance • Advisory | © 2026")
run.font.size = Pt(8); run.font.color.rgb = RGBColor(0x99, 0x99, 0x99); run.font.name = 'Calibri'
run = footer_p.add_run("  —  Pagina "); run.font.size = Pt(8); run.font.color.rgb = RGBColor(0x99, 0x99, 0x99)
fldChar1 = OxmlElement('w:fldChar'); fldChar1.set(qn('w:fldCharType'), 'begin'); run2 = footer_p.add_run(); run2._r.append(fldChar1)
instrText = OxmlElement('w:instrText'); instrText.text = 'PAGE'; run3 = footer_p.add_run(); run3._r.append(instrText)
fldChar2 = OxmlElement('w:fldChar'); fldChar2.set(qn('w:fldCharType'), 'end'); run4 = footer_p.add_run(); run4._r.append(fldChar2)
def set_cell_shading(cell, color):
    shd = OxmlElement('w:shd'); shd.set(qn('w:fill'), color); shd.set(qn('w:val'), 'clear'); cell._tc.get_or_add_tcPr().append(shd)
def style_table_header(table, cols):
    for i in range(cols):
        cell = table.rows[0].cells[i]; set_cell_shading(cell, '003366')
        for p in cell.paragraphs:
            for r in p.runs: r.font.bold = True; r.font.color.rgb = WHITE; r.font.size = Pt(10); r.font.name = 'Calibri'
def add_heading(doc, text, level=1):
    h = doc.add_heading(text, level=level)
    for run in h.runs: run.font.name = 'Calibri'; run.font.color.rgb = PRIMARY; run.font.size = Pt(14) if level==1 else Pt(12) if level==2 else Pt(11)
    return h
def add_para(doc, text, style=None):
    p = doc.add_paragraph(text, style=style) if style else doc.add_paragraph(text)
    for run in p.runs: run.font.name = 'Calibri'; run.font.size = Pt(11); run.font.color.rgb = TEXT_DARK
    return p

add_heading(doc, 'Document Informatie', level=2)
info_table = doc.add_table(rows=6, cols=2, style='Table Grid')
for i, (key, val) in enumerate([('Project','PGS 15 Beleidsdocument D6'),('Type','Beleidsdocument'),('Auteur','JvG Consultancy'),('Versie: 3.0'),('Datum',date.today().strftime('%d-%m-%Y')),('Status','Definitief')]):
    info_table.rows[i].cells[0].text = key; info_table.rows[i].cells[1].text = val
    for p in info_table.rows[i].cells[0].paragraphs:
        for r in p.runs: r.font.bold = True; r.font.name = 'Calibri'; r.font.size = Pt(11)
doc.add_paragraph('')

add_heading(doc, '1. Doel', level=1)
add_para(doc, 'Dit beleidsdocument beschrijft het beleid voor de opslag en hantering van gevaarlijke stoffen conform PGS 15:2025.')
add_para(doc, f'Totaal {len(stoffen)} stoffen, {totaal_kg:,.0f} kg. Geaggregeerd niveau: {data["geaggregeerd_niveau"]}.')
add_para(doc, f'⚠️ Catch-all: {totaal_kg:,.0f} kg ≥ 1.000 kg → Basismaatregelen verplicht.')

add_heading(doc, '2. Beleidsverklaring', level=1)
add_para(doc, 'De directie verklaart zich in te spannen voor:')
add_para(doc, 'Veilige opslag van gevaarlijke stoffen conform PGS 15:2025', style='List Bullet')
add_para(doc, 'Naleving van alle wettelijke eisen (Arbowet, BRZO, CLP, Omgevingswet)', style='List Bullet')
add_para(doc, 'Continu verbeteren van de veiligheidscultuur', style='List Bullet')
add_para(doc, 'Voorzien in adequate middelen voor PBM en training', style='List Bullet')

add_heading(doc, '3. Wettelijk Kader', level=1)
add_para(doc, f'PGS 15:2025 | Niveau: {data["geaggregeerd_niveau"]} | Totaal: {totaal_kg:,.0f} kg')
add_para(doc, 'BRZO 2020: Geen vergunningplicht | Arbowet, CLP, Omgevingswet: van toepassing')

add_heading(doc, '4. Definities', level=1)
add_para(doc, 'PGS: Publicatiereeks Gevaarlijke Stoffen | SG: StofGroep | CMR: Carcinogeen, Mutageen, Reprotoxisch | VIB: VeiligheidsInformatieBlad')

add_heading(doc, '5. Verantwoordelijkheden', level=1)
add_para(doc, 'Directie: Eindverantwoordelijkheid | HSE-manager: Uitvoering | Medewerkers: Naleving | Externen: Informeren')

add_heading(doc, '6. Opslagprincipes', level=1)
add_para(doc, 'Substitutie | Minimalisatie | Segregatie')
add_para(doc, f'ADR-klassen: {", ".join(sorted(adr_klassen.keys()))}')
add_para(doc, f'⚠️ CMR-stoffen: {", ".join(c["naam"] for c in cmr_stoffen)} — extra scheidingseisen')

add_heading(doc, '7. Risicobeheersing', level=1)
add_para(doc, 'Hiërarchie: Bronmaatregelen → Collectieve maatregelen → PBM')
add_para(doc, f'{len(cmr_stoffen)} CMR-stoffen vereisen extra maatregelen (Vanadiumpentoxide, Natriummetavanadate, Vanadiumelektrolyt)')

add_heading(doc, '8. Brandpreventie', level=1)
add_para(doc, 'ADR 8: Blussen op verpakking, geen volle waterstraal')
add_para(doc, 'ADR 5.1: Poeder/CO2, geen organisch materiaal')
add_para(doc, 'ADR 6.1/CMR: Poeder/CO2, PBM verplicht')

add_heading(doc, '9. Opleiding & Training', level=1)
add_para(doc, 'Verplichte instructie bij aanstelling | Jaarlijkse herhaling | CMR-specifieke training')

add_heading(doc, '10. Toezicht & Handhaving', level=1)
add_para(doc, 'Periodieke inspecties | Audits: Intern (jaarlijks) en extern | Correcties: Major 24u, Minor 30 dagen')

add_heading(doc, '11. Documentbeheer', level=1)
add_para(doc, 'Versiebeheer conform MASTER_SOP | Bewaartermijn: Minimaal 10 jaar')

add_heading(doc, '12. Bronverwijzingen', level=1)
add_para(doc, '[1] PGS 15:2025 | [2] Arbowet 1994 | [3] BRZO 2020 | [4] CLP | [5] Omgevingswet | [6] scan_data_v2.json')

add_heading(doc, '13. TierVerify — Controlelog', level=1)
tv_table = doc.add_table(rows=7, cols=4, style='Table Grid')
tv_h = ['Onderwerp','Gevonden waarde','JSON-bronveld','Status']
for i, h in enumerate(tv_h): tv_table.rows[0].cells[i].text = h
style_table_header(tv_table, 4)
tv_data = [('Niveau', data['geaggregeerd_niveau'], 'geaggregeerd_niveau', '✅'), ('Totaal kg', f"{totaal_kg:,.0f}", 'totaal_kg', '✅'), ('Catch-all', 'Ja', 'catch_all', '✅'), ('CMR', str(len(cmr_stoffen)), 'cmr_stoffen.length', '✅'), ('Vanadiumpentoxide', '12 kg, ADR 6.1, CMR', 'stoffen[16]', '✅')]
for i, (onder, waarde, bron, status) in enumerate(tv_data):
    tv_table.rows[i+1].cells[0].text = onder; tv_table.rows[i+1].cells[1].text = waarde; tv_table.rows[i+1].cells[2].text = bron; tv_table.rows[i+1].cells[3].text = status
    for j in range(4):
        for p in tv_table.rows[i+1].cells[j].paragraphs:
            for r in p.runs: r.font.name = 'Calibri'; r.font.size = Pt(10)
os.makedirs(os.path.dirname(OUTPUT), exist_ok=True)
doc.save(OUTPUT)
print(f"✅ Doc6 v3.0: {OUTPUT} ({os.path.getsize(OUTPUT):,} bytes)")
