from PIL import Image, ImageDraw, ImageFilter, ImageFont
from pathlib import Path
import math

ROOT = Path(__file__).resolve().parents[1]
ASSETS = ROOT / 'assets' / 'app-icons'
SRC = ASSETS / 'src'
ADMINSET = ASSETS / 'iconset-admin.iconset'
NOTESSET = ASSETS / 'iconset-notes.iconset'

brand_path = Path('/Users/jason/Library/Messages/Attachments/a9/09/72A0D92D-45A8-44EF-A720-9BD784AE2C62/50C5F0B5-E177-44EF-AD1C-2ABA824E2C41.png')
art_path = Path('/Users/jason/Library/Messages/Attachments/84/04/FB101DFE-7326-43AC-A8C7-7DCE718E0DF1/EB9F3B50-26CC-4B4C-B244-EF5C9141CE54.PNG')
mech_path = Path('/Users/jason/Library/Messages/Attachments/ba/10/48753656-D4BD-4634-BC2C-CB419EB65FB0/52F9CB41-2212-4372-A652-DC33E76CD122.PNG')
music_path = Path('/Users/jason/Library/Messages/Attachments/56/06/622A830D-89A6-4627-9303-AD4E54D0CEB5/82175000-7483-443F-B993-E2C1BA26AC78.PNG')

for p in [brand_path, art_path, mech_path, music_path]:
    if not p.exists():
        raise SystemExit(f'Missing source asset: {p}')

brand = Image.open(brand_path).convert('RGBA')
art = Image.open(art_path).convert('RGBA')
mech = Image.open(mech_path).convert('RGBA')
music = Image.open(music_path).convert('RGBA')

try:
    FONT_BOLD = ImageFont.truetype('/System/Library/Fonts/Supplemental/Arial Bold.ttf', 96)
    FONT_MED = ImageFont.truetype('/System/Library/Fonts/Supplemental/Arial Bold.ttf', 58)
except Exception:
    FONT_BOLD = ImageFont.load_default()
    FONT_MED = ImageFont.load_default()


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


def crop_cover(image, size):
    src_w, src_h = image.size
    scale = max(size / src_w, size / src_h)
    resized = image.resize((int(src_w * scale), int(src_h * scale)), Image.Resampling.LANCZOS)
    left = (resized.width - size) // 2
    top = (resized.height - size) // 2
    return resized.crop((left, top, left + size, top + size))


