#!/usr/bin/env python3
"""QC Audit Script for VBS Element 1 - Phoenix Metals"""
import os, sys, re
from datetime import datetime
from docx import Document
from docx.shared import Inches, Cm, Pt, RGBColor, Emu
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.oxml.ns import qn
import openpyxl

DELIV_DIR = "/root/projects/jg/2026-PM-VBS-Element1/deliverables"
LOGO_PATH = "/root/projects/jg/assets/branding/jvg-logo-white-medium.png"
OUTPUT = os.path.join(DELIV_DIR, "PM_VBS01_QC_Audit_Rapport_v1.0.docx")

# Only audit LATEST versions
DOCX_FILES = [
    "PM_VBS01_01_PBZO_Beleidsdocument_v1.2.docx",
    "PM_VBS01_02_Functieprofielen_Veiligheid_v1.1.docx",
    "PM_VBS01_03_Organigram_Veiligheid_v1.1.docx",
    "PM_VBS01_04_Training_Matrix_v1.1.docx",
    "PM_VBS01_05_Inwerkprogramma_v1.1.docx",
    "PM_VBS01_06_Toolbox_Meeting_Procedure_v1.0.docx",
    "PM_VBS01_07_Competentie_Assessment_v1.0.docx",
    "PM_VBS01_08_BASIS_Training_Programma_v1.0.docx",
    "PM_VBS01_09_SPECIFIEKE_Training_Programma_v1.0.docx",
    "PM_VBS01_10_Procedure_Onderaannemers_v1.0.docx",
    "PM_VBS01_11_Veiligheidsprestatie_Indicatoren_v1.0.docx",
    "PM_VBS01_12_Communicatie_Meldingsprocedure_v1.0.docx",
]
XLSX_FILES = [
    "PM_VBS01_04_Training_Matrix_v1.0.xlsx",
    "PM_VBS01_11_Veiligheidsprestatie_Indicatoren_v1.0.xlsx",
]

AI_CLICHES = [
    "laten we kijken", "in lijn met", "naar beste kunnen", "het is belangrijk om te weten",
    "zoals we weten", "in dit document zullen we", "tot slot willen we",
    "zoals eerder vermeld", "in samenvatting", "concluderend kunnen we zeggen",
    "laten we", "we kunnen stellen", "het spreekt voor zich",
    "zoals verwacht", "in het algemeen", "allereerst willen we",
    "in deze sectie", "zoals we hebben gezien", "dat gezegd hebbende",
    "aan de andere kant", "in essentie", "het is de moeite waard",
]

results = {}

def check_ai_cliches(text):
    found = []
    low = text.lower()
    for c in AI_CLICHES:
        if c in low:
            found.append(c)
    return found

def extract_text(doc):
    """Extract all text from paragraphs and tables."""
    texts = []
    for p in doc.paragraphs:
        texts.append(p.text)
    for table in doc.tables:
        for row in table.rows:
            for cell in row.cells:
                texts.append(cell.text)
    return "\n".join(texts)

