"""
generate_flyer.py — Generador de flyers Kings & Queens.

Flujo:
  1. Imagen 3 (Google AI) genera el fondo artístico.
  2. Pillow pega el logo real + texto y botones de marca encima.

Uso:
  wsl python3 projects/kings-and-queens/scripts/run.py \\
    --type promo --format story \\
    --headline "Inscripciones Abiertas" \\
    --body "Inicio: 3 de marzo\\nCupos limitados" \\
    --cta "Reservá tu lugar" \\
    --output "projects/kings-and-queens/output/flyer.png"
"""

import argparse
import sys
import os
import datetime
import math
from pathlib import Path

try:
    from PIL import Image, ImageDraw, ImageFont, ImageFilter
except ImportError:
    print("ERROR: Pillow no encontrado. Activá el venv.")
    sys.exit(1)

SCRIPTS_DIR = Path(__file__).parent
PROJECT_DIR = SCRIPTS_DIR.parent
ASSETS_DIR  = PROJECT_DIR / "assets"
FONTS_DIR   = ASSETS_DIR / "fonts"
LOGO_PATH   = ASSETS_DIR / "logo.png"
ENV_PATH    = PROJECT_DIR / ".env"

# ---------------------------------------------------------------------------
# Marca
# ---------------------------------------------------------------------------

BRAND = {
    "coral":    "#ED6D70",
    "teal":     "#73C3B4",
    "gris":     "#596E87",
    "blanco":   "#FFFFFF",
    "amarillo": "#FFE066",
    "crema":    "#FFF9E6",
    "negro":    "#1A1A2E",
}

FORMATS = {
    "story": (1080, 1920),
    "post":  (1080, 1350),
}

# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

def hex_to_rgb(h: str) -> tuple:
    h = h.lstrip("#")
    return tuple(int(h[i:i+2], 16) for i in (0, 2, 4))


def load_env() -> dict:
    env = {}
    if ENV_PATH.exists():
        for line in ENV_PATH.read_text().splitlines():
            if "=" in line and not line.startswith("#"):
                k, v = line.split("=", 1)
                env[k.strip()] = v.strip()
    return env


def load_fonts(scale: float) -> dict:
    def sz(base): return max(12, int(base * scale))
    def ttf(name, size):
        p = FONTS_DIR / name
        if not p.exists():
            print(f"WARN: fuente {name} no encontrada. Corré setup_fonts.py")
            return ImageFont.load_default()
        return ImageFont.truetype(str(p), size=size)
    return {
        "headline_xl": ttf("FredokaOne-Regular.ttf", sz(88)),
        "headline_lg": ttf("FredokaOne-Regular.ttf", sz(70)),
        "headline_md": ttf("FredokaOne-Regular.ttf", sz(54)),
        "headline_sm": ttf("FredokaOne-Regular.ttf", sz(40)),
        "body_lg":     ttf("Nunito-SemiBold.ttf",    sz(40)),
        "body_md":     ttf("Nunito-SemiBold.ttf",    sz(34)),
        "body_sm":     ttf("Nunito-Regular.ttf",     sz(28)),
        "body_xs":     ttf("Nunito-Regular.ttf",     sz(22)),
        "script_lg":   ttf("Pacifico-Regular.ttf",   sz(46)),
        "script_md":   ttf("Pacifico-Regular.ttf",   sz(36)),
        "script_sm":   ttf("Pacifico-Regular.ttf",   sz(26)),
        "cta":         ttf("FredokaOne-Regular.ttf", sz(44)),
        "badge":       ttf("FredokaOne-Regular.ttf", sz(28)),
        "footer":      ttf("Nunito-Regular.ttf",     sz(26)),
    }


def remove_white_bg(img: Image.Image, threshold: int = 235) -> Image.Image:
    """Convierte píxeles blancos/casi-blancos a transparentes."""
    rgba = img.convert("RGBA")
    data = rgba.getdata()
    new_data = []
    for r, g, b, a in data:
        if r > threshold and g > threshold and b > threshold:
            new_data.append((255, 255, 255, 0))
        else:
            new_data.append((r, g, b, a))
    rgba.putdata(new_data)
    return rgba


