import urllib.request, time, json
from rembg import remove
from PIL import Image, ImageDraw
from pathlib import Path

OBJ = Path(r"C:\allgifted\mathapi11v2\public\assets\math\objects"); SRC = OBJ/"source"
OBJ.mkdir(parents=True, exist_ok=True); SRC.mkdir(exist_ok=True)
base = "https://d8j0ntlcm91z4.cloudfront.net/user_3ENYB9gUptp5V9uUGoiaDV631pi/"
TARGET = 120*1024

# name: (job_id, raw_filename)
M = {
 "apple":("c0bbea97","hf_20260529_134345_c0bbea97-9c95-46f9-9086-d841e98eb83e.png"),
 "soccer-ball":("4c1bcdcf","hf_20260529_134352_4c1bcdcf-3849-497b-8bc2-b97a665c4597.png"),
 "ball-marble":("349c529e","hf_20260529_134358_349c529e-3ac5-4168-92a6-2ab215c50a28.png"),
 "candy":("d426a637","hf_20260529_134405_d426a637-ceca-409f-8a92-7780c296fa9e.png"),
 "cup-mug":("17888d10","hf_20260529_134550_17888d10-5d57-4540-aa74-50d8c9d850ff.png"),
 "pencil":("536a1150","hf_20260529_134558_536a1150-c3c9-4755-9c6c-65530068c8dd.png"),
 "bag-sack":("5d4b3477","hf_20260529_134603_5d4b3477-bb27-46ae-b6af-c0c3602269ee.png"),
 "cupcake":("7a0436c4","hf_20260529_134609_7a0436c4-b463-4b3c-89ee-0cec46c426a9.png"),
 "basketball":("ed7de2c0","hf_20260529_134708_ed7de2c0-e42d-4a1c-bbb7-1e8576e4ae9e.png"),
 "balloon":("db79f731","hf_20260529_134714_db79f731-6082-4cfc-b2ee-b1d9c9334245.png"),
 "cookie":("01f74083","hf_20260529_134720_01f74083-de46-40b2-b387-9039bae1ba89.png"),
 "strawberry":("c488f680","hf_20260529_134745_c488f680-7013-4fc6-b875-f1ffe6b38184.png"),
 "button":("2280ac26","hf_20260529_134852_2280ac26-a1be-4ece-8394-c7f658c8b794.png"),
 "flower":("a4efbd6a","hf_20260529_134856_a4efbd6a-41d0-4804-a9dd-e7134518ebea.png"),
 "cake":("354a516a","hf_20260529_134907_354a516a-67da-41ae-976b-8291d1d87c5c.png"),
 "basket-tray":("397bf8be","hf_20260529_134939_397bf8be-2680-4bc2-a40c-a6ab822e81ca.png"),
 "tart":("155b194d","hf_20260529_135033_155b194d-e107-4c38-a069-53160d9b2c99.png"),
 "pineapple":("9638d096","hf_20260529_135038_9638d096-0715-4d25-b2a4-87d5c0e1b6b4.png"),
 "mango":("5d6084b1","hf_20260529_135047_5d6084b1-f050-4ed6-9308-42e91863405d.png"),
 "lollipop":("e8f0a9be","hf_20260529_135052_e8f0a9be-8f06-4c70-933d-08fd0999c5c8.png"),
 "umbrella":("7532e7af","hf_20260529_135205_7532e7af-6f73-4522-b5f5-dad2e68baf60.png"),
 "toy-car":("51aa84a3","hf_20260529_135212_51aa84a3-7e2d-4f8d-9717-689b16915455.png"),
 "bicycle":("23fce298","hf_20260529_135220_23fce298-1b14-4f04-9188-e9dcd3e079ae.png"),
 "spinning-top":("2ad15e01","hf_20260529_135227_2ad15e01-465c-464c-8e7f-465408960c9d.png"),
 "stamp":("d15661ec","hf_20260529_135328_d15661ec-0899-4d84-9621-46f42303bcae.png"),
 "shell":("6c588d80","hf_20260529_135333_6c588d80-f632-4fa7-87e4-d7a51f40d1ac.png"),
 "pine-tree":("be1099c1","hf_20260529_135340_be1099c1-3f2f-4ee2-af5b-8b1acdca6fc6.png"),
}
def fetch(u,d):
    for _ in range(5):
        try: urllib.request.urlretrieve(u,d); return True
        except Exception: time.sleep(2)
    return False

entries=[]
for name,(jid,fn) in M.items():
    tmp=SRC/("_src_"+name+".png")
    if not fetch(base+fn,tmp): print("FAIL",name); continue
    cut=remove(Image.open(tmp).convert("RGBA"))   # transparent, no badge
    png=SRC/f"ags-math-obj-{name}.png"; cut.save(png,optimize=True); tmp.unlink()
    webp=OBJ/f"ags-math-obj-{name}.webp"
    for q in (90,86,82,78):
        cut.save(webp,"WEBP",quality=q,lossless=False)
        if webp.stat().st_size<=TARGET: break
    kb=webp.stat().st_size/1024
    entries.append({"id":name,"filename":webp.name,"higgsfield_job_id":jid,
        "file_size_kb":round(kb,1),"cdn_url":f"https://math.allgifted.com/objects/{webp.name}",
        "format":"webp","background":"transparent","badge":"none","status":"approved"})
    print(f"{webp.name:34s} {kb:6.1f}KB", flush=True)

manifest={"description":"AGS Math Tutor object assets (food, toys, stationery)",
 "generated":"2026-05-29","count":len(entries),
 "cdn_url_note":"placeholder until upload confirmed; PNG sources in objects/source/",
 "objects":entries}
(OBJ/"ags_math_objects_manifest.json").write_text(json.dumps(manifest,indent=2),encoding="utf-8")
print("manifest:",len(entries),"objects")

# contact sheet on grey
names=[e["filename"] for e in entries]
import math
cols=6; rows=math.ceil(len(names)/cols); cell=200
cv=Image.new("RGB",(cols*cell,rows*cell),(120,120,120)); dr=ImageDraw.Draw(cv)
for i,n in enumerate(names):
    im=Image.open(OBJ/n).convert("RGBA"); im.thumbnail((cell-12,cell-26),Image.LANCZOS)
    r,c=divmod(i,cols); x,y=c*cell,r*cell
    cv.paste(im,(x+(cell-im.width)//2,y+22+(cell-26-im.height)//2),im)
    dr.rectangle([x,y,x+cell-1,y+18],fill=(20,20,20)); dr.text((x+2,y+4),n.replace("ags-math-obj-","").replace(".webp",""),fill=(255,255,0))
cv.save(r"C:\allgifted\logo-reveal\objects_check.png"); print("contact sheet ready")