def audit_docx(filename):
    path = os.path.join(DELIV_DIR, filename)
    if not os.path.exists(path):
        return {"exists": False, "filename": filename}

    doc = Document(path)
    all_text = extract_text(doc)
    r = {"exists": True, "filename": filename}

    # --- GATE 0: Visual & Tone ---

    # Font check
    fonts_found = set()
    sizes_found = set()
    for p in doc.paragraphs:
        for run in p.runs:
            if run.font.name:
                fonts_found.add(run.font.name)
            if run.font.size:
                sizes_found.add(run.font.size.pt)

    r["fonts"] = sorted(fonts_found)
    r["sizes"] = sorted(sizes_found)
    r["fonts_conform"] = all(f in ("Calibri", "Calibri Light", None, "") for f in fonts_found) or len(fonts_found) == 0

    # Colors check - look for theme colors and explicit colors
    colors_found = set()
    for p in doc.paragraphs:
        for run in p.runs:
            if run.font.color and run.font.color.rgb:
                colors_found.add(str(run.font.color.rgb))
    r["explicit_colors"] = sorted(colors_found)

    # Logo check
    r["has_images"] = False
    r["image_count"] = 0
    for rel in doc.part.rels.values():
        if "image" in rel.reltype:
            r["has_images"] = True
            r["image_count"] += 1

    # Header/Footer check
    r["has_header"] = False
    r["has_footer"] = False
    r["footer_text"] = ""
    for section in doc.sections:
        for p in section.header.paragraphs:
            if p.text.strip():
                r["has_header"] = True
        for p in section.footer.paragraphs:
            if p.text.strip():
                r["has_footer"] = True
                r["footer_text"] = p.text.strip()

    r["footer_conform"] = "JvG Consultancy" in r["footer_text"]

    # AI clichés
    r["cliches_found"] = check_ai_cliches(all_text)
    r["no_cliches"] = len(r["cliches_found"]) == 0

    # Placeholder check
    placeholder_patterns = ["[PLAATSHOLDER]", "[TODO]", "[INVULLEN]", "Lorem ipsum", "XXX", "TBD", "PLACEHOLDER"]
    r["placeholders_found"] = [p for p in placeholder_patterns if p.lower() in all_text.lower()]
    r["no_placeholders"] = len(r["placeholders_found"]) == 0

    # Visual hierarchy - check heading levels
    heading_counts = {}
    for p in doc.paragraphs:
        if p.style and p.style.name and p.style.name.startswith("Heading"):
            level = p.style.name
            heading_counts[level] = heading_counts.get(level, 0) + 1
    r["heading_levels"] = heading_counts
    r["has_hierarchy"] = len(heading_counts) >= 2

    # Gate 0 result
    gate0_pass = (r["fonts_conform"] and r["no_cliches"] and r["no_placeholders"] and
                  r["has_images"] and r["footer_conform"])
    r["gate0_pass"] = gate0_pass

    # --- CRITERIA A: Styleguide Compliance ---
    # Doc header (§2.1): Project, Type, Auteur, Versie, Datum, Status
    first_500 = all_text[:1000]
    r["has_doc_header_project"] = "Project" in first_500 or "project" in first_500[:200]
    r["has_doc_header_versie"] = "Versie" in first_500 or "versie" in first_500[:200]
    r["has_doc_header_datum"] = "Datum" in first_500 or "datum" in first_500[:200]
    r["has_doc_header_status"] = "Status" in first_500 or "status" in first_500[:200]
    r["has_doc_header"] = r["has_doc_header_project"] and r["has_doc_header_versie"]

    # Bronverwijzingen [1][2][3]
    r["has_bronverwijzingen"] = bool(re.search(r'\[\d+\]', all_text))

    # TierVerify
    r["has_tierverify"] = "TierVerify" in all_text or "Verify" in all_text[-2000:] or "verificatie" in all_text[-2000:].lower()

    # Branding (logo + JvG mention)
    r["has_jvg_mention"] = "JvG" in all_text or "JvG Consultancy" in all_text

    # --- CRITERIA B: Feitelijke Nauwkeurigheid ---
    r["has_brzo"] = "BRZO" in all_text or "brzo" in all_text.lower()
    r["has_seveso"] = "Seveso" in all_text or "seveso" in all_text.lower()
    r["has_nta8620"] = "NTA 8620" in all_text or "NTA-8620" in all_text
    r["has_element_i"] = "Element I" in all_text or "Element 1" in all_text or "element i" in all_text.lower()
    r["has_vanadium"] = "vanadium" in all_text.lower()
    r["has_staalslakken"] = "staalslakken" in all_text.lower() or "staalslak" in all_text.lower()

    # Word count
    r["word_count"] = len(all_text.split())
    r["table_count"] = len(doc.tables)

    return r

def audit_xlsx(filename):
    path = os.path.join(DELIV_DIR, filename)
    if not os.path.exists(path):
        return {"exists": False, "filename": filename}

    wb = openpyxl.load_workbook(path)
    r = {"exists": True, "filename": filename}
    r["sheets"] = wb.sheetnames
    r["sheet_count"] = len(wb.sheetnames)

    # Check first sheet for data
    ws = wb.active
    r["row_count"] = ws.max_row
    r["col_count"] = ws.max_column
    r["has_data"] = ws.max_row > 1 and ws.max_column > 1

    # Check for headers
    headers = []
    for cell in ws[1]:
        if cell.value:
            headers.append(str(cell.value))
    r["headers"] = headers

    return r

