#!/usr/bin/env python3
"""
Generate ZZP_Fiscale_Advisering_v1.0.docx
Project: HH&C ZZP Opstartplan
Auteur: Business Analyst via Kas (Director of Operations)
"""

from docx import Document
from docx.shared import Pt, Cm, Inches, RGBColor, Emu
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.enum.section import WD_SECTION
from docx.oxml.ns import qn, nsdecls
from docx.oxml import parse_xml
import os

# ─── Constants ────────────────────────────────────────────────────────────────

OUTPUT_PATH = "/root/projects/jg/2026-zzp-opstart-hhc/deliverables/ZZP_Fiscale_Advisering_v1.0.docx"
LOGO_PATH   = "/root/projects/jg/assets/branding/jvg-logo-white-medium.png"

# Colours
DARK_BLUE   = RGBColor(0x00, 0x33, 0x66)
BODY_GREY   = RGBColor(0x33, 0x33, 0x33)
SOURCE_GREY = RGBColor(0x66, 0x66, 0x66)
WHITE       = RGBColor(0xFF, 0xFF, 0xFF)

# Table shading XML templates
SHADE_HEADER  = 'shdHeaderCell'
SHADE_WHITE   = 'shdWhiteCell'
SHADE_ALT     = 'shdAltCell'

HEADER_SHD = parse_xml(f'<w:shd {nsdecls("w")} w:fill="003366" w:val="clear"/>')
WHITE_SHD  = parse_xml(f'<w:shd {nsdecls("w")} w:fill="FFFFFF" w:val="clear"/>')
ALT_SHD    = parse_xml(f'<w:shd {nsdecls("w")} w:fill="F8F9FA" w:val="clear"/>')

BORDER_XML = (
    f'<w:tcBorders {nsdecls("w")}>'
    '  <w:top w:val="single" w:sz="4" w:color="CCCCCC"/>'
    '  <w:left w:val="single" w:sz="4" w:color="CCCCCC"/>'
    '  <w:bottom w:val="single" w:sz="4" w:color="CCCCCC"/>'
    '  <w:right w:val="single" w:sz="4" w:color="CCCCCC"/>'
    '</w:tcBorders>'
)

# ─── Helper Functions ─────────────────────────────────────────────────────────

def set_cell_shading(cell, shd_element):
    """Apply background shading to a table cell."""
    tc_pr = cell._tc.get_or_add_tcPr()
    # Remove existing shd
    for old in tc_pr.findall(qn('w:shd')):
        tc_pr.remove(old)
    tc_pr.append(shd_element)


def set_cell_borders(cell):
    """Apply 1pt solid #CCCCCC borders to a cell."""
    tc_pr = cell._tc.get_or_add_tcPr()
    for old in tc_pr.findall(qn('w:tcBorders')):
        tc_pr.remove(old)
    tc_pr.append(parse_xml(BORDER_XML))


def style_cell_text(cell, text, *, bold=False, color=BODY_GREY, size=11,
                    alignment=WD_ALIGN_PARAGRAPH.LEFT, font_name="Calibri"):
    """Set cell text with styling."""
    cell.text = ""
    p = cell.paragraphs[0]
    p.alignment = alignment
    p.paragraph_format.space_before = Pt(2)
    p.paragraph_format.space_after = Pt(2)
    run = p.add_run(text)
    run.bold = bold
    run.font.color.rgb = color
    run.font.size = Pt(size)
    run.font.name = font_name