def prepare_logo(scale: float) -> Image.Image | None:
    if not LOGO_PATH.exists():
        print(f"WARN: logo no encontrado en {LOGO_PATH}")
        return None
    logo = Image.open(str(LOGO_PATH))
    logo_no_bg = remove_white_bg(logo)
    target_w = int(380 * scale)
    ratio = target_w / logo_no_bg.width
    target_h = int(logo_no_bg.height * ratio)
    return logo_no_bg.resize((target_w, target_h), Image.LANCZOS)


def wrap_text(draw, text: str, font, max_width: int) -> list:
    words = text.split()
    lines, current = [], []
    for word in words:
        test = " ".join(current + [word])
        bbox = draw.textbbox((0, 0), test, font=font)
        if bbox[2] - bbox[0] <= max_width:
            current.append(word)
        else:
            if current:
                lines.append(" ".join(current))
            current = [word]
    if current:
        lines.append(" ".join(current))
    return lines or [""]


# ---------------------------------------------------------------------------
# Primitivas de dibujo de marca
# ---------------------------------------------------------------------------

def draw_white_card(img: Image.Image, x0, y0, x1, y1, radius=28, alpha=230):
    """Card blanca redondeada semitransparente."""
    layer = Image.new("RGBA", img.size, (0, 0, 0, 0))
    d = ImageDraw.Draw(layer)
    d.rounded_rectangle([(x0, y0), (x1, y1)], radius=radius, fill=(255, 255, 255, alpha))
    base = img.convert("RGBA")
    img.paste(Image.alpha_composite(base, layer).convert("RGB"))


def draw_coral_button(img: Image.Image, draw, x0, y0, x1, y1, label: str, font):
    """Botón CTA coral pill."""
    # Sombra suave
    layer = Image.new("RGBA", img.size, (0, 0, 0, 0))
    d = ImageDraw.Draw(layer)
    d.rounded_rectangle([(x0 + 4, y0 + 6), (x1 + 4, y1 + 6)], radius=60, fill=(0, 0, 0, 60))
    base = img.convert("RGBA")
    img.paste(Image.alpha_composite(base, layer).convert("RGB"))

    draw.rounded_rectangle([(x0, y0), (x1, y1)], radius=60, fill=hex_to_rgb(BRAND["coral"]))
    bbox = draw.textbbox((0, 0), label, font=font)
    tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1]
    cx = (x0 + x1) // 2 - tw // 2
    cy = (y0 + y1) // 2 - th // 2
    draw.text((cx, cy), label, font=font, fill=hex_to_rgb(BRAND["blanco"]))