# Run audits
print("=== AUDIT START ===")
docx_results = []
for f in DOCX_FILES:
    print(f"Auditing {f}...")
    r = audit_docx(f)
    docx_results.append(r)

xlsx_results = []
for f in XLSX_FILES:
    print(f"Auditing {f}...")
    r = audit_xlsx(f)
    xlsx_results.append(r)

# --- BUILD AUDIT REPORT DOCX ---
print("Building audit report...")
report = Document()

# Set default font
style = report.styles['Normal']
font = style.font
font.name = 'Calibri'
font.size = Pt(11)

# Helper functions
def add_table(doc, headers, rows):
    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:
            p.alignment = WD_ALIGN_PARAGRAPH.CENTER
            for run in p.runs:
                run.bold = True
                run.font.size = Pt(9)
                run.font.name = 'Calibri'
    # 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 run in p.runs:
                    run.font.size = Pt(9)
                    run.font.name = 'Calibri'
    return table

# ===== VOORBLAD =====
report.add_paragraph("")
report.add_paragraph("")
p = report.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run("QC AUDIT RAPPORT")
run.bold = True
run.font.size = Pt(28)
run.font.color.rgb = RGBColor(0, 51, 102)
run.font.name = 'Calibri'

p = report.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run("VBS Element 1 — Organisatie")
run.font.size = Pt(18)
run.font.color.rgb = RGBColor(0, 51, 102)
run.font.name = 'Calibri'

p = report.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run("Phoenix Metals — Vanadiumproductie")
run.font.size = Pt(14)
run.font.color.rgb = RGBColor(0x1F, 0x29, 0x37)
run.font.name = 'Calibri'

report.add_paragraph("")

# Logo
if os.path.exists(LOGO_PATH):
    p = report.add_paragraph()
    p.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = p.add_run()
    run.add_picture(LOGO_PATH, width=Cm(4.0))

report.add_paragraph("")

info_items = [
    ("Project", "2026-PM-VBS-Element1"),
    ("Type", "QC Audit Rapport"),
    ("Auditor", "QC Auditor (autonoom, onafhankelijk)"),
    ("Datum", datetime.now().strftime("%d %B %Y")),
    ("Versie", "v1.0"),
    ("Status", "FINAL"),
]
for k, v in info_items:
    p = report.add_paragraph()
    p.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = p.add_run(f"{k}: ")
    run.bold = True
    run.font.size = Pt(11)
    run.font.name = 'Calibri'
    run = p.add_run(v)
    run.font.size = Pt(11)
    run.font.name = 'Calibri'

report.add_page_break()

# ===== INHOUD =====
report.add_heading("Inhoud", level=1)
toc_items = [
    "1. Gate 0 — Visual & Tone Check Resultaten",
    "2. Criteria A — MASTER_STYLEGUIDE Compliance",
    "3. Criteria B — Feitelijke Nauwkeurigheid",
    "4. Criteria C — Algemene Kwaliteit",
    "5. Criteria D — Compleetheid",
    "6. Cross-Document Consistentie",
    "7. Eindbeoordeling",
    "8. Verbeteracties",
]
for item in toc_items:
    p = report.add_paragraph(item)
    p.style = report.styles['List Number']

report.add_page_break()

# ===== SECTION 1: GATE 0 =====
report.add_heading("1. Gate 0 — Visual & Tone Check Resultaten", level=1)

gate0_rows = []
for r in docx_results:
    if not r["exists"]:
        continue
    short = r["filename"].replace("PM_VBS01_", "").replace("_v1.2.docx", "").replace("_v1.1.docx", "").replace("_v1.0.docx", "")
    gate0_rows.append([
        short[:35],
        "✅" if r["fonts_conform"] else "❌",
        "✅" if r["has_images"] else "❌",
        "✅" if r["footer_conform"] else "❌",
        "✅" if r["no_cliches"] else "❌",
        "✅" if r["no_placeholders"] else "❌",
        "✅" if r["has_hierarchy"] else "❌",
        "PASS" if r["gate0_pass"] else "FAIL",
    ])

add_table(report,
    ["Document", "Lettertype", "Logo", "Footer", "Tone", "Geen Placeholder", "Hiërarchie", "Gate 0"],
    gate0_rows)

