#!/usr/bin/env python3
"""Update 12 PGS-15 documents from v5.0/v3.0/v2.0 to v6.1.
Chirurgisch: only text replacements, preserve layout/formatting."""

import shutil, os, re
from docx import Document
from pptx import Presentation

BASE = "/root/projects/jg/2026-pgs15-phoenix-metals/deliverables/docx"
ARCHIVE = "/root/projects/jg/2026-pgs15-phoenix-metals/archive"
os.makedirs(ARCHIVE, exist_ok=True)

# --- Text replacements (applied to every run in paragraphs and tables) ---
REPLACEMENTS = [
    # Hoeveelheden
    (r'\bgeschatte?\b', '150 kg/ltr per product'),
    (r'\bgeschat\b', '150 kg/ltr per product'),
    (r'\btesthoeveelheden\b', '150 kg/ltr per product'),
    (r'<\s*10\s*ton', '150 kg/ltr per product'),
    (r'~?\s*117\s*(kg|ton)', '150 kg/ltr per product'),
    (r'~?\s*118\s*(kg|ton)', '150 kg/ltr per product'),
    (r'<\s*2\.000\s*kg', '150 kg/ltr per product'),
    (r'<\s*2,?000\s*kg', '150 kg/ltr per product'),
    (r'<\s*500\s*kg', '2.700 kg'),
    # Stoffen count
    (r'\b20\s+stoffen\b', '18 stoffen'),
    (r'\b20\s+gevaarlijke\s+stoffen\b', '18 gevaarlijke stoffen'),
    # Seveso totalen
    (r'~?\s*2\.?\s*700\s*kg', '2.700 kg'),
    # Routes - CMR
    (r'CMR-route is leidend', 'ADR-route is leidend bij ADR-geclassificeerde stoffen'),
    (r'CMR-route verplicht Niveau C', 'ADR 6.1 PG III <10.000 kg → Niveau C (Tabel 6)'),
    (r'CMR ongeacht hoeveelheid', 'ADR-route + arbo-maatregelen voor CMR (Arbobesluit art. 4.1c)'),
    (r'CMR-route', 'ADR-route'),
    # Niveaus - ADR 5.1
    (r'Niveau B\b(?![\s\-]*(via|aggre|indiv))', 'Niveau C'),  # generic B->C where safe
    # Versie
    (r'\bv5\.0\b', 'v6.1'),
    (r'\bv4\.0\b', 'v6.1'),
    (r'\bv3\.0\b', 'v6.1'),
    (r'\bv2\.0\b', 'v6.1'),
    # Datum
    (r'6 mei 2026', '7 mei 2026'),
    (r'6 mei\s*2026', '7 mei 2026'),
    (r'6\s+mei\s+2026', '7 mei 2026'),
    # Status
    ('Definitief', 'Definitief — PGS 15:2025 norm-gecorrigeerd'),
]

def apply_replacements(text):
    """Apply all regex/text replacements to a string. Return (new_text, count)."""
    count = 0
    for pattern, repl in REPLACEMENTS:
        if isinstance(pattern, str):
            # literal
            n = text.count(pattern)
            if n:
                text = text.replace(pattern, repl)
                count += n
        else:
            n = len(re.findall(pattern, text))
            if n:
                text = re.sub(pattern, repl, text)
                count += n
    return text, count

def process_run(run):
    """Process a single run, return change count."""
    if not run.text:
        return 0
    new_text, cnt = apply_replacements(run.text)
    if cnt:
        run.text = new_text
    return cnt

def process_paragraph(para):
    cnt = 0
    for run in para.runs:
        cnt += process_run(run)
    return cnt

def process_docx(filepath):
    """Process a DOCX file, return total changes."""
    doc = Document(filepath)
    total = 0
    for para in doc.paragraphs:
        total += process_paragraph(para)
    for table in doc.tables:
        for row in table.rows:
            for cell in row.cells:
                for para in cell.paragraphs:
                    total += process_paragraph(para)
    # Headers/footers
    for section in doc.sections:
        for header in [section.header, section.first_page_header]:
            for para in header.paragraphs:
                total += process_paragraph(para)
        for footer in [section.footer, section.first_page_footer]:
            for para in footer.paragraphs:
                total += process_paragraph(para)
    return doc, total