def add_styled_table(doc, headers, rows, col_widths=None):
    """Create a fully styled table with header row and alternating body rows."""
    num_cols = len(headers)
    table = doc.add_table(rows=1 + len(rows), cols=num_cols)
    table.alignment = WD_TABLE_ALIGNMENT.CENTER

    # Apply widths if provided
    if col_widths:
        for i, w in enumerate(col_widths):
            for row in table.rows:
                row.cells[i].width = w

    # Header row
    for i, h in enumerate(headers):
        cell = table.rows[0].cells[i]
        style_cell_text(cell, h, bold=True, color=WHITE, size=11,
                        alignment=WD_ALIGN_PARAGRAPH.CENTER)
        set_cell_shading(cell, HEADER_SHD)
        set_cell_borders(cell)

    # Body rows
    for r_idx, row_data in enumerate(rows):
        row_cells = table.rows[r_idx + 1].cells
        shd = WHITE_SHD if r_idx % 2 == 0 else ALT_SHD
        for c_idx, val in enumerate(row_data):
            is_bold = c_idx == 0 and len(row_data) > 2  # bold first col for larger tables
            style_cell_text(row_cells[c_idx], str(val), bold=is_bold,
                            color=BODY_GREY, size=11)
            set_cell_shading(row_cells[c_idx], shd)
            set_cell_borders(row_cells[c_idx])

    return table


def add_heading(doc, text, level=1):
    """Add a heading with custom styling."""
    h = doc.add_heading(text, level=level)
    for run in h.runs:
        run.font.name = "Calibri"
        run.font.color.rgb = DARK_BLUE
        if level == 1:
            run.font.size = Pt(16)
        elif level == 2:
            run.font.size = Pt(14)
        else:
            run.font.size = Pt(12)
        run.bold = True
        run.font.color.rgb = DARK_BLUE
    h.paragraph_format.space_before = Pt(14 if level == 1 else 10)
    h.paragraph_format.space_after = Pt(6)
    h.paragraph_format.line_spacing = 1.0
    return h


def add_body(doc, text, *, bold=False, italic=False, size=12, space_after=6,
             color=BODY_GREY):
    """Add a body paragraph."""
    p = doc.add_paragraph()
    run = p.add_run(text)
    run.font.name = "Calibri"
    run.font.size = Pt(size)
    run.font.color.rgb = color
    run.bold = bold
    run.italic = italic
    p.paragraph_format.line_spacing = 1.15
    p.paragraph_format.space_after = Pt(space_after)
    return p


def add_bullet(doc, text):
    """Add a bullet list item."""
    p = doc.add_paragraph(style="List Bullet")
    run = p.add_run(text)
    run.font.name = "Calibri"
    run.font.size = Pt(12)
    run.font.color.rgb = BODY_GREY
    p.paragraph_format.line_spacing = 1.15
    p.paragraph_format.space_after = Pt(3)
    return p


def add_checklist_item(doc, text):
    """Add a checklist item with □ symbol."""
    p = doc.add_paragraph()
    run = p.add_run(f"☐  {text}")
    run.font.name = "Calibri"
    run.font.size = Pt(12)
    run.font.color.rgb = BODY_GREY
    p.paragraph_format.line_spacing = 1.15
    p.paragraph_format.space_after = Pt(4)
    p.paragraph_format.left_indent = Cm(0.5)
    return p


def add_source(doc, text):
    """Add a source/reference line."""
    p = doc.add_paragraph()
    run = p.add_run(text)
    run.font.name = "Calibri"
    run.font.size = Pt(10)
    run.font.color.rgb = SOURCE_GREY
    p.paragraph_format.space_after = Pt(2)
    p.paragraph_format.line_spacing = 1.15
    return p


def add_spacer(doc, pts=6):
    """Add empty paragraph as spacer."""
    p = doc.add_paragraph()
    p.paragraph_format.space_before = Pt(0)
    p.paragraph_format.space_after = Pt(pts)
    return p


# ─── Document Setup ───────────────────────────────────────────────────────────

doc = Document()

# Core properties / metadata
doc.core_properties.title    = "ZZP Fiscale Advisering v1.0"
doc.core_properties.author   = "Business Analyst via Kas"
doc.core_properties.keywords = "ZZP; fiscaal; belastingaftrek; JvG Consultancy"
doc.core_properties.category = "Fiscaal Advies"
doc.core_properties.comments = "Project: HH&C ZZP Opstartplan"

