#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
06_Presentatie_Ledenontmoetingsavond.pptx
Ledenontmoetingsavond District 110 AN — 13 oktober 2026 (incl. aankondiging 2e VDG)
Stijl conform MASTER_STYLEGUIDE v1.5: Lions navy #003366 + goud, sans-serif, minimalistisch.
"""

from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.enum.shapes import MSO_SHAPE

# ---------------------------------------------------------------- constants
NAVY      = RGBColor(0x00, 0x33, 0x66)
NAVY_DARK = RGBColor(0x0A, 0x16, 0x28)
GOLD      = RGBColor(0xC9, 0xA2, 0x27)
GOLD_LT   = RGBColor(0xF0, 0xDF, 0xA8)
WHITE     = RGBColor(0xFF, 0xFF, 0xFF)
TEXT      = RGBColor(0x1F, 0x29, 0x37)
TEXT2     = RGBColor(0x37, 0x41, 0x51)
CARD_BG   = RGBColor(0xF8, 0xF9, 0xFA)
BORDER    = RGBColor(0xE5, 0xE7, 0xEB)
MUTED     = RGBColor(0xB9, 0xC4, 0xD4)

FONT = "Segoe UI"
SW, SH = Inches(13.333), Inches(7.5)
M_L = Inches(0.55)

ASSETS = "/root/projects/jg/2026-pbm-ledenontmoetingsavond-13okt/assets"
LOGO_SIG = f"{ASSETS}/logo_lions_signature.png"
LOGO_EMB = f"{ASSETS}/logo_lions_emblem.png"
OUT = "/root/projects/jg/2026-pbm-ledenontmoetingsavond-13okt/deliverables/pptx/06_Presentatie_Ledenontmoetingsavond.pptx"

prs = Presentation()
prs.slide_width, prs.slide_height = SW, SH
BLANK = prs.slide_layouts[6]

# ---------------------------------------------------------------- helpers
def add_slide():
    return prs.slides.add_slide(BLANK)

def rect(slide, x, y, w, h, fill=None, line=None, line_w=None, shape=MSO_SHAPE.RECTANGLE):
    sp = slide.shapes.add_shape(shape, x, y, w, h)
    if fill is None:
        sp.fill.background()
    else:
        sp.fill.solid(); sp.fill.fore_color.rgb = fill
    if line is None:
        sp.line.fill.background()
    else:
        sp.line.color.rgb = line
        sp.line.width = line_w or Pt(1)
    sp.shadow.inherit = False
    return sp

def text(slide, x, y, w, h, runs, size=16, color=TEXT, bold=False, align=PP_ALIGN.LEFT,
         anchor=MSO_ANCHOR.TOP, line_spacing=1.15, space_after=6):
    tb = slide.shapes.add_textbox(x, y, w, h)
    tf = tb.text_frame
    tf.word_wrap = True
    tf.vertical_anchor = anchor
    tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = 0
    if isinstance(runs, str):
        runs = [runs]
    first = True
    for para in runs:
        p = tf.paragraphs[0] if first else tf.add_paragraph()
        first = False
        p.alignment = align
        p.line_spacing = line_spacing
        p.space_after = Pt(space_after)
        if isinstance(para, str):
            para = [(para, bold, color, size)]
        for (t, b, c, s) in para:
            r = p.add_run(); r.text = t
            r.font.name = FONT; r.font.size = Pt(s); r.font.bold = b; r.font.color.rgb = c
    return tb

def bullets_raw(slide, x, y, w, h, paras, size=13, gap=4):
    out = []
    for p in paras:
        if isinstance(p, str):
            out.append([("• ", False, GOLD, size), (p, False, TEXT, size)])
        else:
            out.append([("• ", False, GOLD, size)] + list(p))
    text(slide, x, y, w, h, out, size=size, space_after=gap, line_spacing=1.12)

def footer(slide, num=None, total=16):
    rect(slide, 0, SH - Inches(0.34), SW, Inches(0.34), fill=NAVY_DARK)
    text(slide, M_L, SH - Inches(0.29), Inches(8), Inches(0.25),
         "Lions District 110 AN  •  Ledenontmoetingsavond  •  13 oktober 2026",
         size=9, color=MUTED)
    if num is not None:
        text(slide, Inches(12.2), SH - Inches(0.29), Inches(0.8), Inches(0.25),
             f"{num} / {total}", size=9, color=MUTED, align=PP_ALIGN.RIGHT)

def header(slide, kicker, title, num=None, total=16):
    rect(slide, 0, 0, SW, Inches(1.18), fill=NAVY)
    rect(slide, 0, Inches(1.18), SW, Pt(3.2), fill=GOLD)
    text(slide, M_L, Inches(0.16), Inches(9.5), Inches(0.3), kicker.upper(),
         size=11.5, color=GOLD_LT, bold=True)
    text(slide, M_L, Inches(0.42), Inches(9.6), Inches(0.7), title,
         size=26, color=WHITE, bold=True)
    try:
        slide.shapes.add_picture(LOGO_EMB, Inches(12.15), Inches(0.14), height=Inches(0.9))
    except Exception:
        pass
    footer(slide, num, total)

def card(slide, x, y, w, h, title, body_lines, accent=GOLD, body_size=12.5):
    rect(slide, x, y, w, h, fill=CARD_BG, line=BORDER, line_w=Pt(1))
    rect(slide, x, y, Pt(4), h, fill=accent)
    text(slide, x + Inches(0.22), y + Inches(0.16), w - Inches(0.44), Inches(0.35),
         title, size=14, color=NAVY, bold=True)
    body = []
    for ln in body_lines:
        if isinstance(ln, tuple):
            body.append([(f"{ln[0]}: ", True, TEXT2, body_size), (ln[1], False, TEXT, body_size)])
        else:
            body.append(ln)
    if body:
        bullets_raw(slide, x + Inches(0.24), y + Inches(0.58), w - Inches(0.48), h - Inches(0.72),
                    body, size=body_size, gap=4)

# ================================================================ SLIDE 1 — Titel
s = add_slide()
rect(s, 0, 0, SW, SH, fill=NAVY)
rect(s, 0, 0, SW, Inches(0.18), fill=GOLD)
rect(s, 0, SH - Inches(0.18), SW, Inches(0.18), fill=GOLD)
rect(s, Inches(9.1), Inches(1.05), Inches(3.55), Inches(5.4), fill=NAVY_DARK,
     shape=MSO_SHAPE.ROUNDED_RECTANGLE)
try:
    s.shapes.add_picture(LOGO_EMB, Inches(10.0), Inches(1.85), height=Inches(1.7))
except Exception:
    pass
text(s, Inches(9.1), Inches(3.8), Inches(3.55), Inches(0.6), "WE SERVE",
     size=22, color=GOLD, bold=True, align=PP_ALIGN.CENTER)
text(s, Inches(0.9), Inches(1.15), Inches(7.8), Inches(0.4),
     "LIONS CLUBS INTERNATIONAL  •  MULTIPLE DISTRICT 110 NEDERLAND",
     size=12, color=GOLD_LT, bold=True)
text(s, Inches(0.9), Inches(1.75), Inches(7.8), Inches(1.9),
     ["District 110 AN", "Ledenontmoetingsavond"], size=40, color=WHITE, bold=True, line_spacing=1.05)
rect(s, Inches(0.93), Inches(3.62), Inches(1.6), Pt(3.5), fill=GOLD)
text(s, Inches(0.9), Inches(3.85), Inches(7.8), Inches(0.6),
     "Dinsdag 13 oktober 2026  •  Aanvang 19:00 uur", size=18, color=GOLD_LT, bold=True)
text(s, Inches(0.9), Inches(4.75), Inches(7.6), Inches(1.5), [
     [("Welkom namens District Governor ", False, WHITE, 15),
      ("Arjan van Ommen", True, GOLD_LT, 15)],
     [("“Samen bouwen we aan een vitaal district — van club naar club, van lid tot lid.”",
       False, RGBColor(0xD7, 0xDE, 0xE8), 14)],
 ], line_spacing=1.25, space_after=8)
try:
    s.shapes.add_picture(LOGO_SIG, Inches(0.9), Inches(6.05), height=Inches(1.05))
except Exception:
    pass

# ================================================================ SLIDE 2 — Agenda
s = add_slide()
header(s, "Programma", "Agenda van de avond", num=2)
agenda = [
    ("19:00", "Opening en welkom", "Door District Governor Arjan van Ommen"),
    ("19:15", "District update 2025-2026", "Werkplan, prestaties en ledenontwikkeling"),
    ("19:40", "Aankondiging 2e Vice District Governor", "Benoeming, motivatie en visie 2026-2027"),
    ("20:00", "Clubvitaliteit en ledengroei", "Trends, vitaliteitsprogramma en good practices"),
    ("20:20", "Service, jeugd en ontwikkeling", "Projecten, LCIF, jeugduitwisseling, training, kalender"),
    ("20:50", "Q&A en netwerken", "Open discussie en informele ontmoeting"),
]
y = Inches(1.55)
for t, titel, sub in agenda:
    rect(s, M_L, y, Inches(1.15), Inches(0.62), fill=NAVY, shape=MSO_SHAPE.ROUNDED_RECTANGLE)
    text(s, M_L, y + Inches(0.13), Inches(1.15), Inches(0.36), t, size=15, color=GOLD_LT,
         bold=True, align=PP_ALIGN.CENTER)
    rect(s, Inches(1.9), y, Inches(10.85), Inches(0.62), fill=CARD_BG, line=BORDER, line_w=Pt(0.75))
    rect(s, Inches(1.9), y, Pt(3.5), Inches(0.62), fill=GOLD)
    text(s, Inches(2.15), y + Inches(0.06), Inches(10.4), Inches(0.5),
         [[(titel + "  ", True, NAVY, 14.5), ("· " + sub, False, TEXT2, 12.5)]])
    y += Inches(0.78)

# ================================================================ SLIDE 3 — District update
s = add_slide()
header(s, "District update", "District 110 AN — stand van zaken 2025-2026", num=3)
card(s, M_L, Inches(1.55), Inches(3.95), Inches(2.75), "Werkplan: voortgang", [
     "Clubvitaliteit en ledengroei — op koers",
     "District governance versterkt (Protocol MD-Organen V1.0)",
     "GMT-ondersteuning naar alle herziene zones",
     "Jeugduitwisseling en serviceprojecten verbinden"])
card(s, Inches(4.7), Inches(1.55), Inches(3.95), Inches(2.75), "Belangrijkste prestaties", [
     "Kabinet 2025-2026 definitief per 11 april 2025",
     "Zone-indeling herzien en gepresenteerd",
     "Club Vitaliteit Programma v4 (april 2025) gelanceerd",
     "Ledenbeleid GMT 2025 landelijk vastgesteld"])
card(s, Inches(8.85), Inches(1.55), Inches(3.95), Inches(2.75), "Ledenontwikkeling", [
     "5-jaarstrend: groeiende én krimpende clubs in beeld",
     "Club health assessment uitgevoerd",
     "Diversiteit als doelstelling uit vitaliteitsprogramma",
     "Actuele cijfers: officiële districtrapportages"])
rect(s, M_L, Inches(4.55), Inches(12.25), Inches(2.3), fill=CARD_BG, line=BORDER, line_w=Pt(1))
rect(s, M_L, Inches(4.55), Pt(4), Inches(2.3), fill=GOLD)
text(s, M_L + Inches(0.25), Inches(4.7), Inches(11.8), Inches(0.4),
     "Kerncijfers en borging", size=15, color=NAVY, bold=True)
kpis = [("CLUBS", "Netwerk in herziene zone-indeling"),
        ("DOEL", "Ledengroei via GMT & Club Vitaliteit v4"),
        ("BORGING", "Meerjarenbeleidsplan MD110 2024-2030"),
        ("VOLGEND JAAR", "Werkplan AN 2026-2027 (concept klaar)")]
kx = M_L + Inches(0.3)
for kop, val in kpis:
    text(s, kx, Inches(5.25), Inches(2.9), Inches(1.3),
         [[(kop, True, GOLD, 12)], [(val, False, TEXT, 12.5)]], space_after=4)
    kx += Inches(3.0)

# ================================================================ SLIDE 4 — Ledenontwikkeling
s = add_slide()
header(s, "Ledenontwikkeling", "Trends, club health en diversiteit", num=4)
gx, gy, gw, gh = M_L, Inches(1.6), Inches(7.1), Inches(4.7)
rect(s, gx, gy, gw, gh, fill=CARD_BG, line=BORDER, line_w=Pt(1))
text(s, gx + Inches(0.25), gy + Inches(0.15), Inches(6.6), Inches(0.35),
     "Ledenontwikkeling 110 AN — 5-jaar trend (weergave indicatief)", size=14, color=NAVY, bold=True)
base_y = gy + Inches(4.05)
bars = [("2021-22", 0.62), ("2022-23", 0.58), ("2023-24", 0.60), ("2024-25", 0.66), ("2025-26", 0.72)]
max_h = Inches(2.5)
bx = gx + Inches(0.75)
rect(s, gx + Inches(0.55), base_y, Inches(6.2), Pt(1.2), fill=BORDER)
for lbl, frac in bars:
    bh = Emu(int(max_h * frac))
    rect(s, bx, base_y - bh, Inches(0.85), bh, fill=NAVY)
    text(s, bx - Inches(0.1), base_y + Inches(0.08), Inches(1.05), Inches(0.3), lbl,
         size=11, color=TEXT2, align=PP_ALIGN.CENTER)
    bx += Inches(1.18)
text(s, gx + Inches(0.25), gy + Inches(4.35), Inches(6.6), Inches(0.3),
     "Definitieve cijfers: 5 Year Membership Trend-rapportage (Lions database).",
     size=9.5, color=MUTED)
# rechterkolom
card(s, Inches(8.0), Inches(1.6), Inches(4.78), Inches(1.45), "Club health assessment", [
     "Vitaliteitsmeting per club uitgevoerd",
     "Extra aandacht voor krimpende clubs via zones"])
card(s, Inches(8.0), Inches(3.2), Inches(4.78), Inches(1.45), "5-jaar trendanalyse", [
     "Groeiende en krimpende clubs in kaart",
     "Input voor doelgerichte zonebenadering"])
card(s, Inches(8.0), Inches(4.8), Inches(4.78), Inches(1.5), "Diversiteit en inclusiviteit", [
     "Membership types & gender per club gemeten",
     "Doelstellingen uit Club Vitaliteit v4"])

# ================================================================ SLIDE 5 — 2e VDG aankondiging
s = add_slide()
rect(s, 0, 0, SW, SH, fill=NAVY)
rect(s, 0, 0, SW, Inches(0.18), fill=GOLD)
rect(s, 0, SH - Inches(0.18), SW, Inches(0.18), fill=GOLD)
try:
    s.shapes.add_picture(LOGO_EMB, Inches(11.9), Inches(0.5), height=Inches(1.3))
except Exception:
    pass
text(s, Inches(0.9), Inches(1.0), Inches(8), Inches(0.4), "MOMENT VAN DE AVOND",
     size=13, color=GOLD_LT, bold=True)
text(s, Inches(0.9), Inches(1.45), Inches(9.5), Inches(1.0),
     "Aankondiging 2e Vice District Governor", size=34, color=WHITE, bold=True)
rect(s, Inches(0.93), Inches(2.45), Inches(1.6), Pt(3.5), fill=GOLD)
text(s, Inches(0.9), Inches(2.8), Inches(5.9), Inches(2.2), [
     [("Naam kandidaat: ", True, GOLD_LT, 16), ("[naam — nader te bepalen door DG]", False, WHITE, 16)],
     [("Benoemd door: ", True, GOLD_LT, 16), ("District Governor Arjan van Ommen", False, WHITE, 16)],
     [("Grondslag: ", True, GOLD_LT, 16), ("Statuten MD110 Nederland § 4.2", False, WHITE, 16)],
     [("Verkiezing: ", True, GOLD_LT, 16), ("Districtsconventie, conform Election Guidelines LCI", False, WHITE, 16)],
 ], space_after=10, line_spacing=1.2)
rect(s, Inches(7.2), Inches(2.8), Inches(5.3), Inches(3.3), fill=NAVY_DARK,
     shape=MSO_SHAPE.ROUNDED_RECTANGLE)
text(s, Inches(7.5), Inches(3.05), Inches(4.7), Inches(0.4), "Motivatie", size=16, color=GOLD, bold=True)
text(s, Inches(7.5), Inches(3.55), Inches(4.7), Inches(2.4), [
     "Ervaring in club- en districtbestuur",
     "Aantoonbare affiniteit met ledengroei",
     "Beschikbaar voor traject 2e VDG → 1e VDG → DG",
     "Onderschrijft ethische standaarden LCI",
 ], size=13.5, color=RGBColor(0xD7, 0xDE, 0xE8), space_after=7)
text(s, Inches(0.9), Inches(5.6), Inches(5.9), Inches(1.2), [
     [("Visie (kern): ", True, GOLD_LT, 14),
      ("“Een verbindend en groeiend district, met vitale clubs als fundament voor service aan de samenleving.”",
       False, RGBColor(0xD7, 0xDE, 0xE8), 14)]], line_spacing=1.25)

# ================================================================ SLIDE 6 — Visie en plannen 2e VDG
s = add_slide()
header(s, "2e VDG", "Visie en plannen voor 2026-2027", num=6)
card(s, M_L, Inches(1.55), Inches(3.95), Inches(2.9), "Prioriteiten 2026-2027", [
     "Ledengroei en -behoud via GMT-agenda",
     "Club Vitaliteit Programma v4 in elke zone",
     "Onboarding en mentoring van nieuwe leden",
     "Zichtbare serviceimpact per club"])
card(s, Inches(4.7), Inches(1.55), Inches(3.95), Inches(2.9), "Samenwerking met kabinet", [
     "Afstemming conform Protocol MD-Organen § 3.1",
     "Verbinding met GMT, GLT en zonevoorzitters",
     "Voorbereiding Taakverdeling GR 2026-2027",
     "Inwerktraject en kabinetstraining"])
card(s, Inches(8.85), Inches(1.55), Inches(3.95), Inches(2.9), "Ambities voor het district", [
     "Iedere club in beeld via health assessment",
     "Meer diversiteit in lidmaatschap",
     "Jeugd en service structureel verweven",
     "Kwaliteitsborging van districtsevenementen"])
rect(s, M_L, Inches(4.75), Inches(12.25), Inches(2.1), fill=CARD_BG, line=BORDER, line_w=Pt(1))
rect(s, M_L, Inches(4.75), Pt(4), Inches(2.1), fill=GOLD)
text(s, M_L + Inches(0.25), Inches(4.9), Inches(11.8), Inches(0.4),
     "Meerjarig bestuursmodel (opeenvolgend, conform LCI-structuur)", size=15, color=NAVY, bold=True)
steps = [("2026-2027", "2e Vice District Governor"), ("2027-2028", "1e Vice District Governor"),
         ("2028-2029", "District Governor")]
sx = M_L + Inches(0.4)
for i, (jr, rol) in enumerate(steps):
    rect(s, sx, Inches(5.45), Inches(3.5), Inches(1.1), fill=NAVY, shape=MSO_SHAPE.ROUNDED_RECTANGLE)
    text(s, sx, Inches(5.6), Inches(3.5), Inches(0.3), jr, size=12, color=GOLD_LT, bold=True,
         align=PP_ALIGN.CENTER)
    text(s, sx, Inches(5.95), Inches(3.5), Inches(0.4), rol, size=14, color=WHITE, bold=True,
         align=PP_ALIGN.CENTER)
    if i < 2:
        text(s, sx + Inches(3.5), Inches(5.75), Inches(0.5), Inches(0.5), "→", size=20,
             color=GOLD, bold=True, align=PP_ALIGN.CENTER)
    sx += Inches(4.0)

# ================================================================ SLIDE 7 — Club vitaliteit
s = add_slide()
header(s, "Clubvitaliteit", "Club Vitaliteit Programma v4", num=7)
card(s, M_L, Inches(1.55), Inches(3.95), Inches(2.6), "Kerninitiatieven", [
     "Inclusiviteit en diversiteit als vast agendapunt",
     "Verbeterde onboarding van nieuwe leden",
     "Betrokkenheid van actieve leden versterken",
     "Jaarlijkse vitaliteitsmeting per club"])
card(s, Inches(4.7), Inches(1.55), Inches(3.95), Inches(2.6), "Good practices", [
     "Persoonlijke uitnodiging werkt het best",
     "Gestructureerde onboarding verhoogt behoud",
     "Mentorprogramma's volgens Ledenbeleid GMT",
     "Clubgood practices vanavond gedeeld"])
card(s, Inches(8.85), Inches(1.55), Inches(3.95), Inches(2.6), "Beschikbare ondersteuning", [
     "GMT-team en zonevoorzitters als eerste lijn",
     "Districtsmaterialen en modules vitaliteit",
     "Trainingen en intervisie op districtniveau",
     "Ondersteuning op maat bij krimpende clubs"])
rect(s, M_L, Inches(4.45), Inches(12.25), Inches(2.4), fill=NAVY, shape=MSO_SHAPE.ROUNDED_RECTANGLE)
text(s, M_L + Inches(0.35), Inches(4.7), Inches(11.6), Inches(0.4),
     "Vitaliteitscyclus — doorlopend en meetbaar", size=15, color=GOLD, bold=True)
cyc = ["Meten", "Analyseren", "Actieplan", "Begeleiden", "Evalueren"]
cx = M_L + Inches(0.45)
for i, c in enumerate(cyc):
    rect(s, cx, Inches(5.35), Inches(2.1), Inches(0.95), fill=NAVY_DARK,
         shape=MSO_SHAPE.ROUNDED_RECTANGLE)
    text(s, cx, Inches(5.65), Inches(2.1), Inches(0.4), c, size=14, color=GOLD_LT, bold=True,
         align=PP_ALIGN.CENTER)
    if i < len(cyc) - 1:
        text(s, cx + Inches(2.1), Inches(5.6), Inches(0.35), Inches(0.5), "→", size=16,
             color=GOLD, bold=True, align=PP_ALIGN.CENTER)
    cx += Inches(2.45)
text(s, M_L + Inches(0.35), Inches(6.4), Inches(11.6), Inches(0.3),
     "Gebaseerd op Club Vitaliteit Programma v4 (april 2025) en Ledenbeleid GMT Lions Nederland 2025.",
     size=9.5, color=MUTED)

# ================================================================ SLIDE 8 — Service projecten
s = add_slide()
header(s, "Service", "Serviceprojecten en LCIF", num=8)
card(s, M_L, Inches(1.55), Inches(5.95), Inches(2.6), "Highlightprojecten district", [
     "Sight/diabetes- en gehoordrelevante activiteiten",
     "Jeugd- en onderwijsprojecten per zone",
     "Lokale clubprojecten verbonden via districtsthema's",
     "Resultaten zichtbaar via LCI Global Dashboard"])
card(s, Inches(6.85), Inches(1.55), Inches(5.95), Inches(2.6), "LCIF grant-mogelijkheden", [
     "District & Club Community Impact Grants",
     "Matching grants voor grotere projecten",
     "Criteria en deadlines via lcif.org en GMT",
     "Hulp bij aanvragen via het kabinet"])
card(s, M_L, Inches(4.35), Inches(12.25), Inches(2.5), "Planning volgend jaar", [
     ("Q4-2026", "Projectregistratie en impactrapportage in LCI-dashboards"),
     ("Q1-2027", "LCIF-aanvragen voorstellen indienen bij kabinet"),
     ("Voorjaar 2027", "Districtsconventie: projectmarkt en awarduitreiking"),
     ("Doorlopend", "Zonegewijze ondersteuning en good-practice-uitwisseling")], body_size=13)
