#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""JvG Consultancy — gedeelde DOCX/XLSX builder (Asbest Golden Standard formaat).

DSL: document = lijst items:
  ("h1", txt) ("h2", txt) ("h3", txt) ("p", txt) ("pb", lead, txt)
  ("b", txt) ("bb", lead, txt) ("n", txt)            # bullet / numbered
  ("t", headers, rows)                                # tabel
  ("tc", headers, rows, color_col)                    # tabel met statuskleur
  ("page",)                                           # paginabreak
"""
import os
from docx import Document
from docx.shared import Pt, Cm, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_BREAK
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.enum.section import WD_SECTION
from docx.oxml.ns import qn
from docx.oxml import OxmlElement

NAVY = RGBColor(0x00, 0x33, 0x66)
NAVY_HEX = "003366"
GREEN_HEX, ORANGE_HEX, RED_HEX = "00A859", "F59E0B", "EF4444"
GREY_HEX = "F2F2F2"

ASBEST_DIR = "/root/projects/jg/HSEQ/2026-08-17-asbest-audit-003059-verse"
LOGO_CANDIDATES = [
    "/root/projects/jg/2026-audit-koole-mercury-003057/working/assets/jvg-logo-small-upgrade.png",
    "/root/projects/jg/assets/branding/jvg-logo-small.png",
]


def _logo():
    for c in LOGO_CANDIDATES:
        if os.path.exists(c):
            return c
    return None


def _shade(cell, hex_color):
    shd = OxmlElement("w:shd")
    shd.set(qn("w:val"), "clear")
    shd.set(qn("w:color"), "auto")
    shd.set(qn("w:fill"), hex_color)
    cell._tc.get_or_add_tcPr().append(shd)


def _cell(c, text, bold=False, color="1F2937", size=9.5, fill=None):
    c.text = ""
    first = True
    for line in str(text).split("\n"):
        p = c.paragraphs[0] if first else c.add_paragraph()
        first = False
        r = p.add_run(line)
        r.bold = bold
        r.font.size = Pt(size)
        r.font.name = "Calibri"
        r.font.color.rgb = RGBColor.from_string(color)
    if fill:
        _shade(c, fill)


def status_style(val):
    v = str(val)
    if v.startswith(("P1", "HOOG", "ROOD", "ONTBREEKT", "CRITICAL")):
        return RED_HEX, True
    if v.startswith(("P2", "MIDDEN", "ORANJE", "AFWIJK", "DEELS")):
        return ORANGE_HEX, True
    if v.startswith(("Conform", "GROEN", "LAAG", "CONFORM")):
        return GREEN_HEX, True
    return None, False


def build_docx(items, meta, doc=None):
    """meta: title, subtitle, sub2, refline, baselines, footer, logo(bool)."""
    doc = doc or Document()
    st = doc.styles["Normal"]
    st.font.name = "Calibri"
    st.font.size = Pt(11)
    st.element.rPr.rFonts.set(qn("w:eastAsia"), "Calibri")
    for name, size in (("Heading 1", 16), ("Heading 2", 13), ("Heading 3", 11)):
        h = doc.styles[name]
        h.font.name = "Calibri"
        h.font.size = Pt(size)
        h.font.color.rgb = NAVY
        h.font.bold = True
    for s in doc.sections:
        s.top_margin, s.bottom_margin = Cm(2.2), Cm(2.0)
        s.left_margin, s.right_margin = Cm(2.4), Cm(2.4)

    # header / footer
    sec = doc.sections[0]
    hdr = sec.header.paragraphs[0]
    hdr.alignment = WD_ALIGN_PARAGRAPH.RIGHT
    logo = _logo() if meta.get("logo", True) else None
    if logo:
        hdr.add_run().add_picture(logo, width=Cm(2.0))
    else:
        r = hdr.add_run("JvG Consultancy")
        r.bold = True
        r.font.color.rgb = NAVY
    ftr = sec.footer.paragraphs[0]
    ftr.text = meta.get("footer", "JvG Consultancy — Vertrouwelijk")
    ftr.alignment = WD_ALIGN_PARAGRAPH.CENTER
    for r in ftr.runs:
        r.font.size = Pt(8)
        r.font.color.rgb = NAVY

    def para(text, bold=False, size=11, color=None, align=None, after=6, italic=False):
        p = doc.add_paragraph()
        r = p.add_run(text)
        r.bold, r.italic = bold, italic
        r.font.size = Pt(size)
        r.font.name = "Calibri"
        if color:
            r.font.color.rgb = color
        if align:
            p.alignment = align
        p.paragraph_format.space_after = Pt(after)
        return p

    # ---- titelpagina ----
    doc.add_paragraph()
    para(meta.get("doctag", "JvG CONSULTANCY"), bold=True, size=14, color=NAVY,
         align=WD_ALIGN_PARAGRAPH.CENTER, after=2)
    para(meta["title"], bold=True, size=24, color=NAVY,
         align=WD_ALIGN_PARAGRAPH.CENTER, after=2)
    if meta.get("subtitle"):
        para(meta["subtitle"], bold=True, size=16, color=NAVY,
             align=WD_ALIGN_PARAGRAPH.CENTER, after=2)
    if meta.get("sub2"):
        para(meta["sub2"], size=12, align=WD_ALIGN_PARAGRAPH.CENTER, after=16)
    if meta.get("refline"):
        para(meta["refline"], size=10, align=WD_ALIGN_PARAGRAPH.CENTER, after=4)
    if meta.get("refline2"):
        para(meta["refline2"], size=10, align=WD_ALIGN_PARAGRAPH.CENTER, after=4)
    para("Status: Definitief — Vertrouwelijk", size=10, italic=True,
         align=WD_ALIGN_PARAGRAPH.CENTER, after=20)

    for it in items:
        kind = it[0]
        if kind == "h1":
            doc.add_heading(it[1], level=1)
        elif kind == "h2":
            doc.add_heading(it[1], level=2)
        elif kind == "h3":
            doc.add_heading(it[1], level=3)
        elif kind == "p":
            para(it[1])
        elif kind == "pi":  # italic small note
            para(it[1], size=9.5, italic=True, after=4)
        elif kind == "pb":  # bold lead + text
            p = doc.add_paragraph()
            r1 = p.add_run(it[1] + " ")
            r1.bold = True
            r2 = p.add_run(it[2])
            for r in (r1, r2):
                r.font.size = Pt(11)
                r.font.name = "Calibri"
            p.paragraph_format.space_after = Pt(6)
        elif kind == "b":
            p = doc.add_paragraph(it[1], style="List Bullet")
            p.paragraph_format.space_after = Pt(3)
        elif kind == "bb":
            p = doc.add_paragraph(style="List Bullet")
            r1 = p.add_run(it[1] + " ")
            r1.bold = True
            r2 = p.add_run(it[2])
            for r in (r1, r2):
                r.font.name = "Calibri"
                r.font.size = Pt(11)
            p.paragraph_format.space_after = Pt(3)
        elif kind == "n":
            p = doc.add_paragraph(it[1], style="List Number")
            p.paragraph_format.space_after = Pt(3)
        elif kind == "t":
            _table(doc, it[1], it[2])
        elif kind == "tc":
            _table(doc, it[1], it[2], color_col=it[3] if len(it) > 3 else None)
        elif kind == "page":
            doc.add_paragraph().add_run().add_break(WD_BREAK.PAGE)
    return doc


def _table(doc, headers, rows, color_col=None):
    t = doc.add_table(rows=1, cols=len(headers))
    t.style = "Table Grid"
    t.alignment = WD_TABLE_ALIGNMENT.CENTER
    for i, h in enumerate(headers):
        _cell(t.rows[0].cells[i], h, bold=True, color="FFFFFF", size=9.5, fill=NAVY_HEX)
    for row in rows:
        cells = t.add_row().cells
        for i, val in enumerate(row):
            fill, bold = (None, False)
            if color_col is not None and i == color_col:
                fill, bold = status_style(val)
                if fill is None:
                    fill = GREY_HEX
            _cell(cells[i], val, bold=bold, fill=fill)
    doc.add_paragraph().paragraph_format.space_after = Pt(2)
    return t


# ---------------- XLSX ----------------
def build_xlsx(sheets, path):
    """sheets: [(title, header_row, rows, widths)]."""
    import openpyxl
    from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
    from openpyxl.utils import get_column_letter
    wb = openpyxl.Workbook()
    wb.remove(wb.active)
    hdr_fill = PatternFill("solid", fgColor=NAVY_HEX)
    hdr_font = Font(color="FFFFFF", bold=True, size=10, name="Calibri")
    thin = Side(style="thin", color="C9CFD6")
    border = Border(left=thin, right=thin, top=thin, bottom=thin)
    fills = {
        "ROOD": PatternFill("solid", fgColor="EF4444"),
        "ORANJE": PatternFill("solid", fgColor="F59E0B"),
        "GROEN": PatternFill("solid", fgColor="00A859"),
        "P1": PatternFill("solid", fgColor="EF4444"),
        "P2": PatternFill("solid", fgColor="F59E0B"),
    }
    for title, headers, rows, widths in sheets:
        ws = wb.create_sheet(title[:31])
        ws.append(headers)
        for c in ws[1]:
            c.fill, c.font, c.border = hdr_fill, hdr_font, border
            c.alignment = Alignment(vertical="center", wrap_text=True)
        for r in rows:
            ws.append(list(r))
        for ri in range(2, ws.max_row + 1):
            for c in ws[ri]:
                c.border = border
                c.font = Font(size=10, name="Calibri")
                c.alignment = Alignment(vertical="top", wrap_text=True)
                v = str(c.value or "")
                for key, fl in fills.items():
                    if v.startswith(key):
                        c.fill = fl
                        c.font = Font(size=10, bold=True, name="Calibri")
                        break
        for i, w in enumerate(widths, start=1):
            ws.column_dimensions[get_column_letter(i)].width = w
        ws.freeze_panes = "A2"
    wb.save(path)