# Default style
style = doc.styles["Normal"]
style.font.name = "Calibri"
style.font.size = Pt(12)
style.font.color.rgb = BODY_GREY
style.paragraph_format.line_spacing = 1.15
style.paragraph_format.space_after = Pt(6)

# Page margins
for section in doc.sections:
    section.top_margin    = Cm(2.54)
    section.bottom_margin = Cm(2.54)
    section.left_margin   = Cm(2.54)
    section.right_margin  = Cm(2.54)

    # ─── Header with logo ─────────────────────────────────────────────────
    header = section.header
    header.is_linked_to_previous = False
    # Clear default paragraph
    if header.paragraphs:
        header_par = header.paragraphs[0]
    else:
        header_par = header.add_paragraph()
    header_par.text = ""
    header_par.alignment = WD_ALIGN_PARAGRAPH.RIGHT

    if os.path.exists(LOGO_PATH):
        run = header_par.add_run()
        # Logo: 2.0 cm wide, maintain aspect ratio (1.115:1)
        run.add_picture(LOGO_PATH, width=Cm(2.0), height=Cm(1.79))

    # ─── Footer ───────────────────────────────────────────────────────────
    footer = section.footer
    footer.is_linked_to_previous = False
    if footer.paragraphs:
        footer_par = footer.paragraphs[0]
    else:
        footer_par = footer.add_paragraph()

    footer_par.text = ""
    footer_par.alignment = WD_ALIGN_PARAGRAPH.LEFT

    # Main footer text
    run1 = footer_par.add_run("JvG Consultancy | Safety • Governance • Advisory")
    run1.font.name = "Calibri"
    run1.font.size = Pt(9)
    run1.font.color.rgb = SOURCE_GREY

    # Tab to right for page number
    run2 = footer_par.add_run("\t\t")
    run2.font.size = Pt(9)

    # Add PAGE field
    fld_char_begin = parse_xml(f'<w:fldChar {nsdecls("w")} w:fldCharType="begin"/>')
    fld_char_end   = parse_xml(f'<w:fldChar {nsdecls("w")} w:fldCharType="end"/>')
    instr_text     = parse_xml(f'<w:instrText {nsdecls("w")} xml:space="preserve"> PAGE </w:instrText>')

    run3 = footer_par.add_run()
    run3.font.name = "Calibri"
    run3.font.size = Pt(9)
    run3.font.color.rgb = SOURCE_GREY
    run3._r.append(fld_char_begin)
    run3._r.append(instr_text)
    run3._r.append(fld_char_end)

    # Subtext line
    sub_par = footer.add_paragraph()
    sub_par.text = "Orchestration Divisie | Fiscaal Advies"
    sub_par.alignment = WD_ALIGN_PARAGRAPH.LEFT
    for r in sub_par.runs:
        r.font.name = "Calibri"
        r.font.size = Pt(8)
        r.font.color.rgb = SOURCE_GREY
    sub_par.paragraph_format.space_before = Pt(0)
    sub_par.paragraph_format.space_after = Pt(0)

    # Set tab stops for right-aligning page number
    from docx.shared import Twips
    tabs = footer_par.paragraph_format.tab_stops
    usable_width = section.page_width - section.left_margin - section.right_margin
    tabs.add_tab_stop(usable_width, WD_ALIGN_PARAGRAPH.RIGHT)


# ─── Title Page Block ─────────────────────────────────────────────────────────

# Document classification badge
classif_p = doc.add_paragraph()
classif_p.alignment = WD_ALIGN_PARAGRAPH.RIGHT
classif_run = classif_p.add_run("VERTROUWELIJK")
classif_run.font.name = "Calibri"
classif_run.font.size = Pt(9)
classif_run.font.color.rgb = RGBColor(0xCC, 0x00, 0x00)
classif_run.bold = True
classif_p.paragraph_format.space_after = Pt(12)

