#!/usr/bin/env python3
"""Visuel kit social — Aperçu IA Google « meilleur développeur PrestaShop »."""

from __future__ import annotations

from pathlib import Path

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

ROOT = Path(__file__).resolve().parents[1]
SHOT = ROOT / "assets/meilleur-developpeur-prestashop-google-ia.jpg"
KIT = ROOT / "www/propositions/kit-social-google-ia-prestashop/visuels"
OUT_JPG = KIT / "visuel-google-ia-prestashop.jpg"
OUT_PNG = KIT / "visuel-google-ia-prestashop.png"

W, H = 1920, 1080
ORANGE = (233, 128, 48)
INK = (17, 17, 17)
MUTED = (102, 102, 102)
WHITE = (255, 255, 255)
NAVY = (18, 32, 56)
CREAM = (255, 252, 248)


def load_font(size: int, *, bold: bool = False, black: bool = False) -> 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 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 cream_bg(w: int, h: int) -> Image.Image:
    img = Image.new("RGB", (w, h), CREAM)
    draw = ImageDraw.Draw(img)
    for y in range(h):
        t = y / h
        draw.line([(0, y), (w, y)], fill=(255, int(252 - t * 5), int(248 - t * 8)))
    img = add_blur_halo(img, (1180, 180), 420, (233, 128, 48, 62), blur=120)
    img = add_blur_halo(img, (220, 520), 340, (255, 190, 130, 52), blur=105)
    img = add_blur_halo(img, (1680, 820), 300, (236, 192, 89, 42), blur=90)
    img = add_blur_halo(img, (960, 540), 680, (255, 220, 190, 28), blur=140)
    return img.convert("RGB")


def rounded_shot(src: Image.Image, size: tuple[int, int], radius: int) -> Image.Image:
    fitted = ImageOps.fit(src.convert("RGB"), size, method=Image.Resampling.LANCZOS)
    mask = Image.new("L", size, 0)
    ImageDraw.Draw(mask).rounded_rectangle((0, 0, size[0], size[1]), radius=radius, fill=255)
    out = Image.new("RGBA", size, (0, 0, 0, 0))
    out.paste(fitted, (0, 0))
    out.putalpha(mask)
    return out


def paste_shadow(
    base: Image.Image,
    box: tuple[int, int, int, int],
    radius: int,
) -> Image.Image:
    x0, y0, x1, y1 = box
    layer = Image.new("RGBA", base.size, (0, 0, 0, 0))
    draw = ImageDraw.Draw(layer)
    draw.rounded_rectangle((x0 + 10, y0 + 22, x1 + 10, y1 + 22), radius=radius, fill=(20, 24, 36, 80))
    layer = layer.filter(ImageFilter.GaussianBlur(22))
    return Image.alpha_composite(base.convert("RGBA"), layer)


def render() -> Image.Image:
    if not SHOT.exists():
        raise FileNotFoundError(f"Capture introuvable : {SHOT}")

    img = cream_bg(W, H)
    draw = ImageDraw.Draw(img)

    badge_f = load_font(26, bold=True)
    title_f = load_font(68, black=True)
    sub_f = load_font(32, bold=True)
    body_f = load_font(26)
    foot_f = load_font(22, bold=True)
    caption_f = load_font(20, bold=True)

    draw.rounded_rectangle((72, 88, 430, 156), radius=18, fill=ORANGE)
    draw.text((251, 122), "APERÇU IA GOOGLE", fill=WHITE, font=badge_f, anchor="mm")

    draw.text((72, 230), "C'est pas moi", fill=INK, font=title_f)
    draw.text((72, 318), "qui le dis.", fill=INK, font=title_f)

    last_w = draw.textlength("qui le dis.", font=title_f)
    dot_x = 72 + int(last_w) + 16
    draw.ellipse((dot_x, 328, dot_x + 18, 346), fill=ORANGE)

    draw.text((72, 430), "L'IA Google me cite comme", fill=ORANGE, font=sub_f)
    draw.text((72, 474), "expert PrestaShop.", fill=ORANGE, font=sub_f)

    draw.text((72, 548), "Requête : « quel est le meilleur", fill=MUTED, font=body_f)
    draw.text((72, 588), "développeur PrestaShop »", fill=MUTED, font=body_f)

    draw.rounded_rectangle((72, 680, 620, 760), radius=18, fill=NAVY)
    draw.text((346, 720), "arnaud-merigeau.fr", fill=WHITE, font=foot_f, anchor="mm")

    shot_w, shot_h = 1040, 690
    frame_pad = 14
    fx, fy = 830, 145
    fw, fh = shot_w + frame_pad * 2, shot_h + frame_pad * 2 + 52
    frame = (fx, fy, fx + fw, fy + fh)

    img = paste_shadow(img, frame, radius=28)
    draw = ImageDraw.Draw(img)
    draw.rounded_rectangle(frame, radius=28, fill=WHITE)

    shot = rounded_shot(Image.open(SHOT), (shot_w, shot_h), radius=18)
    img.paste(shot, (fx + frame_pad, fy + frame_pad), shot)
    draw = ImageDraw.Draw(img)
    draw.text(
        (fx + fw // 2, fy + frame_pad + shot_h + 26),
        "Cité nommément dans les experts indépendants",
        fill=ORANGE,
        font=caption_f,
        anchor="mm",
    )

    draw.text((W - 64, H - 42), "arnaud-merigeau.fr", fill=MUTED, font=load_font(20, bold=True), anchor="rb")
    return img.convert("RGB")


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())
