#!/usr/bin/env python3
"""
REACH Kennisdossier Generator v2.0
Samenvoegt Deel 1 + Deel 2 markdown → professionele DOCX met Phoenix Metals huisstijl
Output: REACH_Kennisdossier_Phoenix_Metals_v2.0.docx
"""

from docx import Document
from docx.shared import Pt, Inches, Cm, RGBColor, Emu
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, nsdecls
from docx.oxml import parse_xml
import re

# ── Config ──
BLAUW = RGBColor(0x00, 0x33, 0x66)
ORANJE = RGBColor(0xFF, 0x66, 0x00)
ZWART = RGBColor(0x00, 0x00, 0x00)
WIT = RGBColor(0xFF, 0xFF, 0xFF)
LIJN = RGBColor(0xCC, 0xCC, 0xCC)
DEEL1 = "/root/projects/jg/2026-reach-phoenix-metals-v2/working/kennisdossier_deel1.md"
DEEL2 = "/root/projects/jg/2026-reach-phoenix-metals-v2/working/kennisdossier_deel2.md"
OUTPUT = "/root/projects/jg/2026-reach-phoenix-metals-v2/deliverables/kennisdossier/REACH_Kennisdossier_Phoenix_Metals_v2.0.docx"

doc = Document()

# ── Styles ──
style = doc.styles['Normal']
font = style.font
font.name = 'Calibri'
font.size = Pt(11)
font.color.rgb = ZWART
pf = style.paragraph_format
pf.space_after = Pt(6)
pf.space_before = Pt(2)
pf.line_spacing = 1.15

# Heading 1
h1 = doc.styles['Heading 1']
h1.font.name = 'Calibri'
h1.font.size = Pt(22)
h1.font.bold = True
h1.font.color.rgb = BLAUW
h1.paragraph_format.space_before = Pt(24)
h1.paragraph_format.space_after = Pt(12)
h1.paragraph_format.keep_with_next = True

# Heading 2
h2 = doc.styles['Heading 2']
h2.font.name = 'Calibri'
h2.font.size = Pt(16)
h2.font.bold = True
h2.font.color.rgb = BLAUW
h2.paragraph_format.space_before = Pt(18)
h2.paragraph_format.space_after = Pt(8)

# Heading 3
h3 = doc.styles['Heading 3']
h3.font.name = 'Calibri'
h3.font.size = Pt(13)
h3.font.bold = True
h3.font.color.rgb = RGBColor(0x00, 0x55, 0x88)
h3.paragraph_format.space_before = Pt(12)
h3.paragraph_format.space_after = Pt(6)

# ── Margins ──
for section in doc.sections:
    section.top_margin = Cm(2.5)
    section.bottom_margin = Cm(2.0)
    section.left_margin = Cm(2.5)
    section.right_margin = Cm(2.5)

# ── Helper Functions ──
def add_colored_line(doc, color_hex='003366'):
    """Add a horizontal colored line"""
    p = doc.add_paragraph()
    pPr = p._p.get_or_add_pPr()
    pBdr = parse_xml(f'<w:pBdr {nsdecls("w")}><w:bottom w:val="single" w:sz="12" w:space="1" w:color="{color_hex}"/></w:pBdr>')
    pPr.append(pBdr)
    p.paragraph_format.space_after = Pt(6)
    return p

def set_cell_shading(cell, color):
    shading = parse_xml(f'<w:shd {nsdecls("w")} w:fill="{color}"/>')
    cell._tc.get_or_add_tcPr().append(shading)

def add_table_from_md(doc, header_row, data_rows):
    """Create a styled table from markdown table data"""
    table = doc.add_table(rows=1 + len(data_rows), cols=len(header_row))
    table.style = 'Table Grid'
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    
    # Header
    for i, h in enumerate(header_row):
        cell = table.rows[0].cells[i]
        cell.text = h.strip()
        for p in cell.paragraphs:
            p.alignment = WD_ALIGN_PARAGRAPH.CENTER
            for run in p.runs:
                run.font.bold = True
                run.font.size = Pt(10)
                run.font.color.rgb = WIT
                run.font.name = 'Calibri'
        set_cell_shading(cell, '003366')
    
    # Data rows
    for r_idx, row in enumerate(data_rows):
        for c_idx, val in enumerate(row):
            cell = table.rows[r_idx + 1].cells[c_idx]
            cell.text = val.strip()
            for p in cell.paragraphs:
                for run in p.runs:
                    run.font.size = Pt(10)
                    run.font.name = 'Calibri'
            if r_idx % 2 == 1:
                set_cell_shading(cell, 'F2F6FA')
    
    doc.add_paragraph()  # spacing after table
    return table

