#!/usr/bin/env python3
"""Génère le visuel glassmorphism 16:9 + la page HTML du kit social « Merci Pennylane »."""

from __future__ import annotations

import math
import subprocess
import sys
from pathlib import Path

from PIL import Image, ImageDraw, ImageEnhance, ImageFilter, ImageFont, ImageOps

ROOT = Path(__file__).resolve().parents[1]
KIT_DIR = ROOT / "www/propositions/kit-social-pennylane-merci"
PHOTO_PATH = ROOT / "assets/arnaud-headshot-square.png"
OUT_VISUAL = KIT_DIR / "visuels/merci-pennylane-16x9.png"
OUT_VISUAL_LEGACY = KIT_DIR / "visuels/merci-pennylane.png"

W, H = 1920, 1080
ORANGE = (233, 128, 48)
TEAL = (0, 140, 140)
NAVY = (12, 35, 62)
DARK = (8, 12, 22)
WHITE = (255, 255, 255)
GRAY = (190, 195, 205)
GOLD = (240, 176, 32)

MODULE_NAME = "Pennylane Synchronisation"
MODULE_SUBTITLE = "Clients et factures automatiques"
AUTHOR = "Jérôme Langer"
REVIEW = (
    "3 clics et la synchronisation PrestaShop / Pennylane fonctionne. "
    "Les factures s'importent directement, le client est créé, on ne pouvait rêver plus simple "
    "pour le passage à la facturation électronique !"
)


def load_font(size: int, bold: bool = False) -> ImageFont.FreeTypeFont | ImageFont.ImageFont:
    montserrat = [
        f"/Library/Fonts/Montserrat-{'Bold' if bold else 'Regular'}.ttf",
        str(Path.home() / f"Library/Fonts/Montserrat-{'Bold' if bold else 'Regular'}.ttf"),
    ]
    arial = [
        "/System/Library/Fonts/Supplemental/Arial Bold.ttf" if bold else "/System/Library/Fonts/Supplemental/Arial.ttf",
        "/Library/Fonts/Arial Bold.ttf" if bold else "/Library/Fonts/Arial.ttf",
    ]
    for path in montserrat + arial:
        if Path(path).exists():
            return ImageFont.truetype(path, size)
    return ImageFont.load_default()


def text_width(draw: ImageDraw.ImageDraw, text: str, font: ImageFont.ImageFont) -> float:
    return draw.textlength(text, font=font)


def draw_star(draw: ImageDraw.ImageDraw, cx: float, cy: float, radius: float, fill: tuple[int, int, int]) -> None:
    points: list[tuple[float, float]] = []
    for i in range(10):
        angle = math.pi / 2 + i * math.pi / 5
        r = radius if i % 2 == 0 else radius * 0.42
        points.append((cx + math.cos(angle) * r, cy - math.sin(angle) * r))
    draw.polygon(points, fill=fill)


def draw_wrapped_quote(
    draw: ImageDraw.ImageDraw,
    text: str,
    x: int,
    y: int,
    max_width: int,
    font: ImageFont.ImageFont,
    fill: tuple[int, int, int],
    line_height: int,
) -> int:
    words = text.split()
    lines: list[str] = []
    current = "«"
    for word in words:
        trial = f"{current} {word}".strip()
        if text_width(draw, trial, font) <= max_width:
            current = trial
        else:
            lines.append(current)
            current = word
    lines.append(f"{current} »")
    for line in lines:
        draw.text((x, y), line, fill=fill, font=font)
        y += line_height
    return y