# Main title
title_p = doc.add_paragraph()
title_p.alignment = WD_ALIGN_PARAGRAPH.LEFT
title_run = title_p.add_run("FISCALE ADVISERING — ZZP BELASTINGAFTREK")
title_run.font.name = "Calibri"
title_run.font.size = Pt(16)
title_run.bold = True
title_run.font.color.rgb = DARK_BLUE
title_p.paragraph_format.space_after = Pt(4)
title_p.paragraph_format.line_spacing = 1.0

# Subtitle / project line
sub_p = doc.add_paragraph()
sub_run = sub_p.add_run("Project: HH&C ZZP Opstartplan")
sub_run.font.name = "Calibri"
sub_run.font.size = Pt(13)
sub_run.font.color.rgb = DARK_BLUE
sub_p.paragraph_format.space_after = Pt(10)

# Meta info table (header block)
meta_lines = [
    ("Opdrachtgever", "Jorick van Gemert (JvG Consultancy)"),
    ("Auteur", "Business Analyst via Kas (Director of Operations)"),
    ("Versie", "1.0"),
    ("Datum", "2026-07-29"),
    ("Status", "Final"),
    ("Classificatie", "Vertrouwelijk"),
]

meta_table = doc.add_table(rows=len(meta_lines), cols=2)
meta_table.alignment = WD_TABLE_ALIGNMENT.LEFT
for i, (label, value) in enumerate(meta_lines):
    label_cell = meta_table.rows[i].cells[0]
    value_cell = meta_table.rows[i].cells[1]
    style_cell_text(label_cell, label, bold=True, color=DARK_BLUE, size=10)
    style_cell_text(value_cell, value, color=BODY_GREY, size=10)
    label_cell.width = Cm(4.0)
    value_cell.width = Cm(12.0)

add_spacer(doc, 12)

# Horizontal rule
hr_p = doc.add_paragraph()
hr_p.paragraph_format.space_before = Pt(0)
hr_p.paragraph_format.space_after = Pt(12)
p_pr = hr_p._p.get_or_add_pPr()
p_bdr = parse_xml(
    f'<w:pBdr {nsdecls("w")}>'
    '  <w:bottom w:val="single" w:sz="8" w:color="003366" w:space="1"/>'
    '</w:pBdr>'
)
p_pr.append(p_bdr)


# ─── Hoofdstuk 1: Executive Summary ───────────────────────────────────────────

add_heading(doc, "1. Executive Summary", level=1)

add_body(doc,
    "Dit advies beantwoordt drie fiscale vraagstukken voor de ZZP-structuur van "
    "Jorick van Gemert:"
)

add_body(doc,
    "1. Zakelijke aftrekposten: Jaarlijks €1.160 tot €2.060 aftrekbaar voor "
    "Ziggo, Vodafone en Featherless AI.",
    bold=False
)
add_body(doc,
    "2. Stopstrategie: Optie B aanbevolen — na 2 jaar reductie naar 1 dag/week "
    "in plaats van volledige stop."
)
add_body(doc,
    "3. Aftrekposten bij minimale ZZP: ~€260/jaar proportioneel aftrekbaar bij "
    "1 dag/week."
)

add_spacer(doc, 4)

add_body(doc,
    "Deze advisering is gebaseerd op de Nederlandse belastingwetgeving 2026 en "
    "de specifieke situatie van twee opdrachtgevers met een uurtarief van €100."
)


# ─── Hoofdstuk 2: Zakelijke Aftrekposten ──────────────────────────────────────

add_heading(doc, "2. Zakelijke Aftrekposten", level=1)

add_heading(doc, "2.1 Overzicht", level=2)

add_body(doc,
    "De volgende posten zijn aftrekbaar als zakelijke lasten van de onderneming, "
    "mits deze aantoonbaar in het belang van de onderneming worden gemaakt. "
    "Bewaar alle facturen en bankafschriften als bewijsvoering."
)

add_spacer(doc, 4)