def process_pptx(filepath):
    """Process a PPTX file, return total changes."""
    prs = Presentation(filepath)
    total = 0
    for slide in prs.slides:
        for shape in slide.shapes:
            if shape.has_text_frame:
                for para in shape.text_frame.paragraphs:
                    for run in para.runs:
                        total += process_run(run)
            if shape.has_table:
                for row in shape.table.rows:
                    for cell in row.cells:
                        for para in cell.text_frame.paragraphs:
                            for run in para.runs:
                                total += process_run(run)
    return prs, total

# Document definitions
DOCS = [
    ("PGS15_Kennisdossier_Phoenix_Metals_D1_v5.0.docx", "PGS15_Kennisdossier_Phoenix_Metals_D1_v6.1.docx", "docx"),
    ("PGS15_VeiligWerken_HSEQ_Phoenix_Metals_D2_v5.0.docx", "PGS15_VeiligWerken_HSEQ_Phoenix_Metals_D2_v6.1.docx", "docx"),
    ("PGS15_Veiligheidsinfo_Documentatie_Phoenix_Metals_D3_v5.0.docx", "PGS15_Veiligheidsinfo_Documentatie_Phoenix_Metals_D3_v6.1.docx", "docx"),
    ("PGS15_MasterSOP_Opslagveiligheid_Phoenix_Metals_D4_v5.0.docx", "PGS15_MasterSOP_Opslagveiligheid_Phoenix_Metals_D4_v6.1.docx", "docx"),
    ("PGS15_Basishandleiding_Phoenix_Metals_v5.0.docx", "PGS15_Basishandleiding_Phoenix_Metals_v6.1.docx", "docx"),
    ("PGS15_Beleidsdocument_Policy_v3.0.docx", "PGS15_Beleidsdocument_Policy_v6.1.docx", "docx"),
    ("PGS15_Audit_Checklist_v5.0.docx", "PGS15_Audit_Checklist_v6.1.docx", "docx"),
    ("PGS15_Audit_Procedure_v5.0.docx", "PGS15_Audit_Procedure_v6.1.docx", "docx"),
    ("PGS15_Audit_Rapport_Template_v5.0.docx", "PGS15_Audit_Rapport_Template_v6.1.docx", "docx"),
    ("PGS15_Management_Presentatie_Phoenix_Metals_D5_v5.0.pptx", "PGS15_Management_Presentatie_Phoenix_Metals_D5_v6.1.pptx", "pptx"),
    ("PGS15_Procedure_Opslagveiligheid_v2.0.docx", "PGS15_Procedure_Opslagveiligheid_v6.1.docx", "docx"),
    ("PGS15_Werkinstructie_GevaarlijkeStoffen_v2.0.docx", "PGS15_Werkinstructie_GevaarlijkeStoffen_v6.1.docx", "docx"),
]

results = []

for src_name, dst_name, ftype in DOCS:
    src_path = os.path.join(BASE, src_name)
    dst_path = os.path.join(BASE, dst_name)
    arc_path = os.path.join(ARCHIVE, src_name)
    
    if not os.path.exists(src_path):
        results.append(f"❌ {src_name}: BRON NIET GEVONDEN")
        continue
    
    # Archive source
    shutil.copy2(src_path, arc_path)
    
    try:
        if ftype == "docx":
            obj, changes = process_docx(src_path)
            obj.save(dst_path)
        else:
            obj, changes = process_pptx(src_path)
            obj.save(dst_path)
        
        status = f"✅ {changes} wijzigingen" if changes else "ℹ️ 0 wijzigingen (geen matches)"
        results.append(f"{status} | {src_name} → {dst_name}")
    except Exception as e:
        results.append(f"❌ {src_name}: FOUT - {e}")

print("\n" + "="*80)
print("UPDATE RESULTATEN v5.0 → v6.1")
print("="*80)
for r in results:
    print(r)
print("="*80)
print(f"Klaar. {len(results)} documenten verwerkt.")
