from pathlib import Path
import subprocess

from PIL import Image, ImageDraw, ImageFilter, ImageFont


ROOT = Path(__file__).resolve().parents[1]
ASSET_ROOT = ROOT / "assets" / "app-icons"
SRC_ROOT = ASSET_ROOT / "src"
NOTES_SET = ASSET_ROOT / "iconset-notes.iconset"
ADMIN_SET = ASSET_ROOT / "iconset-admin.iconset"


def font(size):
    for path in [
        "/System/Library/Fonts/Supplemental/Arial Bold.ttf",
        "/System/Library/Fonts/Supplemental/Impact.ttf",
    ]:
        try:
            return ImageFont.truetype(path, size)
        except OSError:
            pass
    return ImageFont.load_default()


def rounded_mask(size, radius):
    mask = Image.new("L", (size, size), 0)
    draw = ImageDraw.Draw(mask)
    draw.rounded_rectangle((0, 0, size, size), radius=radius, fill=255)
    return mask


def make_icon(label, accent):
    size = 1024
    icon = Image.new("RGBA", (size, size), (15, 18, 27, 255))
    draw = ImageDraw.Draw(icon)

    for i in range(64):
        t = i / 63
        color = (
            int(20 + accent[0] * 0.16 * t),
            int(24 + accent[1] * 0.12 * t),
            int(34 + accent[2] * 0.12 * t),
            255,
        )
        draw.rounded_rectangle((i * 8, i * 8, size - i * 8, size - i * 8), radius=230 - i, outline=color, width=8)

    glow = Image.new("RGBA", (size, size), (0, 0, 0, 0))
    glow_draw = ImageDraw.Draw(glow)
    glow_draw.ellipse((168, 126, 856, 814), fill=(*accent, 92))
    glow = glow.filter(ImageFilter.GaussianBlur(52))
    icon.alpha_composite(glow)

    badge = Image.new("RGBA", (size, size), (0, 0, 0, 0))
    badge_draw = ImageDraw.Draw(badge)
    badge_draw.rounded_rectangle((168, 150, 856, 780), radius=96, fill=(246, 241, 228, 242), outline=(255, 255, 255, 255), width=10)
    badge_draw.rounded_rectangle((220, 218, 804, 324), radius=46, fill=(*accent, 235))
    badge_draw.rectangle((500, 320, 524, 706), fill=(20, 23, 32, 220))
    badge_draw.polygon([(314, 640), (512, 282), (710, 640)], fill=(18, 21, 30, 235))
    badge_draw.polygon([(356, 610), (512, 332), (668, 610)], fill=(246, 241, 228, 255))
    badge_draw.polygon([(406, 586), (512, 394), (618, 586)], fill=(*accent, 245))
    badge_draw.ellipse((244, 420, 342, 518), fill=(255, 122, 47, 255), outline=(18, 21, 30, 255), width=8)
    badge_draw.ellipse((682, 420, 780, 518), fill=(62, 141, 255, 255), outline=(18, 21, 30, 255), width=8)
    icon.alpha_composite(badge)

    label_font = font(122)
    text_bbox = draw.textbbox((0, 0), label, font=label_font)
    text_w = text_bbox[2] - text_bbox[0]
    text_h = text_bbox[3] - text_bbox[1]
    text_x = (size - text_w) / 2
    text_y = 810 + (110 - text_h) / 2
    for dx, dy in [(-4, 0), (4, 0), (0, -4), (0, 4)]:
        draw.text((text_x + dx, text_y + dy), label, font=label_font, fill=(0, 0, 0, 210))
    draw.text((text_x, text_y), label, font=label_font, fill=(255, 255, 255, 255))

    out = Image.new("RGBA", (size, size), (0, 0, 0, 0))
    out.paste(icon, (0, 0), rounded_mask(size, 228))
    return out


def save_iconset(image, iconset):
    iconset.mkdir(parents=True, exist_ok=True)
    for base_size in [16, 32, 128, 256, 512]:
        image.resize((base_size, base_size), Image.Resampling.LANCZOS).save(iconset / f"icon_{base_size}x{base_size}.png")
        image.resize((base_size * 2, base_size * 2), Image.Resampling.LANCZOS).save(iconset / f"icon_{base_size}x{base_size}@2x.png")


def main():
    SRC_ROOT.mkdir(parents=True, exist_ok=True)
    notes = make_icon("AFP", (229, 59, 113))
    admin = make_icon("AFP", (58, 166, 118))
    notes.save(SRC_ROOT / "anime-fighter-pro-organizer-1024.png")
    admin.save(SRC_ROOT / "anime-fighter-pro-admin-1024.png")
    save_iconset(notes, NOTES_SET)
    save_iconset(admin, ADMIN_SET)
    subprocess.run(["iconutil", "-c", "icns", str(NOTES_SET), "-o", str(ASSET_ROOT / "notes.icns")], check=True)
    subprocess.run(["iconutil", "-c", "icns", str(ADMIN_SET), "-o", str(ASSET_ROOT / "admin.icns")], check=True)
    print("Built Anime Fighter Pro app icons.")


if __name__ == "__main__":
    main()