# Table: Zakelijke aftrekposten
headers_aftrek = ["Post", "Maandbedrag", "Jaarbedrag", "Aftrekbaar %", "Aftrekbaar (€)"]
rows_aftrek = [
    ["Ziggo (internet/TV zakelijk)", "€50-80", "€600-960", "100%", "€600-960"],
    ["Vodafone (mobiel zakelijk)", "€30-50", "€360-600", "100%", "€360-600"],
    ["Featherless AI (API kosten)", "€17-42", "€200-500", "100%", "€200-500"],
    ["Totaal", "", "", "", "€1.160-2.060"],
]
add_styled_table(doc, headers_aftrek, rows_aftrek,
                 col_widths=[Cm(5.5), Cm(2.8), Cm(2.8), Cm(2.5), Cm(3.0)])

add_spacer(doc, 8)

# 2.2 Voorwaarden
add_heading(doc, "2.2 Voorwaarden voor Aftrek", level=2)

voorwaarden = [
    "De uitgaven moeten direct samenhangen met de ondernemingsactiviteiten",
    "Gemengde kosten (zakelijk + privé) moeten pro rato worden verdeeld",
    "Bewijsvoering: facturen met bedrijfsnaam, bankafschriften, urenregistratie",
    "De posten moeten worden geboekt in de winst- en verliesrekening van de onderneming",
]
for v in voorwaarden:
    add_bullet(doc, v)

add_spacer(doc, 6)

# 2.3 Praktische Toelichting
add_heading(doc, "2.3 Praktische Toelichting per Post", level=2)

add_body(doc,
    "Ziggo (Internet/TV): Zakelijk internet is essentieel voor communicatie met "
    "opdrachtgevers, facturatie en administratie. Het zakelijke deel is volledig "
    "aftrekbaar indien er een apart zakelijk abonnement is, of pro rato "
    "(bijvoorbeeld 70% zakelijk bij gemengd gebruik)."
)

add_body(doc,
    "Vodafone (Mobiel): Zakelijk mobiel gebruik voor opdrachtgevers. Bij een "
    "separaat zakelijk nummer: 100% aftrekbaar. Bij gemengd gebruik: schat "
    "60-80% zakelijk."
)

add_body(doc,
    "Featherless AI: API-kosten voor AI-tools die worden ingezet voor "
    "bedrijfsvoering (analyse, automatisering, content productie). Volledig "
    "aftrekbaar als zakelijke kosten. Bewaar de maandelijkse facturen van "
    "Featherless."
)


# ─── Hoofdstuk 3: Scenario-analyse ────────────────────────────────────────────

add_heading(doc, "3. Scenario-analyse — Stoppen vs. Behouden", level=1)

add_spacer(doc, 4)

headers_scenario = ["Aspect", "Optie A: Direct Stoppen", "Optie B: 1 Dag/Week Behouden"]
rows_scenario = [
    ["Inkomsten ZZP",          "€0",                           "~€41.600/jaar bruto"],
    ["Zakelijke aftrekposten",  "€0 (vervalt)",                 "~€260/jaar"],
    ["Administratieve last",    "Geen",                         "Minimaal (1 opdrachtgever)"],
    ["Wet DBA risico",          "Geen",                         "Laag (1 opdrachtgever)"],
    ["Flexibiliteit",           "Geen",                         "Hoog — buffer voor fluctuaties"],
    ["Pensioenopbouw ZZP",     "Stopt",                        "Doorlopend (jaarruimte)"],
    ["Ondernemingsstatus",      "Verval",                       "Behouden (voorkeursrecht)"],
    ["MKB-winstvrijstelling",   "Verval",                       "Behouden"],
]
add_styled_table(doc, headers_scenario, rows_scenario,
                 col_widths=[Cm(4.5), Cm(5.5), Cm(6.5)])

add_spacer(doc, 8)

# 3.1 Advies
add_heading(doc, "3.1 Advies: Optie B (AANBEVOLEN)", level=2)