def make_background() -> Image.Image:
    base = Image.new("RGB", (W, H), DARK)
    glow = Image.new("RGBA", (W, H), (0, 0, 0, 0))
    gdraw = ImageDraw.Draw(glow)
    blobs = [
        (280, 180, 520, ORANGE, 90),
        (1500, 120, 480, TEAL, 80),
        (1100, 700, 600, ORANGE, 55),
        (400, 820, 450, TEAL, 50),
        (W // 2, H // 2, 700, (40, 60, 100), 35),
    ]
    for cx, cy, radius, color, alpha in blobs:
        gdraw.ellipse((cx - radius, cy - radius, cx + radius, cy + radius), fill=(*color, alpha))
    glow = glow.filter(ImageFilter.GaussianBlur(80))
    return Image.alpha_composite(base.convert("RGBA"), glow).convert("RGB")


def circular_avatar(photo: Image.Image, size: int) -> Image.Image:
    photo = ImageOps.fit(photo.convert("RGB"), (size, size), method=Image.Resampling.LANCZOS)
    photo = ImageEnhance.Contrast(photo).enhance(1.08)
    photo = ImageEnhance.Brightness(photo).enhance(1.05)
    mask = Image.new("L", (size, size), 0)
    ImageDraw.Draw(mask).ellipse((0, 0, size, size), fill=255)
    ring = Image.new("RGBA", (size + 12, size + 12), (0, 0, 0, 0))
    rdraw = ImageDraw.Draw(ring)
    rdraw.ellipse((0, 0, size + 11, size + 11), outline=(*ORANGE, 255), width=4)
    out = Image.new("RGBA", (size + 12, size + 12), (0, 0, 0, 0))
    out.paste(ring, (0, 0), ring)
    avatar = Image.new("RGBA", (size + 12, size + 12), (0, 0, 0, 0))
    avatar.paste(photo, (6, 6), mask)
    out = Image.alpha_composite(out, avatar)
    return out


def draw_glass_card(canvas: Image.Image, box: tuple[int, int, int, int]) -> Image.Image:
    x1, y1, x2, y2 = box
    region = canvas.crop(box).filter(ImageFilter.GaussianBlur(14))
    glass = Image.new("RGBA", (x2 - x1, y2 - y1), (25, 30, 45, 155))
    region_rgba = region.convert("RGBA")
    blended = Image.blend(region_rgba, glass, 0.55)

    overlay = Image.new("RGBA", canvas.size, (0, 0, 0, 0))
    odraw = ImageDraw.Draw(overlay)
    odraw.rounded_rectangle(box, radius=28, fill=(30, 38, 55, 170))
    odraw.rounded_rectangle(box, radius=28, outline=(255, 255, 255, 55), width=2)

    # Bordure dégradée orange → teal (simulée par double trait)
    odraw.rounded_rectangle((x1 - 1, y1 - 1, x2 + 1, y2 + 1), radius=30, outline=(*ORANGE, 120), width=2)
    odraw.rounded_rectangle((x1 + 1, y1 + 1, x2 - 1, y2 - 1), radius=26, outline=(*TEAL, 90), width=1)

    return Image.alpha_composite(canvas.convert("RGBA"), overlay)


def draw_thumbs_up(draw: ImageDraw.ImageDraw, cx: int, cy: int, scale: float = 1.0) -> None:
    s = scale
    palm = [(cx - 40 * s, cy + 30 * s), (cx + 40 * s, cy + 30 * s), (cx + 35 * s, cy - 10 * s), (cx - 35 * s, cy - 10 * s)]
    draw.polygon(palm, fill=(220, 225, 235))
    thumb = [(cx + 25 * s, cy - 10 * s), (cx + 55 * s, cy - 70 * s), (cx + 70 * s, cy - 55 * s), (cx + 40 * s, cy + 5 * s)]
    draw.polygon(thumb, fill=(245, 248, 255))
    draw.ellipse((cx - 55 * s, cy - 85 * s, cx - 15 * s, cy - 45 * s), fill=(245, 248, 255))


def render_visual_glass_16x9() -> Image.Image:
    canvas = make_background()
    canvas = draw_glass_card(canvas, (220, 160, W - 220, H - 120))
    draw = ImageDraw.Draw(canvas)

    # Avatar
    if PHOTO_PATH.exists():
        avatar = circular_avatar(Image.open(PHOTO_PATH), 150)
        canvas.paste(avatar, (175, 115), avatar)
        canvas = canvas.convert("RGBA")
        draw = ImageDraw.Draw(canvas)

    # Onglet étoiles (haut droite de la carte)
    tab_x1, tab_y1, tab_x2, tab_y2 = W - 420, 130, W - 240, 195
    draw.rounded_rectangle((tab_x1, tab_y1, tab_x2, tab_y2), radius=16, fill=(20, 26, 38, 220))
    draw.rounded_rectangle((tab_x1, tab_y1, tab_x2, tab_y2), radius=16, outline=(255, 255, 255, 40), width=1)
    sx = tab_x1 + 28
    sy = tab_y1 + 32
    for i in range(5):
        draw_star(draw, sx + i * 30, sy, 11, GOLD)
    draw.text((tab_x2 - 24, sy), "5/5", fill=WHITE, font=load_font(22, True), anchor="rm")

    # Contenu texte
    tx, ty = 300, 250
    draw.rounded_rectangle((tx, ty, tx + 280, ty + 42), radius=20, fill=ORANGE)
    draw.text((tx + 20, ty + 21), "MODULE PRESTASHOP", fill=WHITE, font=load_font(20, True), anchor="lm")
    ty += 70

    draw.text((tx, ty), MODULE_NAME, fill=WHITE, font=load_font(54, True), anchor="lt")
    ty += 62
    draw.text((tx, ty), MODULE_SUBTITLE, fill=TEAL, font=load_font(28), anchor="lt")
    ty += 52
    draw.text((tx, ty), AUTHOR, fill=GRAY, font=load_font(26, True), anchor="lt")
    ty += 48

    ty = draw_wrapped_quote(draw, REVIEW, tx, ty, W - 560, load_font(28), WHITE, 40)

    draw.text((tx, H - 80), "Merci pour votre avis", fill=ORANGE, font=load_font(32, True), anchor="lt")
    draw.text((W // 2, H - 42), "arnaud-merigeau.fr", fill=GRAY, font=load_font(22), anchor="mm")

    # Icône thumbs up bas droite
    draw_thumbs_up(draw, W - 300, H - 230, 1.4)

    return canvas.convert("RGB")


def main() -> int:
    OUT_VISUAL.parent.mkdir(parents=True, exist_ok=True)
    img = render_visual_glass_16x9()
    img.save(OUT_VISUAL, "PNG", optimize=True)
    print(f"✓ {OUT_VISUAL.relative_to(ROOT)}")

    page_script = ROOT / "scripts/generate-social-kit-page.py"
    subprocess.run([sys.executable, str(page_script), str(KIT_DIR)], check=True)
    print("\nKit prêt (brouillon local, non déployé) :")
    print(f"  → {KIT_DIR / 'content.html'}")
    print(f"  → {OUT_VISUAL}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