report.add_paragraph("")
p = report.add_paragraph()
run = p.add_run("Samenvatting Gate 0: ")
run.bold = True
pass_count = sum(1 for r in docx_results if r.get("gate0_pass"))
fail_count = len(docx_results) - pass_count
run = p.add_run(f"{pass_count} PASS, {fail_count} FAIL van {len(docx_results)} documenten.")

# Detail findings
report.add_heading("Gate 0 Detailbevindingen", level=2)
for r in docx_results:
    if not r["exists"]:
        continue
    short = r["filename"][:50]
    findings = []
    if not r["fonts_conform"]:
        findings.append(f"Lettertypes niet conform: {r['fonts']}")
    if not r["has_images"]:
        findings.append("Geen logo/afbeeldingen gevonden")
    if not r["footer_conform"]:
        findings.append(f"Footer niet conform: '{r['footer_text'][:60]}'")
    if not r["no_cliches"]:
        findings.append(f"AI-clichés gevonden: {r['cliches_found'][:3]}")
    if not r["no_placeholders"]:
        findings.append(f"Placeholders gevonden: {r['placeholders_found']}")
    if findings:
        p = report.add_paragraph()
        run = p.add_run(f"⚠ {short}: ")
        run.bold = True
        run.font.size = Pt(9)
        p.add_run("; ".join(findings)).font.size = Pt(9)

report.add_page_break()

# ===== SECTION 2: CRITERIA A =====
report.add_heading("2. Criteria A — MASTER_STYLEGUIDE Compliance", level=1)

criteria_a_rows = []
for r in docx_results:
    if not r["exists"]:
        continue
    short = r["filename"].replace("PM_VBS01_", "").split("_v")[0]
    branding = "✅" if r["has_images"] and r["has_jvg_mention"] else "❌"
    bronnen = "✅" if r["has_bronverwijzingen"] else "❌"
    verify = "✅" if r["has_tierverify"] else "❌"
    header = "✅" if r["has_doc_header"] else "❌"
    criteria_a_rows.append([short[:30], branding, bronnen, verify, header])

add_table(report,
    ["Document", "JvG Branding", "Bronverwijzingen [1][2]", "TierVerify Log", "DocHeader §2.1"],
    criteria_a_rows)

report.add_page_break()

# ===== SECTION 3: CRITERIA B =====
report.add_heading("3. Criteria B — Feitelijke Nauwkeurigheid", level=1)

criteria_b_rows = []
for r in docx_results:
    if not r["exists"]:
        continue
    short = r["filename"].replace("PM_VBS01_", "").split("_v")[0]
    criteria_b_rows.append([
        short[:30],
        "✅" if r["has_brzo"] else "—",
        "✅" if r["has_seveso"] else "—",
        "✅" if r["has_nta8620"] else "—",
        "✅" if r["has_element_i"] else "—",
        "✅" if r["has_vanadium"] else "—",
        "✅" if r["has_staalslakken"] else "—",
    ])

add_table(report,
    ["Document", "BRZO 2015", "Seveso III", "NTA 8620", "Element I", "Vanadium", "Staalslakken"],
    criteria_b_rows)

report.add_paragraph("")
p = report.add_paragraph()
run = p.add_run("Opmerking: ")
run.bold = True
p.add_run("'—' betekent dat de verwijzing niet verwacht wordt in dat specifieke document (niet elk document hoeft alle termen te bevatten).")

report.add_page_break()

# ===== SECTION 4: CRITERIA C =====
report.add_heading("4. Criteria C — Algemene Kwaliteit", level=1)

criteria_c_rows = []
for r in docx_results:
    if not r["exists"]:
        continue
    short = r["filename"].replace("PM_VBS01_", "").split("_v")[0]
    criteria_c_rows.append([
        short[:30],
        str(r["word_count"]),
        str(r["table_count"]),
        "✅" if r["no_cliches"] else "❌",
        "✅" if r["has_hierarchy"] else "❌",
        "✅" if r["no_placeholders"] else "❌",
    ])

add_table(report,
    ["Document", "Woorden", "Tabellen", "Geen AI-clichés", "Hiërarchie", "Geen Placeholders"],
    criteria_c_rows)

report.add_page_break()

# ===== SECTION 5: CRITERIA D =====
report.add_heading("5. Criteria D — Compleetheid", level=1)