add_body(doc,
    "Aanbeveling: Behoud 1 dag/week ZZP-naast-loondienst na de 2-jarige periode.",
    bold=True
)

add_body(doc, "Motivatie:", bold=True, space_after=3)

motivatie = [
    "Fiscaal voordeel: Behoud van zakelijke aftrekposten en MKB-winstvrijstelling",
    "Inkomstenbuffer: Aanvullend inkomen van ~€41.600/jaar bruto biedt financiële flexibiliteit",
    "Ondernemingsstatus: Behoud van fiscale voordelen die gepaard gaan met ondernemerschap",
    "Strategische positioning: Zichtbaarheid in de markt behouden voor toekomstige kansen",
    "Risicospreiding: Niet 100% afhankelijk van één inkomstenbron (Wintershall)",
]
for i, m in enumerate(motivatie, 1):
    add_bullet(doc, f"{i}. {m}")

add_spacer(doc, 4)

add_body(doc, "Randvoorwaarden:", bold=True, space_after=3)

randvoorwaarden = [
    "Behoud modelovereenkomst met minimaal één opdrachtgever",
    "Zorg dat de ZZP-activiteit voldoet aan het urencriterium (1.225 uur/jaar "
    "indelingsbeschikking — optioneel maar voordelig)",
    "Houd zakelijke administratie actueel (ook bij 1 dag/week)",
]
for r in randvoorwaarden:
    add_bullet(doc, r)


# ─── Hoofdstuk 4: Voorbeeldberekening ─────────────────────────────────────────

add_heading(doc, "4. Voorbeeldberekening — 1 Dag/Week", level=1)

add_body(doc,
    "Onderstaande berekening toont het fiscale effect van reductie naar "
    "1 dag/week ZZP-activiteit."
)

add_spacer(doc, 4)

headers_berek = ["Post", "Bedrag"]
rows_berek = [
    ["Bruto inkomen ZZP (1 dag/week × €100 × 8 uur × 45 weken)", "€36.000"],
    ["Ziggo zakelijk (pro rato 50%)",                             "€300-480"],
    ["Vodafone zakelijk (pro rato 50%)",                          "€180-300"],
    ["Featherless AI (pro rato 50%)",                             "€100-250"],
    ["Totale aftrekposten",                                       "€580-1.030"],
    ["Belastbare winst",                                          "≈ €34.970-35.420"],
    ["MKB-winstvrijstelling (13,5%)",                             "≈ €4.721-4.782"],
    ["Belastbare winst na vrijstelling",                          "≈ €30.188-30.637"],
]
add_styled_table(doc, headers_berek, rows_berek,
                 col_widths=[Cm(11.0), Cm(5.5)])

add_spacer(doc, 8)

add_body(doc,
    "Netto fiscus effect: De zakelijke aftrekposten leveren bij 1 dag/week een "
    "belastingbesparing van ongeveer €260 per jaar op (bij een marginaal tarief "
    "van 49,5% in de hoogste schijf).",
    italic=True
)


# ─── Hoofdstuk 5: Continuïteitsplan ───────────────────────────────────────────

add_heading(doc, "5. Continuïteitsplan (Overgangsperiode)", level=1)

add_spacer(doc, 4)

headers_tijd = ["Periode", "Activiteit", "Inkomsten ZZP", "Fiscale Focus"]
rows_tijd = [
    ["Jaar 1-2 (2026-2027)", "Volledige ZZP: 2 dagen/week", "~€72.000/jaar",
     "Maximaliseer aftrekposten, bouw reserves op"],
    ["Jaar 3 (2028)",        "Reductie: 1 dag/week",        "~€36.000/jaar",
     "Behoud structuur, evaluatie opdrachtgevers"],
    ["Jaar 4+ (2029+)",      "Evaluatie",                    "Variabel",
     "Beslissing: stoppen of behouden"],
]
add_styled_table(doc, headers_tijd, rows_tijd,
                 col_widths=[Cm(4.0), Cm(4.5), Cm(3.5), Cm(4.5)])

