"""Generate placeholder animated GIFs for all cat states.

Run once: python -m opencat.generate_placeholders
Users will replace these with custom AI-generated GIFs.
"""

import os
import sys

# Add parent dir so we can import the old sprites module
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))

from PIL import Image, ImageDraw, ImageFont

S = 80  # sprite size

# ── Colors ──
BODY = (74, 74, 90)
BODY_LIGHT = (94, 94, 110)
EAR_INNER = (255, 143, 163)
EYE_GREEN = (127, 224, 160)
EYE_CLOSED = (200, 200, 220)
NOSE_PINK = (255, 143, 163)
MOUTH = (200, 200, 220)
ERROR_RED = (255, 100, 100)
ZZZ_COLOR = (150, 150, 180)
POOP_BROWN = (139, 90, 43)
DONE_GREEN = (127, 224, 160)


def _new():
    return Image.new('RGBA', (S, S), (0, 0, 0, 0))

def _body(draw, y=0):
    draw.ellipse([14, 22+y, 66, 70+y], fill=BODY)
    draw.ellipse([24, 38+y, 56, 66+y], fill=BODY_LIGHT)

def _ears(draw, y=0, droopy=False):
    t = 22 + y
    if droopy:
        draw.polygon([(18,t),(10,t-10),(28,t+4)], fill=BODY)
        draw.polygon([(62,t),(70,t-10),(52,t+4)], fill=BODY)
        draw.polygon([(19,t),(13,t-6),(26,t+2)], fill=EAR_INNER)
        draw.polygon([(61,t),(67,t-6),(54,t+2)], fill=EAR_INNER)
    else:
        draw.polygon([(18,t),(8,t-18),(30,t)], fill=BODY)
        draw.polygon([(62,t),(72,t-18),(50,t)], fill=BODY)
        draw.polygon([(20,t),(12,t-12),(28,t)], fill=EAR_INNER)
        draw.polygon([(60,t),(68,t-12),(52,t)], fill=EAR_INNER)

def _open_eyes(draw, y=0, look_up=False):
    t = 34 + y; p = -2 if look_up else 0
    draw.ellipse([24,t,34,t+10], fill=(255,255,255))
    draw.ellipse([46,t,56,t+10], fill=(255,255,255))
    draw.ellipse([26,t+2+p,32,t+8+p], fill=EYE_GREEN)
    draw.ellipse([48,t+2+p,54,t+8+p], fill=EYE_GREEN)
    draw.ellipse([28,t+3+p,31,t+7+p], fill=(20,20,30))
    draw.ellipse([50,t+3+p,53,t+7+p], fill=(20,20,30))

def _closed_eyes(draw, y=0):
    t = 38 + y
    draw.arc([24,t-3,34,t+5], start=0, end=180, fill=EYE_CLOSED, width=2)
    draw.arc([46,t-3,56,t+5], start=0, end=180, fill=EYE_CLOSED, width=2)

def _half_eyes(draw, y=0):
    t = 36 + y
    draw.arc([24,t,34,t+8], start=200, end=340, fill=EYE_GREEN, width=2)
    draw.arc([46,t,56,t+8], start=200, end=340, fill=EYE_GREEN, width=2)

def _happy_eyes(draw, y=0):
    t = 36 + y
    draw.arc([24,t,34,t+8], start=200, end=340, fill=EYE_GREEN, width=2)
    draw.arc([46,t,56,t+8], start=200, end=340, fill=EYE_GREEN, width=2)

def _x_eyes(draw, y=0):
    t = 34 + y
    draw.line([(25,t+1),(33,t+9)], fill=ERROR_RED, width=2)
    draw.line([(25,t+9),(33,t+1)], fill=ERROR_RED, width=2)
    draw.line([(47,t+1),(55,t+9)], fill=ERROR_RED, width=2)
    draw.line([(47,t+9),(55,t+1)], fill=ERROR_RED, width=2)

def _nose(draw, y=0):
    draw.polygon([(38,44+y),(42,44+y),(40,47+y)], fill=NOSE_PINK)

def _mouth_w(draw, y=0):
    t = 47 + y
    draw.arc([33,t,40,t+5], start=0, end=180, fill=MOUTH, width=1)
    draw.arc([40,t,47,t+5], start=0, end=180, fill=MOUTH, width=1)

def _mouth_open(draw, y=0):
    t = 47 + y
    draw.ellipse([36,t,44,t+6], fill=(60,40,50))
    draw.arc([36,t,44,t+6], start=0, end=360, fill=MOUTH, width=1)

def _mouth_sad(draw, y=0):
    draw.arc([34,48+y,46,54+y], start=180, end=360, fill=MOUTH, width=1)

def _paws(draw, y=0):
    t = 62 + y
    draw.rounded_rectangle([26,t,34,t+8], radius=3, fill=BODY)
    draw.rounded_rectangle([46,t,54,t+8], radius=3, fill=BODY)

def _cheeks(draw, y=0):
    draw.ellipse([18,42+y,26,47+y], fill=EAR_INNER)
    draw.ellipse([54,42+y,62,47+y], fill=EAR_INNER)

def _tail(draw, y=0, phase=0):
    offsets = [0, 3, 0, -3]
    tip = offsets[phase % 4]
    draw.arc([58,48+y+tip,74,64+y], start=270, end=90, fill=BODY, width=3)

