#!/usr/bin/env python3
"""Generate Antidetect Profiles browser icon PNG sizes and firefox.icns (macOS)."""

from __future__ import annotations

import math
import os
import shutil
import subprocess
import sys

try:
    from PIL import Image, ImageDraw, ImageFilter, ImageFont
except ImportError:
    print("Install Pillow: pip install pillow", file=sys.stderr)
    sys.exit(1)

DIR = os.path.dirname(os.path.abspath(__file__))
SIZES = (16, 32, 64, 128, 256, 512, 1024)
ICONSET_SPECS = (
    (16, "icon_16x16.png"),
    (32, "icon_16x16@2x.png"),
    (32, "icon_32x32.png"),
    (64, "icon_32x32@2x.png"),
    (128, "icon_128x128.png"),
    (256, "icon_128x128@2x.png"),
    (256, "icon_256x256.png"),
    (512, "icon_256x256@2x.png"),
    (512, "icon_512x512.png"),
    (1024, "icon_512x512@2x.png"),
)


def _lerp(a: float, b: float, t: float) -> float:
    return a + (b - a) * t


def _gradient_bg(size: int) -> Image.Image:
    img = Image.new("RGBA", (size, size), (0, 0, 0, 0))
    px = img.load()
    for y in range(size):
        for x in range(size):
            t = (x + y) / (2 * size)
            r = int(_lerp(12, 38, t))
            g = int(_lerp(18, 24, t))
            b = int(_lerp(42, 72, t))
            px[x, y] = (r, g, b, 255)
    return img


def _rounded_mask(size: int, radius_ratio: float = 0.22) -> Image.Image:
    mask = Image.new("L", (size, size), 0)
    draw = ImageDraw.Draw(mask)
    radius = int(size * radius_ratio)
    draw.rounded_rectangle((0, 0, size - 1, size - 1), radius=radius, fill=255)
    return mask


def _draw_icon(size: int) -> Image.Image:
    base = _gradient_bg(size)
    mask = _rounded_mask(size)
    canvas = Image.new("RGBA", (size, size), (0, 0, 0, 0))
    canvas.paste(base, (0, 0), mask)

    draw = ImageDraw.Draw(canvas)
    pad = size * 0.12
    inner = (pad, pad, size - pad, size - pad)
    draw.rounded_rectangle(inner, radius=int(size * 0.18), outline=(134, 59, 255, 220), width=max(1, size // 64))

    shield_w = size * 0.52
    shield_h = size * 0.58
    cx = size / 2
    top = size * 0.24
    shield = [
        (cx, top),
        (cx + shield_w / 2, top + shield_h * 0.22),
        (cx + shield_w / 2, top + shield_h * 0.72),
        (cx, top + shield_h),
        (cx - shield_w / 2, top + shield_h * 0.72),
        (cx - shield_w / 2, top + shield_h * 0.22),
    ]
    draw.polygon(shield, fill=(30, 36, 54, 240), outline=(134, 59, 255, 255))

    # Browser window motif inside shield
    win_left = cx - shield_w * 0.28
    win_top = top + shield_h * 0.34
    win_right = cx + shield_w * 0.28
    win_bottom = top + shield_h * 0.66
    draw.rounded_rectangle(
        (win_left, win_top, win_right, win_bottom),
        radius=max(1, size // 80),
        fill=(18, 22, 34, 255),
        outline=(110, 170, 255, 180),
        width=max(1, size // 128),
    )
    dot_y = win_top + size * 0.035
    for i, color in enumerate(((255, 95, 86), (255, 189, 46), (39, 201, 63))):
        dx = win_left + size * 0.05 + i * size * 0.045
        draw.ellipse((dx, dot_y, dx + size * 0.022, dot_y + size * 0.022), fill=color)

    # AP monogram
    font_size = max(8, int(size * 0.17))
    try:
        font = ImageFont.truetype("/System/Library/Fonts/Supplemental/Avenir Next Heavy.ttf", font_size)
    except OSError:
        try:
            font = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", font_size)
        except OSError:
            font = ImageFont.load_default()

    text = "AP"
    bbox = draw.textbbox((0, 0), text, font=font)
    tw = bbox[2] - bbox[0]
    th = bbox[3] - bbox[1]
    tx = cx - tw / 2
    ty = top + shield_h * 0.18 - th / 2
    draw.text((tx, ty), text, fill=(237, 230, 255, 255), font=font)

    if size >= 128:
        canvas = canvas.filter(ImageFilter.UnsharpMask(radius=1.2, percent=120, threshold=2))
    return canvas


def main() -> None:
    os.makedirs(DIR, exist_ok=True)
    rendered: dict[int, Image.Image] = {}

    for size in SIZES:
        img = _draw_icon(size)
        name = f"icon-{size}.png"
        path = os.path.join(DIR, name)
        img.save(path, "PNG")
        rendered[size] = img
        print(f"Wrote {path}")

    master = rendered[1024]
    master_path = os.path.join(DIR, "browser-icon-1024.png")
    master.save(master_path, "PNG")
    print(f"Wrote {master_path}")

    icon512 = os.path.join(DIR, "icon-512.png")
    rendered[512].save(icon512, "PNG")

    if sys.platform == "darwin" and shutil.which("iconutil"):
        iconset = os.path.join(DIR, "ap-browser.iconset")
        if os.path.isdir(iconset):
            shutil.rmtree(iconset)
        os.makedirs(iconset, exist_ok=True)
        for px, filename in ICONSET_SPECS:
            out = os.path.join(iconset, filename)
            rendered[px].save(out, "PNG")
        icns_path = os.path.join(DIR, "firefox.icns")
        subprocess.run(
            ["iconutil", "-c", "icns", iconset, "-o", icns_path],
            check=True,
        )
        shutil.rmtree(iconset)
        print(f"Wrote {icns_path}")
    else:
        print("iconutil not available; skipped firefox.icns", file=sys.stderr)


if __name__ == "__main__":
    main()