def process_inline_formatting(paragraph, text):
    """Process bold (**text**), italic (*text*), and code (`text`) in text"""
    # Bold
    parts = re.split(r'(\*\*.*?\*\*)', text)
    for part in parts:
        if part.startswith('**') and part.endswith('**'):
            run = paragraph.add_run(part[2:-2])
            run.bold = True
        else:
            # Check for inline code
            code_parts = re.split(r'(`[^`]+`)', part)
            for cp in code_parts:
                if cp.startswith('`') and cp.endswith('`'):
                    run = paragraph.add_run(cp[1:-1])
                    run.font.name = 'Consolas'
                    run.font.size = Pt(9.5)
                else:
                    if cp:
                        paragraph.add_run(cp)

def process_markdown_file(doc, filepath, skip_first_title=False):
    """Parse markdown and convert to DOCX paragraphs, tables, and headings"""
    with open(filepath, 'r', encoding='utf-8') as f:
        lines = f.readlines()
    
    in_table = False
    table_header = []
    table_data = []
    first_h1 = True
    skip_first = skip_first_title
    
    i = 0
    while i < len(lines):
        line = lines[i].rstrip()
        
        # Skip empty lines in tables
        if in_table and not line.strip():
            i += 1
            continue
        
        # Table detection
        if '|' in line and line.strip().startswith('|'):
            if not in_table:
                in_table = True
                table_header = []
                table_data = []
            
            cells = [c.strip() for c in line.split('|')[1:-1]]
            
            # Skip separator line (|---|---|)
            if all(re.match(r'^[-:]+$', c) for c in cells):
                i += 1
                continue
            
            if not table_header:
                table_header = cells
            else:
                table_data.append(cells)
            i += 1
            continue
        elif in_table:
            # End of table
            if table_header and table_data:
                add_table_from_md(doc, table_header, table_data)
            in_table = False
            table_header = []
            table_data = []
        
        # Skip empty lines
        if not line.strip():
            i += 1
            continue
        
        # Headings
        if line.startswith('# '):
            if skip_first and first_h1:
                first_h1 = False
                i += 1
                continue
            p = doc.add_heading(line[2:].strip(), level=1)
            add_colored_line(doc)
            i += 1
            continue
        
        if line.startswith('## '):
            p = doc.add_heading(line[3:].strip(), level=2)
            i += 1
            continue
        
        if line.startswith('### '):
            p = doc.add_heading(line[4:].strip(), level=3)
            i += 1
            continue
        
        if line.startswith('#### '):
            p = doc.add_heading(line[5:].strip(), level=4)
            i += 1
            continue
        
        # Horizontal rule
        if line.strip() in ('---', '***', '___'):
            add_colored_line(doc, 'CCCCCC')
            i += 1
            continue
        
        # Bullet lists
        if line.strip().startswith('- ') or line.strip().startswith('* '):
            text = re.sub(r'^[\s\-\*]+ ', '', line)
            # Check indent level
            indent_level = len(line) - len(line.lstrip())
            p = doc.add_paragraph(style='List Bullet')
            p.clear()
            process_inline_formatting(p, text.strip())
            p.paragraph_format.left_indent = Cm(1.0 + (indent_level // 2) * 0.5)
            i += 1
            continue
        
        # Numbered lists
        m = re.match(r'^(\s*)(\d+)[\.\)]\s+(.*)', line)
        if m:
            indent = len(m.group(1))
            text = m.group(3)
            p = doc.add_paragraph(style='List Number')
            p.clear()
            process_inline_formatting(p, text.strip())
            p.paragraph_format.left_indent = Cm(1.0 + (indent // 2) * 0.5)
            i += 1
            continue
        
        # Letter lists (a. b. c.)
        m = re.match(r'^(\s*)([a-z])[\.\)]\s+(.*)', line)
        if m:
            text = m.group(3)
            p = doc.add_paragraph(style='List Bullet')
            p.clear()
            run = p.add_run(text.strip())
            run.font.size = Pt(11)
            p.paragraph_format.left_indent = Cm(1.5)
            i += 1
            continue
        
        # Regular paragraph
        p = doc.add_paragraph()
        process_inline_formatting(p, line.strip())
        i += 1
    
    # Flush remaining table
    if in_table and table_header and table_data:
        add_table_from_md(doc, table_header, table_data)

# ── Cover Page ──
for _ in range(6):
    doc.add_paragraph()

# Title
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run('REACH KENNISDOSSIER')
run.font.size = Pt(32)
run.font.bold = True
run.font.color.rgb = BLAUW
run.font.name = 'Calibri'

# Subtitle
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run('Verordening (EG) 1907/2006')
run.font.size = Pt(18)
run.font.color.rgb = RGBColor(0x00, 0x55, 0x88)
run.font.name = 'Calibri'

add_colored_line(doc, 'FF6600')

# Company
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run('Phoenix Metals B.V.')
run.font.size = Pt(20)
run.font.bold = True
run.font.color.rgb = BLAUW
run.font.name = 'Calibri'

p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run('Vanadiumextractie uit Secundaire Grondstoffen')
run.font.size = Pt(14)
run.font.color.rgb = RGBColor(0x66, 0x66, 0x66)
run.font.name = 'Calibri'

for _ in range(4):
    doc.add_paragraph()

# Meta info
meta_items = [
    ('Versie', '2.0'),
    ('Datum', '26 april 2026'),
    ('Classificatie', 'Vertrouwelijk'),
    ('Opdrachtgever', 'Phoenix Metals B.V.'),
    ('Auteur', 'Kas — HSEQ Intelligence Unit'),
    ('Documenttype', 'Educatief Referentiedocument'),
]

table = doc.add_table(rows=len(meta_items), cols=2)
table.style = 'Table Grid'
table.alignment = WD_TABLE_ALIGNMENT.CENTER
for idx, (label, value) in enumerate(meta_items):
    cell_l = table.rows[idx].cells[0]
    cell_r = table.rows[idx].cells[1]
    cell_l.text = label
    cell_r.text = value
    for p in cell_l.paragraphs:
        for run in p.runs:
            run.font.bold = True
            run.font.size = Pt(10)
            run.font.name = 'Calibri'
            run.font.color.rgb = WIT
    for p in cell_r.paragraphs:
        for run in p.runs:
            run.font.size = Pt(10)
            run.font.name = 'Calibri'
    set_cell_shading(cell_l, '003366')
    if idx % 2 == 1:
        set_cell_shading(cell_r, 'F2F6FA')

# Page break
doc.add_page_break()

# ── Process Deel 1 ──
process_markdown_file(doc, DEEL1, skip_first_title=True)

# ── Process Deel 2 ──
process_markdown_file(doc, DEEL2, skip_first_title=True)

# ── Footer ──
section = doc.sections[0]
footer = section.footer
footer.is_linked_to_previous = False
p = footer.paragraphs[0]
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run('REACH Kennisdossier v2.0 — Phoenix Metals B.V. — Vertrouwelijk')
run.font.size = Pt(8)
run.font.color.rgb = RGBColor(0x99, 0x99, 0x99)
run.font.name = 'Calibri'

# ── Save ──
doc.save(OUTPUT)
print(f"✅ Opgeslagen: {OUTPUT}")

# Stats
total_words = 0
for p in doc.paragraphs:
    total_words += len(p.text.split())
for t in doc.tables:
    for row in t.rows:
        for cell in row.cells:
            total_words += len(cell.text.split())
print(f"Woorden: {total_words}")
print(f"Tabellen: {len(doc.tables)}")
print(f"Paragrafen: {len(doc.paragraphs)}")