def _text(draw, txt, x, y, color=ZZZ_COLOR):
    draw.text((x, y), txt, fill=color)


def _save_gif(frames, path, duration=150):
    """Save RGBA frames as animated GIF with transparency."""
    # Convert RGBA to palette mode with transparency
    processed = []
    for f in frames:
        # Create a palette image with transparency
        rgb = Image.new('RGB', f.size, (0, 0, 0))
        rgb.paste(f, mask=f.split()[3])
        p = rgb.quantize(colors=255, method=2)
        # Set transparency for black background pixels
        mask = f.split()[3]
        p_data = list(p.getdata())
        m_data = list(mask.getdata())
        for i in range(len(p_data)):
            if m_data[i] < 128:
                p_data[i] = 255  # transparent index
        p.putdata(p_data)
        p.info['transparency'] = 255
        processed.append(p)

    processed[0].save(
        path,
        save_all=True,
        append_images=processed[1:],
        duration=duration,
        loop=0,
        transparency=255,
        disposal=2,
    )


def gen_sleeping():
    frames = []
    for i in range(4):
        img = _new(); draw = ImageDraw.Draw(img)
        y = [0,-1,-2,-1][i]
        _body(draw,y); _ears(draw,y); _closed_eyes(draw,y)
        _nose(draw,y); _mouth_w(draw,y); _paws(draw,y)
        zzz = ["","z","zZ","zZz"][i]
        if zzz: _text(draw, zzz, 58, 14+y)
        frames.append(img)
    return frames

def gen_connecting():
    frames = []
    for i in range(3):
        img = _new(); draw = ImageDraw.Draw(img)
        _body(draw); _ears(draw)
        [_half_eyes, _open_eyes, _half_eyes][i](draw)
        _nose(draw); _mouth_w(draw); _paws(draw)
        _text(draw, "."*(i+1), 36, 8, EYE_GREEN)
        frames.append(img)
    return frames

def gen_idle():
    frames = []
    for i in range(6):
        img = _new(); draw = ImageDraw.Draw(img)
        _body(draw); _ears(draw)
        _closed_eyes(draw) if i >= 4 else _open_eyes(draw)
        _nose(draw); _mouth_w(draw); _paws(draw); _tail(draw, phase=i)
        frames.append(img)
    return frames

def gen_thinking():
    frames = []
    for i in range(4):
        img = _new(); draw = ImageDraw.Draw(img)
        _body(draw); _ears(draw); _open_eyes(draw, look_up=True)
        _nose(draw); _mouth_w(draw); _paws(draw)
        for d in range((i%3)+1):
            draw.ellipse([34+d*8,4,38+d*8,8], fill=EYE_GREEN)
        frames.append(img)
    return frames

def gen_talking():
    frames = []
    for i in range(4):
        img = _new(); draw = ImageDraw.Draw(img)
        y = [0,-2,0,-1][i]
        _body(draw,y); _ears(draw,y); _happy_eyes(draw,y); _cheeks(draw,y)
        _nose(draw,y)
        _mouth_open(draw,y) if i%2==0 else _mouth_w(draw,y)
        _paws(draw,y)
        frames.append(img)
    return frames

def gen_done():
    """Cat pooping — task completed, produced output! 💩"""
    frames = []
    for i in range(4):
        img = _new(); draw = ImageDraw.Draw(img)
        y = [0, -1, -2, 0][i]
        _body(draw, y); _ears(draw, y)
        # strained/satisfied face
        if i < 2:
            _closed_eyes(draw, y)  # straining
        else:
            _happy_eyes(draw, y)   # relief!
            _cheeks(draw, y)
        _nose(draw, y); _mouth_open(draw, y); _paws(draw, y)
        # poop emoji growing
        if i >= 1:
            px, py = 60, 62 + y
            sz = min(i * 4, 10)
            draw.ellipse([px, py-sz, px+sz, py], fill=POOP_BROWN)
            if i >= 2:
                draw.ellipse([px+1, py-sz-4, px+sz-2, py-sz+2], fill=POOP_BROWN)
            if i >= 3:
                # done checkmark
                _text(draw, "✓", 62, 4, DONE_GREEN)
        frames.append(img)
    return frames

def gen_error():
    frames = []
    for i in range(2):
        img = _new(); draw = ImageDraw.Draw(img)
        _body(draw); _ears(draw, droopy=True); _x_eyes(draw)
        _nose(draw); _mouth_sad(draw); _paws(draw)
        if i == 1:
            shifted = Image.new('RGBA', (S,S), (0,0,0,0))
            shifted.paste(img, (1, 0))
            frames.append(shifted)
        else:
            frames.append(img)
    return frames


def main():
    out = os.path.join(os.path.dirname(__file__), "ui", "assets")
    os.makedirs(out, exist_ok=True)

    generators = {
        "sleeping": gen_sleeping,
        "connecting": gen_connecting,
        "idle": gen_idle,
        "thinking": gen_thinking,
        "talking": gen_talking,
        "done": gen_done,
        "error": gen_error,
    }
    for name, gen in generators.items():
        frames = gen()
        path = os.path.join(out, f"{name}.gif")
        _save_gif(frames, path, duration=200)
        print(f"  {name}.gif ({len(frames)} frames)")

    print(f"\nPlaceholder GIFs saved to {out}/")
    print("Replace them with your own AI-generated GIFs!")


if __name__ == "__main__":
    main()
