#!/usr/bin/env python3
"""Visuel kit social PrestaShop vs Shopify — 1920×1080, charte arnaud-merigeau.fr."""

from __future__ import annotations

from pathlib import Path

from PIL import Image, ImageDraw, ImageFilter, ImageFont

ROOT = Path(__file__).resolve().parents[1]
KIT = ROOT / "www/propositions/kit-social-prestashop-shopify-2026/visuels"
OUT_JPG = KIT / "visuel-prestashop-shopify-2026.jpg"
OUT_PNG = KIT / "visuel-prestashop-shopify-2026.png"

W, H = 1920, 1080
ORANGE = (233, 128, 48)
PEACH = (255, 202, 161)
INK = (0, 0, 0)
MUTED = (102, 102, 102)
WHITE = (255, 255, 255)
SHOPIFY_GREEN = (149, 191, 71)


def load_font(
    size: int,
    *,
    bold: bool = False,
    black: bool = False,
) -> ImageFont.FreeTypeFont | ImageFont.ImageFont:
    if black:
        candidates = [
            "/System/Library/Fonts/Supplemental/Arial Black.ttf",
            "/Library/Fonts/Arial Black.ttf",
            "/System/Library/Fonts/Supplemental/Arial Bold.ttf",
        ]
    elif bold:
        candidates = [
            "/System/Library/Fonts/Supplemental/Arial Bold.ttf",
            "/Library/Fonts/Arial Bold.ttf",
        ]
    else:
        candidates = [
            "/System/Library/Fonts/Supplemental/Arial.ttf",
            "/Library/Fonts/Arial.ttf",
        ]
    for path in candidates:
        if Path(path).exists():
            return ImageFont.truetype(path, size)
    return ImageFont.load_default()


def draw_heavy_title(
    draw: ImageDraw.ImageDraw,
    xy: tuple[int, int],
    text: str,
    font: ImageFont.ImageFont,
    *,
    fill: tuple[int, int, int] = INK,
) -> None:
    x, y = xy
    for dx, dy in ((0, 0), (1, 0), (0, 1), (1, 1)):
        draw.text((x + dx, y + dy), text, fill=fill, font=font, anchor="mm")


def draw_badge(
    draw: ImageDraw.ImageDraw,
    xy: tuple[int, int],
    text: str,
    fill: tuple[int, int, int],
    font: ImageFont.ImageFont,
    *,
    pad_x: int = 28,
    pad_y: int = 14,
) -> tuple[int, int, int, int]:
    tw = draw.textlength(text, font=font)
    th = font.size + 16
    x, y = xy
    box = (x, y, x + tw + pad_x * 2, y + th + pad_y * 2)
    draw.rounded_rectangle(box, radius=18, fill=fill)
    draw.text((x + pad_x, y + pad_y), text, fill=WHITE, font=font)
    return box


def add_blur_halo(
    base: Image.Image,
    center: tuple[int, int],
    radius: int,
    color: tuple[int, int, int, int],
    blur: int,
) -> Image.Image:
    layer = Image.new("RGBA", base.size, (0, 0, 0, 0))
    draw = ImageDraw.Draw(layer)
    cx, cy = center
    draw.ellipse((cx - radius, cy - radius, cx + radius, cy + radius), fill=color)
    layer = layer.filter(ImageFilter.GaussianBlur(radius=blur))
    return Image.alpha_composite(base.convert("RGBA"), layer)


def draw_badges_row(
    draw: ImageDraw.ImageDraw,
    y: int,
    badges: list[tuple[str, tuple[int, int, int]]],
    font: ImageFont.ImageFont,
    *,
    gap: int = 32,
    pad_x: int = 28,
    pad_y: int = 14,
) -> None:
    widths = [draw.textlength(text, font=font) + pad_x * 2 for text, _ in badges]
    total_w = sum(widths) + gap * (len(badges) - 1)
    x = (W - total_w) // 2
    for (text, color), width in zip(badges, widths):
        draw_badge(draw, (x, y), text, color, font, pad_x=pad_x, pad_y=pad_y)
        x += width + gap


def render() -> Image.Image:
    img = Image.new("RGB", (W, H), (255, 252, 248))
    draw = ImageDraw.Draw(img)

    for y in range(H):
        t = y / H
        r = int(255 - t * 3)
        g = int(252 - t * 5)
        b = int(248 - t * 8)
        draw.line([(0, y), (W, y)], fill=(r, g, b))

    img = add_blur_halo(img, (1180, 220), 420, (233, 128, 48, 62), blur=120)
    img = add_blur_halo(img, (260, 420), 360, (255, 190, 130, 52), blur=105)
    img = add_blur_halo(img, (1520, 760), 320, (236, 192, 89, 42), blur=90)
    img = add_blur_halo(img, (760, 900), 280, (233, 128, 48, 38), blur=80)
    img = add_blur_halo(img, (960, 540), 680, (255, 220, 190, 28), blur=140)
    img = img.convert("RGB")
    draw = ImageDraw.Draw(img)

    font_title = load_font(118, black=True)
    font_sub = load_font(40)
    font_badge = load_font(34, bold=True)
    font_url = load_font(22, bold=True)

    y_prestashop = 262
    y_ou = 372
    y_shopify = 472

    draw_heavy_title(draw, (W // 2, y_prestashop), "PRESTASHOP", font_title)
    draw.text((W // 2, y_ou), "ou", fill=MUTED, font=load_font(52), anchor="mm")
    draw_heavy_title(draw, (W // 2, y_shopify), "SHOPIFY ?", font_title)

    draw.text(
        (W // 2, 582),
        "Le comparatif honnête pour choisir (ou migrer) en 2026",
        fill=ORANGE,
        font=font_sub,
        anchor="mm",
    )

    draw_badges_row(
        draw,
        678,
        [
            ("OPEN SOURCE", ORANGE),
            ("SAAS", SHOPIFY_GREEN),
        ],
        font_badge,
    )

    draw.text((W - 64, H - 48), "arnaud-merigeau.fr", fill=MUTED, font=font_url, anchor="rb")

    dot_x = W // 2 + int(draw.textlength("SHOPIFY ?", font=font_title) // 2) + 18
    dot_y = y_shopify - 30
    draw.ellipse((dot_x, dot_y, dot_x + 22, dot_y + 22), fill=ORANGE)

    return img


def main() -> int:
    KIT.mkdir(parents=True, exist_ok=True)
    img = render()
    img.save(OUT_JPG, "JPEG", quality=92, optimize=True)
    img.save(OUT_PNG, "PNG", optimize=True)
    print(f"Visuels : {OUT_JPG.name}, {OUT_PNG.name}")
    return 0


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