def draw_badge_pill(img: Image.Image, draw, label: str, font, cx, y,
                    bg="#ED6D70", fg="#FFFFFF") -> int:
    """Pill pequeño. Devuelve y inferior."""
    bbox = draw.textbbox((0, 0), label, font=font)
    tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1]
    ph, pv = 24, 10
    x0 = cx - tw // 2 - ph
    x1 = cx + tw // 2 + ph
    y0 = y
    y1 = y + th + pv * 2
    draw.rounded_rectangle([(x0, y0), (x1, y1)], radius=40, fill=hex_to_rgb(bg))
    draw.text((cx - tw // 2, y0 + pv), label, font=font, fill=hex_to_rgb(fg))
    return y1


def draw_highlighter(img: Image.Image, cx, y, text: str, font, draw,
                     color="#FFE066", alpha=105):
    """Resaltador fibra bajo el texto — dibuja ANTES del texto."""
    import random
    bbox = draw.textbbox((0, 0), text, font=font)
    tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1]
    pad_h, pad_v = 10, 4
    x0 = cx - tw // 2 - pad_h; x1 = cx + tw // 2 + pad_h
    y0 = y - pad_v;             y1 = y + th + pad_v
    r, g, b = hex_to_rgb(color)
    layer = Image.new("RGBA", img.size, (0, 0, 0, 0))
    ld = ImageDraw.Draw(layer)
    ld.rectangle([(x0, y0), (x1, y1)], fill=(r, g, b, alpha))
    angle = random.uniform(-2, 2)
    rotated = layer.rotate(angle, center=(cx, (y0 + y1) / 2), expand=False)
    base = img.convert("RGBA")
    img.paste(Image.alpha_composite(base, rotated).convert("RGB"))


def draw_footer(img: Image.Image, font, whatsapp="+54 9 291-4227793"):
    """Banda semitransparente con WhatsApp al pie."""
    W, H = img.size
    y0 = int(H * 0.915)
    layer = Image.new("RGBA", img.size, (0, 0, 0, 0))
    ld = ImageDraw.Draw(layer)
    ld.rectangle([(0, y0), (W, H)], fill=(26, 26, 46, 180))
    base = img.convert("RGBA")
    img.paste(Image.alpha_composite(base, layer).convert("RGB"))
    draw = ImageDraw.Draw(img)
    text = f"  {whatsapp}"
    bbox = draw.textbbox((0, 0), text, font=font)
    tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1]
    draw.text(((W - tw) // 2, y0 + 12), text, font=font, fill=hex_to_rgb(BRAND["blanco"]))


def draw_doodle_underline(draw, x0, y, x1, color="#ED6D70", thickness=3, seed=42):
    import random
    rng = random.Random(seed)
    pts = [(x0 + i * (x1 - x0) / 10, y + rng.randint(-3, 3)) for i in range(11)]
    rgb = hex_to_rgb(color)
    for i in range(len(pts) - 1):
        draw.line([pts[i], pts[i+1]], fill=rgb, width=thickness)


# ---------------------------------------------------------------------------
# Layouts
# ---------------------------------------------------------------------------

def s(px, scale): return max(1, int(px * scale))


def layout_promo(img: Image.Image, args, fonts, scale: float):
    draw = ImageDraw.Draw(img)
    W, H = img.size
    cx = W // 2

    # Logo
    logo = prepare_logo(scale)
    if logo:
        lx = cx - logo.width // 2
        img.paste(logo, (lx, s(55, scale)), logo)
        logo_bottom = s(55, scale) + logo.height + s(20, scale)
    else:
        logo_bottom = s(120, scale)

    y = logo_bottom

    # Badge
    if args.badge:
        y = draw_badge_pill(img, draw, args.badge, fonts["badge"], cx, y) + s(18, scale)
    else:
        y += s(10, scale)

    # Headline card con resaltador
    margin = s(60, scale)
    headline_lines = wrap_text(draw, args.headline, fonts["headline_lg"], W - margin * 2 - s(40, scale))
    lh = int(fonts["headline_lg"].size * 1.25)
    card_h = len(headline_lines) * lh + s(55, scale)
    draw_white_card(img, margin, y, W - margin, y + card_h, radius=s(24, scale))

    ty = y + s(28, scale)
    for i, line in enumerate(headline_lines):
        bbox = draw.textbbox((0, 0), line, font=fonts["headline_lg"])
        tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1]
        if i == 0:
            draw_highlighter(img, cx, ty, line, fonts["headline_lg"], ImageDraw.Draw(img))
            draw = ImageDraw.Draw(img)
        draw.text((cx - tw // 2, ty), line, font=fonts["headline_lg"], fill=hex_to_rgb(BRAND["gris"]))
        ty += th + s(8, scale)
    y += card_h + s(22, scale)

    # Subheadline
    if args.subheadline:
        bbox = draw.textbbox((0, 0), args.subheadline, font=fonts["body_md"])
        tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1]
        draw.text((cx - tw // 2, y), args.subheadline, font=fonts["body_md"], fill=hex_to_rgb(BRAND["blanco"]))
        draw_doodle_underline(draw, cx - tw // 2, y + th + 5, cx + tw // 2, seed=args.seed)
        y += th + s(28, scale)

    # Body card
    bmargin = s(55, scale)
    body_lines_raw = args.body.split("\\n") if "\\n" in args.body else args.body.split("\n")
    all_body = []
    for raw in body_lines_raw:
        all_body.extend(wrap_text(draw, raw, fonts["body_md"], W - bmargin * 2 - s(50, scale)) or [""])
    blh = int(fonts["body_md"].size * 1.4)
    bcard_h = len(all_body) * blh + s(55, scale)
    draw_white_card(img, bmargin, y, W - bmargin, y + bcard_h, radius=s(24, scale))
    draw = ImageDraw.Draw(img)

    ty2 = y + s(28, scale)
    for line in all_body:
        bbox = draw.textbbox((0, 0), line, font=fonts["body_md"])
        tw2, th2 = bbox[2] - bbox[0], bbox[3] - bbox[1]
        draw.text((cx - tw2 // 2, ty2), line, font=fonts["body_md"], fill=hex_to_rgb(BRAND["gris"]))
        ty2 += th2 + s(14, scale)
    y += bcard_h + s(18, scale)

    # extra1
    if args.extra1:
        bbox = draw.textbbox((0, 0), args.extra1, font=fonts["body_sm"])
        tw3, th3 = bbox[2] - bbox[0], bbox[3] - bbox[1]
        draw.text((cx - tw3 // 2, y), args.extra1, font=fonts["body_sm"], fill=hex_to_rgb(BRAND["blanco"]))
        y += th3 + s(15, scale)

    # CTA
    cta_y0 = H - s(290, scale)
    cta_y1 = cta_y0 + s(110, scale)
    draw_coral_button(img, ImageDraw.Draw(img), s(95, scale), cta_y0, W - s(95, scale), cta_y1, args.cta, fonts["cta"])

    draw_footer(img, fonts["footer"])


def layout_evento(img: Image.Image, args, fonts, scale: float):
    draw = ImageDraw.Draw(img)
    W, H = img.size
    cx = W // 2

    logo = prepare_logo(scale)
    if logo:
        img.paste(logo, (cx - logo.width // 2, s(50, scale)), logo)
        logo_bottom = s(50, scale) + logo.height + s(25, scale)
    else:
        logo_bottom = s(120, scale)

    y = logo_bottom

    # Tipo de evento / badge
    event_label = args.badge if args.badge else "EVENTO ESPECIAL"
    y = draw_badge_pill(img, ImageDraw.Draw(img), event_label, fonts["script_md"], cx, y,
                        bg=BRAND["coral"], fg=BRAND["blanco"]) + s(20, scale)
    draw = ImageDraw.Draw(img)

    # Card fecha/hora
    if args.extra1 or args.extra2:
        cmargin = s(80, scale)
        draw_white_card(img, cmargin, y, W - cmargin, y + s(135, scale), radius=s(22, scale))
        draw = ImageDraw.Draw(img)
        if args.extra1:
            bbox = draw.textbbox((0, 0), args.extra1, font=fonts["headline_sm"])
            tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1]
            draw.text((cx - tw // 2, y + s(18, scale)), args.extra1, font=fonts["headline_sm"], fill=hex_to_rgb(BRAND["coral"]))
        if args.extra2:
            bbox = draw.textbbox((0, 0), args.extra2, font=fonts["body_md"])
            tw2, th2 = bbox[2] - bbox[0], bbox[3] - bbox[1]
            draw.text((cx - tw2 // 2, y + s(75, scale)), args.extra2, font=fonts["body_md"], fill=hex_to_rgb(BRAND["gris"]))
        y += s(155, scale)

    # Headline con resaltador amarillo directo sobre fondo
    hl_lines = wrap_text(draw, args.headline, fonts["headline_xl"], W - s(100, scale))
    for line in hl_lines:
        bbox = draw.textbbox((0, 0), line, font=fonts["headline_xl"])
        tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1]
        draw_highlighter(img, cx, y, line, fonts["headline_xl"], ImageDraw.Draw(img), color=BRAND["amarillo"], alpha=120)
        draw = ImageDraw.Draw(img)
        draw.text((cx - tw // 2, y), line, font=fonts["headline_xl"], fill=hex_to_rgb(BRAND["blanco"]))
        y += th + s(8, scale)

    y += s(20, scale)

    # Body card
    if args.body:
        bm = s(55, scale)
        body_lines_raw = args.body.split("\\n") if "\\n" in args.body else args.body.split("\n")
        all_body = []
        for raw in body_lines_raw:
            all_body.extend(wrap_text(draw, raw, fonts["body_md"], W - bm * 2 - s(50, scale)) or [""])
        blh = int(fonts["body_md"].size * 1.4)
        bcard_h = len(all_body) * blh + s(50, scale)
        draw_white_card(img, bm, y, W - bm, y + bcard_h, radius=s(24, scale))
        draw = ImageDraw.Draw(img)
        ty = y + s(25, scale)
        for line in all_body:
            bbox = draw.textbbox((0, 0), line, font=fonts["body_md"])
            tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1]
            draw.text((cx - tw // 2, ty), line, font=fonts["body_md"], fill=hex_to_rgb(BRAND["gris"]))
            ty += th + s(14, scale)

    cta_y0 = H - s(290, scale)
    draw_coral_button(img, ImageDraw.Draw(img), s(95, scale), cta_y0, W - s(95, scale), cta_y0 + s(110, scale), args.cta, fonts["cta"])
    draw_footer(img, fonts["footer"])


def layout_educativo(img: Image.Image, args, fonts, scale: float):
    draw = ImageDraw.Draw(img)
    W, H = img.size
    cx = W // 2

    logo = prepare_logo(scale)
    if logo:
        img.paste(logo, (cx - logo.width // 2, s(45, scale)), logo)
        logo_bottom = s(45, scale) + logo.height + s(18, scale)
    else:
        logo_bottom = s(110, scale)

    y = logo_bottom

    # Badge sección
    section = args.badge if args.badge else "TIP DE HOY"
    y = draw_badge_pill(img, ImageDraw.Draw(img), section, fonts["badge"], cx, y,
                        bg=BRAND["gris"], fg=BRAND["blanco"]) + s(22, scale)
    draw = ImageDraw.Draw(img)

    # Card crema estilo notebook
    cmargin = s(48, scale)
    card_y0 = y
    card_h = s(750, scale)
    layer = Image.new("RGBA", img.size, (0, 0, 0, 0))
    ld = ImageDraw.Draw(layer)
    ld.rounded_rectangle([(cmargin, card_y0), (W - cmargin, card_y0 + card_h)],
                          radius=s(26, scale), fill=(255, 249, 230, 235))
    base = img.convert("RGBA")
    img.paste(Image.alpha_composite(base, layer).convert("RGB"))
    draw = ImageDraw.Draw(img)

    inner_y = card_y0 + s(38, scale)

    # Headline (término en inglés) + resaltador
    draw_highlighter(img, cx, inner_y, args.headline, fonts["headline_lg"], ImageDraw.Draw(img),
                     color=BRAND["amarillo"], alpha=120)
    draw = ImageDraw.Draw(img)
    bbox = draw.textbbox((0, 0), args.headline, font=fonts["headline_lg"])
    tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1]
    draw.text((cx - tw // 2, inner_y), args.headline, font=fonts["headline_lg"], fill=hex_to_rgb(BRAND["coral"]))
    inner_y += th + s(8, scale)

    # Subheadline
    if args.subheadline:
        bbox = draw.textbbox((0, 0), args.subheadline, font=fonts["body_sm"])
        tw2, th2 = bbox[2] - bbox[0], bbox[3] - bbox[1]
        draw.text((cx - tw2 // 2, inner_y), args.subheadline, font=fonts["body_sm"], fill=hex_to_rgb(BRAND["gris"]))
        inner_y += th2 + s(20, scale)

    # Body
    body_lines_raw = args.body.split("\\n") if "\\n" in args.body else args.body.split("\n")
    all_body = []
    for raw in body_lines_raw:
        all_body.extend(wrap_text(draw, raw, fonts["body_md"], W - cmargin * 2 - s(60, scale)) or [""])
    for line in all_body:
        bbox = draw.textbbox((0, 0), line, font=fonts["body_md"])
        tw3, th3 = bbox[2] - bbox[0], bbox[3] - bbox[1]
        draw.text((cx - tw3 // 2, inner_y), line, font=fonts["body_md"], fill=hex_to_rgb(BRAND["gris"]))
        inner_y += th3 + s(12, scale)

    inner_y += s(18, scale)

    # Ejemplo en Pacifico
    if args.extra1:
        example = f'"{args.extra1}"'
        ex_lines = wrap_text(draw, example, fonts["script_md"], W - cmargin * 2 - s(80, scale))
        for line in ex_lines:
            bbox = draw.textbbox((0, 0), line, font=fonts["script_md"])
            tw4, th4 = bbox[2] - bbox[0], bbox[3] - bbox[1]
            draw.text((cx - tw4 // 2, inner_y), line, font=fonts["script_md"], fill=hex_to_rgb(BRAND["gris"]))
            inner_y += th4 + s(8, scale)

    # Traducción con underline
    if args.extra2:
        bbox = draw.textbbox((0, 0), args.extra2, font=fonts["body_sm"])
        tw5, th5 = bbox[2] - bbox[0], bbox[3] - bbox[1]
        draw.text((cx - tw5 // 2, inner_y), args.extra2, font=fonts["body_sm"], fill=hex_to_rgb(BRAND["gris"]))
        draw_doodle_underline(draw, cx - tw5 // 2, inner_y + th5 + 4, cx + tw5 // 2,
                              color=BRAND["teal"], seed=args.seed)

    cta_y0 = H - s(290, scale)
    draw_coral_button(img, ImageDraw.Draw(img), s(95, scale), cta_y0, W - s(95, scale), cta_y0 + s(110, scale), args.cta, fonts["cta"])
    draw_footer(img, fonts["footer"])


def layout_testimonio(img: Image.Image, args, fonts, scale: float):
    draw = ImageDraw.Draw(img)
    W, H = img.size
    cx = W // 2

    logo = prepare_logo(scale)
    if logo:
        img.paste(logo, (cx - logo.width // 2, s(55, scale)), logo)
        logo_bottom = s(55, scale) + logo.height + s(25, scale)
    else:
        logo_bottom = s(120, scale)

    y = logo_bottom

    # Comilla decorativa
    quote_char = "\u201c"
    bbox = draw.textbbox((0, 0), quote_char, font=fonts["headline_xl"])
    qw, qh = bbox[2] - bbox[0], bbox[3] - bbox[1]
    draw.text((cx - qw // 2, y), quote_char, font=fonts["headline_xl"], fill=hex_to_rgb(BRAND["coral"]))

    # Card blanca para la cita (se superpone a la comilla)
    cmargin = s(52, scale)
    qcard_y0 = y + int(qh * 0.55)
    body_lines_raw = args.body.split("\\n") if "\\n" in args.body else args.body.split("\n")
    all_body = []
    for raw in body_lines_raw:
        all_body.extend(wrap_text(draw, raw, fonts["body_lg"], W - cmargin * 2 - s(60, scale)) or [""])
    blh = int(fonts["body_lg"].size * 1.45)
    qcard_h = len(all_body) * blh + s(70, scale)
    draw_white_card(img, cmargin, qcard_y0, W - cmargin, qcard_y0 + qcard_h, radius=s(26, scale))
    draw = ImageDraw.Draw(img)

    # Resaltador en primer segmento si hay accent
    ty = qcard_y0 + s(35, scale)
    for i, line in enumerate(all_body):
        bbox = draw.textbbox((0, 0), line, font=fonts["body_lg"])
        tw2, th2 = bbox[2] - bbox[0], bbox[3] - bbox[1]
        if i == 0 and args.accent:
            draw_highlighter(img, cx, ty, args.accent, fonts["body_lg"], ImageDraw.Draw(img))
            draw = ImageDraw.Draw(img)
        draw.text((cx - tw2 // 2, ty), line, font=fonts["body_lg"], fill=hex_to_rgb(BRAND["gris"]))
        ty += th2 + s(14, scale)

    y = qcard_y0 + qcard_h + s(28, scale)

    # Nombre del alumno con underline doodle
    if args.extra1:
        bbox = draw.textbbox((0, 0), args.extra1, font=fonts["headline_sm"])
        tw3, th3 = bbox[2] - bbox[0], bbox[3] - bbox[1]
        draw.text((cx - tw3 // 2, y), args.extra1, font=fonts["headline_sm"], fill=hex_to_rgb(BRAND["coral"]))
        draw_doodle_underline(draw, cx - tw3 // 2, y + th3 + 5, cx + tw3 // 2, seed=args.seed)
        y += th3 + s(32, scale)

    # Badge de logro
    if args.extra2:
        y = draw_badge_pill(img, ImageDraw.Draw(img), args.extra2, fonts["badge"], cx, y) + s(22, scale)
        draw = ImageDraw.Draw(img)

    # 5 estrellas
    star_r = s(22, scale)
    star_gap = s(14, scale)
    total_w = 5 * star_r * 2 + 4 * star_gap
    sx = cx - total_w // 2
    for i in range(5):
        scx = sx + i * (star_r * 2 + star_gap) + star_r
        scy = y + star_r
        pts = []
        for j in range(10):
            r = star_r if j % 2 == 0 else int(star_r * 0.45)
            angle = math.pi * 2 * j / 10 - math.pi / 2
            pts.append((scx + r * math.cos(angle), scy + r * math.sin(angle)))
        draw.polygon(pts, outline=hex_to_rgb(BRAND["amarillo"]), width=max(2, s(3, scale)))
    y += star_r * 2 + s(20, scale)

    # Línea motivacional
    motiv = "¡Vos también podés lograrlo!"
    bbox = draw.textbbox((0, 0), motiv, font=fonts["script_sm"])
    tw4, th4 = bbox[2] - bbox[0], bbox[3] - bbox[1]
    draw.text((cx - tw4 // 2, y), motiv, font=fonts["script_sm"], fill=hex_to_rgb(BRAND["blanco"]))

    cta_y0 = H - s(290, scale)
    draw_coral_button(img, ImageDraw.Draw(img), s(95, scale), cta_y0, W - s(95, scale), cta_y0 + s(110, scale), args.cta, fonts["cta"])
    draw_footer(img, fonts["footer"])


LAYOUTS = {
    "promo":      layout_promo,
    "evento":     layout_evento,
    "educativo":  layout_educativo,
    "testimonio": layout_testimonio,
}


# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------

def main():
    parser = argparse.ArgumentParser(description="Generador de flyers Kings & Queens (Imagen 3 + Pillow)")
    parser.add_argument("--type",        required=True, choices=list(LAYOUTS))
    parser.add_argument("--format",      required=True, choices=list(FORMATS))
    parser.add_argument("--headline",    required=True)
    parser.add_argument("--body",        required=True)
    parser.add_argument("--cta",         required=True)
    parser.add_argument("--output",      required=True)
    parser.add_argument("--subheadline", default=None)
    parser.add_argument("--accent",      default=None)
    parser.add_argument("--badge",       default=None)
    parser.add_argument("--extra1",      default=None)
    parser.add_argument("--extra2",      default=None)
    parser.add_argument("--seed",        type=int, default=int(datetime.date.today().strftime("%Y%m%d")))
    args = parser.parse_args()

    env = load_env()
    api_key = env.get("OPENAI_API_KEY") or os.environ.get("OPENAI_API_KEY")
    if not api_key:
        print("ERROR: No se encontró OPENAI_API_KEY en .env")
        sys.exit(1)

    W, H = FORMATS[args.format]
    scale = H / 1920.0

    output_path = Path(args.output)
    output_path.parent.mkdir(parents=True, exist_ok=True)

    # 1. Generar fondo con DALL-E 3
    from generate_background import generate_background
    bg = generate_background(api_key, args.type, args.format)
    bg = bg.resize((W, H), Image.LANCZOS).convert("RGB")

    # 2. Aplicar overlay de marca
    fonts = load_fonts(scale)
    LAYOUTS[args.type](bg, args, fonts, scale)

    # 3. Guardar
    bg.save(str(output_path), "PNG", dpi=(72, 72))
    print(f"Flyer guardado: {output_path}  ({W}x{H}px)")


if __name__ == "__main__":
    main()