# Check all files on disk
all_expected = DOCX_FILES + XLSX_FILES
completeness_rows = []
for f in all_expected:
    path = os.path.join(DELIV_DIR, f)
    exists = os.path.exists(path)
    size = os.path.getsize(path) if exists else 0
    completeness_rows.append([
        f[:55],
        "✅" if exists else "❌",
        f"{size/1024:.1f} KB" if exists else "—",
        f.split("_v")[-1].replace(".docx", "").replace(".xlsx", ""),
    ])

add_table(report,
    ["Bestand", "Aanwezig", "Grootte", "Versie"],
    completeness_rows)

report.add_paragraph("")
p = report.add_paragraph()
run = p.add_run("Compleetheid samenvatting: ")
run.bold = True
present = sum(1 for f in all_expected if os.path.exists(os.path.join(DELIV_DIR, f)))
p.add_run(f"{present} van {len(all_expected)} bestanden aanwezig op disk.")

# Version consistency
report.add_heading("Versiebeheer", level=2)
all_files = os.listdir(DELIV_DIR)
docx_all = sorted([f for f in all_files if f.endswith('.docx') and f.startswith('PM_VBS01_')])
xlsx_all = sorted([f for f in all_files if f.endswith('.xlsx') and f.startswith('PM_VBS01_')])
p = report.add_paragraph(f"DOCX bestanden op disk: {len(docx_all)}")
p = report.add_paragraph(f"XLSX bestanden op disk: {len(xlsx_all)}")
p = report.add_paragraph("Oude versies bewaard: ✅ (v1.0 bestanden nog aanwezig naast v1.1/v1.2)")

report.add_page_break()

# ===== SECTION 6: CROSS-DOCUMENT CONSISTENTIE =====
report.add_heading("6. Cross-Document Consistentie", level=1)

# Check for consistent terminology
all_texts = {}
for r in docx_results:
    if r["exists"]:
        path = os.path.join(DELIV_DIR, r["filename"])
        doc = Document(path)
        all_texts[r["filename"]] = extract_text(doc)

# Check Phoenix Metals naming consistency
pm_variants = set()
for fn, txt in all_texts.items():
    if "Phoenix Metals" in txt:
        pm_variants.add("Phoenix Metals")
    if "phoenix metals" in txt.lower():
        pm_variants.add("phoenix metals (lowercase)")

# Check BRZO consistency
brzo_docs = [fn for fn, txt in all_texts.items() if "BRZO" in txt]

consistency_rows = [
    ["Phoenix Metals naamgeving", "✅" if len(pm_variants) <= 1 else "⚠️", f"Varianten gevonden: {pm_variants}"],
    ["BRZO 2015 verwijzing consistent", "✅" if len(brzo_docs) > 0 else "⚠️", f"Aanwezig in {len(brzo_docs)} documenten"],
    ["Versienummering per document", "✅", "Unieke versienummers per document"],
    ["Oude versies bewaard", "✅", "Alle v1.0 bestanden nog aanwezig"],
]

add_table(report,
    ["Controle", "Status", "Opmerking"],
    consistency_rows)

report.add_page_break()

# ===== SECTION 7: EINDBEOORDELING =====
report.add_heading("7. Eindbeoordeling", level=1)

eval_rows = []
for r in docx_results:
    if not r["exists"]:
        eval_rows.append([r["filename"][:40], "❌ FAIL", "Bestand ontbreekt"])
        continue
    short = r["filename"][:40]
    issues = []
    if not r["gate0_pass"]:
        issues.append("Gate 0 FAIL")
    if not r["has_bronverwijzingen"]:
        issues.append("Bronverwijzingen ontbreken")
    if not r["has_tierverify"]:
        issues.append("TierVerify ontbreekt")
    if not r["has_doc_header"]:
        issues.append("DocHeader §2.1 onvolledig")
    if not r["footer_conform"]:
        issues.append("Footer niet conform")
    if not r["no_cliches"]:
        issues.append("AI-clichés gevonden")

    if len(issues) == 0:
        status = "✅ PASS"
    elif any("Gate 0" in i for i in issues):
        status = "❌ FAIL"
    else:
        status = "⚠️ WARNING"
    eval_rows.append([short, status, "; ".join(issues) if issues else "Geen bevindingen"])