def make_card(icon, size, accent=(255,255,255,235)):
    card = Image.new('RGBA', (size, size), (0, 0, 0, 0))
    shadow = Image.new('RGBA', (size, size), (0, 0, 0, 0))
    ds = ImageDraw.Draw(shadow)
    ds.rounded_rectangle((18, 26, size-6, size-2), radius=int(size*0.18), fill=(0, 0, 0, 82))
    shadow = shadow.filter(ImageFilter.GaussianBlur(size*0.06))
    card.alpha_composite(shadow)
    d = ImageDraw.Draw(card)
    d.rounded_rectangle((10, 10, size-14, size-14), radius=int(size*0.18), fill=accent, outline=(255,255,255,255), width=max(2, size//34))
    inner = crop_cover(icon, int(size*0.72))
    inner_mask = rounded_mask(inner.width, int(inner.width*0.12))
    inner.putalpha(inner_mask)
    card.alpha_composite(inner, ((size-inner.width)//2, (size-inner.height)//2))
    return card


def draw_label(canvas, text, fill, outline=(255,255,255,230)):
    d = ImageDraw.Draw(canvas)
    x0, y0, x1, y1 = 150, 786, 874, 930
    d.rounded_rectangle((x0, y0, x1, y1), radius=56, fill=fill, outline=outline, width=6)
    bbox = d.textbbox((0,0), text, font=FONT_MED)
    tw = bbox[2]-bbox[0]
    th = bbox[3]-bbox[1]
    d.text((512 - tw/2, y0 + (y1-y0-th)/2 - 8), text, font=FONT_MED, fill=(255,255,255,255))


def make_base():
    size = 1024
    base = crop_cover(brand, size)
    overlay = Image.new('RGBA', (size, size), (0,0,0,0))
    od = ImageDraw.Draw(overlay)
    od.rounded_rectangle((0,0,size,size), radius=230, fill=(8,10,18,74))
    od.rectangle((0, 540, size, size), fill=(6,8,14,78))
    base.alpha_composite(overlay)

    ring = Image.new('RGBA', (size, size), (0,0,0,0))
    rd = ImageDraw.Draw(ring)
    rd.rounded_rectangle((22,22,size-22,size-22), radius=220, outline=(255,255,255,210), width=10)
    rd.rounded_rectangle((44,44,size-44,size-44), radius=200, outline=(22,34,66,180), width=6)
    base.alpha_composite(ring)

    mask = rounded_mask(size, 228)
    out = Image.new('RGBA', (size, size), (0,0,0,0))
    out.paste(base, (0,0), mask)
    return out


def make_admin_icon():
    icon = make_base()
    title = Image.new('RGBA', icon.size, (0,0,0,0))
    dt = ImageDraw.Draw(title)
    bbox = dt.textbbox((0,0), 'SSB', font=FONT_BOLD)
    tw = bbox[2]-bbox[0]
    th = bbox[3]-bbox[1]
    tx = 512 - tw/2
    ty = 88
    for ox, oy in [(-4,0),(4,0),(0,-4),(0,4),(-3,-3),(3,3),(-3,3),(3,-3)]:
        dt.text((tx+ox, ty+oy), 'SSB', font=FONT_BOLD, fill=(8,10,18,180))
    dt.text((tx, ty), 'SSB', font=FONT_BOLD, fill=(255,255,255,248))
    icon.alpha_composite(title)

    card_size = 248
    left = make_card(art, card_size, accent=(255,255,255,238)).rotate(-12, resample=Image.Resampling.BICUBIC, expand=True)
    center = make_card(mech, card_size, accent=(255,255,255,244))
    right = make_card(music, card_size, accent=(255,255,255,238)).rotate(12, resample=Image.Resampling.BICUBIC, expand=True)
    icon.alpha_composite(left, (90, 330))
    icon.alpha_composite(right, (578, 330))
    icon.alpha_composite(center, (389, 300))
    draw_label(icon, 'ADMIN', (29, 71, 154, 232))
    return icon


def make_notes_icon():
    icon = make_base()
    pad = 150
    panel = Image.new('RGBA', (1024,1024), (0,0,0,0))
    d = ImageDraw.Draw(panel)
    d.rounded_rectangle((pad, 140, 1024-pad, 760), radius=82, fill=(255,255,255,236), outline=(255,255,255,255), width=8)
    d.rounded_rectangle((pad+36, 190, 1024-pad-36, 252), radius=30, fill=(40, 110, 70, 235))
    for y in [330, 420, 510, 600]:
        d.rounded_rectangle((pad+74, y, 1024-pad-74, y+18), radius=9, fill=(76, 84, 108, 185))
    for x, color in [(pad+74, (56, 154, 88, 255)), (pad+102, (230, 94, 164, 255)), (pad+130, (214, 169, 45, 255))]:
        d.rounded_rectangle((x, 330, x+12, 618), radius=6, fill=color)
    icon.alpha_composite(panel)
    pencil = crop_cover(art, 250)
    pencil = pencil.resize((250,250), Image.Resampling.LANCZOS)
    pencil_mask = rounded_mask(250, 44)
    pencil.putalpha(pencil_mask)
    icon.alpha_composite(pencil, (648, 436))
    draw_label(icon, 'NOTES', (167, 60, 120, 232))
    return icon


def save_iconset(image, folder):
    folder.mkdir(parents=True, exist_ok=True)
    sizes = [16, 32, 128, 256, 512]
    for size in sizes:
        img = image.resize((size, size), Image.Resampling.LANCZOS)
        img.save(folder / f'icon_{size}x{size}.png')
        img2 = image.resize((size*2, size*2), Image.Resampling.LANCZOS)
        img2.save(folder / f'icon_{size}x{size}@2x.png')
    image.save(folder / 'icon_512x512@2x.png')

admin = make_admin_icon()
notes = make_notes_icon()
SRC.mkdir(parents=True, exist_ok=True)
admin.save(SRC / 'admin-1024.png')
notes.save(SRC / 'notes-1024.png')
save_iconset(admin, ADMINSET)
save_iconset(notes, NOTESSET)
print('Built source PNGs and iconsets.')