add_spacer(doc, 8)

# 5.1 Actiepunten
add_heading(doc, "5.1 Actiepunten per Fase", level=2)

add_body(doc, "Fase 1 (Jaar 1-2):", bold=True, color=DARK_BLUE, space_after=3)
fase1 = [
    "Stuur facturen maandelijks",
    "Houd urenregistratie bij (voor urencriterium)",
    "Boek alle zakelijke kosten direct",
    "Bouw belastingreserve: 40-45% van ZZP-inkomsten",
]
for f in fase1:
    add_bullet(doc, f)

add_spacer(doc, 4)

add_body(doc, "Fase 2 (Jaar 3):", bold=True, color=DARK_BLUE, space_after=3)
fase2 = [
    "Herzie modelovereenkomsten bij gewijzigde inzet",
    "Evalueer welke opdrachtgever te behouden (Phoenix Metals of Club of Engineers)",
    "Pas boekhouding aan naar 1 dag/week verdeling",
    "Houd belastingreserve: 40-45% (gelijk, maar over minder omvang)",
]
for f in fase2:
    add_bullet(doc, f)

add_spacer(doc, 4)

add_body(doc, "Fase 3 (Jaar 4+):", bold=True, color=DARK_BLUE, space_after=3)
fase3 = [
    "Jaarlijkse evaluatie: levert de ZZP nog voldoende op?",
    "Bij stoppen: formele onderneming beëindigen bij KvK",
    "Zorg voor correcte afwikkeling (stakingsverlies, fiscale oudedagsreserve)",
]
for f in fase3:
    add_bullet(doc, f)


# ─── Hoofdstuk 6: Compliance Checklist ────────────────────────────────────────

add_heading(doc, "6. Compliance Checklist", level=1)

add_spacer(doc, 4)

checklist = [
    "Wet DBA: Modelovereenkomst met beide opdrachtgevers (actueel)",
    "Urencriterium: 1.225 uur/jaar registreren (voorbelasting en voordeelsrechten)",
    "Boekhouding: Facturen, bankafschriften, urenregistratie up-to-date",
    "BTW aangifte: Per kwartaal (ook bij 1 dag/week)",
    "Inkomstenbelasting: Jaarlijks aangifte met winst uit onderneming (Box 1)",
    "Belastingreserve: 40-45% van ZZP-omzet opzij zetten",
    "Verzekeringen: AVB (Algemene Voorwaarden Bewaarplicht), eventueel arbeidsongeschiktheid",
    "KvK registratie: Actueel houden",
    "Zakelijke bankrekening: Scheiding privé/zakelijk",
    "Jaarrekening: Opstellen of laten opstellen door boekhouder",
]
for item in checklist:
    add_checklist_item(doc, item)


# ─── Hoofdstuk 7: Bronnen en Verwijzingen ─────────────────────────────────────

add_heading(doc, "7. Bronnen en Verwijzingen", level=1)

add_spacer(doc, 4)

bronnen = [
    "1. Belastingdienst — Ondernemers en belastingen (www.belastingdienst.nl)",
    "2. Belastingdienst — Zakelijke kosten aftrekken",
    "3. Wet DBA (Deregulering Beoordeling Arbeidsrelaties) — Rijksoverheid.nl",
    "4. MKB-winstvrijstelling — Belastingdienst.nl",
    "5. JvG Consultancy — ZZP Opstartplan v2.0 (intern document)",
]
for b in bronnen:
    add_source(doc, b)


# ─── Save ─────────────────────────────────────────────────────────────────────

os.makedirs(os.path.dirname(OUTPUT_PATH), exist_ok=True)
doc.save(OUTPUT_PATH)

file_size = os.path.getsize(OUTPUT_PATH)
print(f"✅ DOCX succesvol gegenereerd")
print(f"   Pad: {OUTPUT_PATH}")
print(f"   Grootte: {file_size:,} bytes ({file_size/1024:.1f} KB)")