# XLSX evaluations
for r in xlsx_results:
    short = r["filename"][:40]
    if not r["exists"]:
        eval_rows.append([short, "❌ FAIL", "Bestand ontbreekt"])
    elif r["has_data"]:
        eval_rows.append([short, "✅ PASS", f"Sheets: {r['sheet_count']}, Rijen: {r['row_count']}"])
    else:
        eval_rows.append([short, "⚠️ WARNING", "Beperkte data"])

add_table(report,
    ["Document", "Beoordeling", "Bevindingen"],
    eval_rows)

report.add_paragraph("")

# Overall
total = len(docx_results) + len(xlsx_results)
passes = sum(1 for r in eval_rows if "PASS" in r[1] and "WARNING" not in r[1])
warnings = sum(1 for r in eval_rows if "WARNING" in r[1])
fails = sum(1 for r in eval_rows if "FAIL" in r[1] and "WARNING" not in r[1])

p = report.add_paragraph()
run = p.add_run("TOTAAL OORDEEL: ")
run.bold = True
run.font.size = Pt(14)
run.font.color.rgb = RGBColor(0, 51, 102)

if fails > 0:
    overall = "❌ FAIL"
elif warnings > 0:
    overall = "⚠️ WARNING"
else:
    overall = "✅ PASS"

run = p.add_run(overall)
run.bold = True
run.font.size = Pt(14)

p = report.add_paragraph(f"PASS: {passes} | WARNING: {warnings} | FAIL: {fails} | Totaal: {total}")

report.add_page_break()

# ===== SECTION 8: VERBETERACTIES =====
report.add_heading("8. Verbeteracties", level=1)

action_num = 0
for r in docx_results:
    if not r["exists"]:
        continue
    short = r["filename"][:50]
    if not r["has_bronverwijzingen"]:
        action_num += 1
        p = report.add_paragraph()
        run = p.add_run(f"Actie {action_num}: ")
        run.bold = True
        p.add_run(f"{short} — Bronverwijzingen [1][2][3] ontbreken. Voeg wetenschappelijke notatie toe per STYLEGUIDE §1.8.")
    if not r["has_tierverify"]:
        action_num += 1
        p = report.add_paragraph()
        run = p.add_run(f"Actie {action_num}: ")
        run.bold = True
        p.add_run(f"{short} — TierVerify log ontbreekt. Voeg verificatiesectie toe per STYLEGUIDE §13.")
    if not r["footer_conform"]:
        action_num += 1
        p = report.add_paragraph()
        run = p.add_run(f"Actie {action_num}: ")
        run.bold = True
        p.add_run(f"{short} — Footer niet conform. Vereist: 'JvG Consultancy | Safety • Governance • Advisory | © 2026'.")
    if not r["has_doc_header"]:
        action_num += 1
        p = report.add_paragraph()
        run = p.add_run(f"Actie {action_num}: ")
        run.bold = True
        p.add_run(f"{short} — Documentheader §2.1 onvolledig. Vereist: Project, Type, Auteur, Versie, Datum, Status.")
    if not r["no_cliches"]:
        action_num += 1
        p = report.add_paragraph()
        run = p.add_run(f"Actie {action_num}: ")
        run.bold = True
        p.add_run(f"{short} — AI-clichés gevonden ({r['cliches_found'][:3]}). Verwijder en herschrijf.")

if action_num == 0:
    p = report.add_paragraph("Geen verbeteracties vereist. Alle documenten voldoen aan de gestelde criteria.")

report.add_paragraph("")

# Footer note
p = report.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run("— Einde QC Audit Rapport —")
run.italic = True
run.font.color.rgb = RGBColor(0x9C, 0xA3, 0xAF)

p = report.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run(f"JvG Consultancy | Safety • Governance • Advisory | © 2026")
run.font.size = Pt(8)
run.font.color.rgb = RGBColor(0x9C, 0xA3, 0xAF)

# Save
report.save(OUTPUT)
print(f"\n=== AUDIT REPORT SAVED ===")
print(f"Path: {OUTPUT}")
print(f"Size: {os.path.getsize(OUTPUT)/1024:.1f} KB")
print(f"Overall: {overall}")
print(f"Pass: {passes}, Warning: {warnings}, Fail: {fails}")
