from pathlib import Path

from PIL import Image


ROOT = Path(__file__).resolve().parent
OUTPUT = ROOT.parents[1] / "assets" / "kubejs" / "textures" / "item"
OUTPUT.mkdir(parents=True, exist_ok=True)

CANVAS_SIZE = 32
SUBJECT_SIZE = 28


def downscale(name: str) -> None:
    source = Image.open(ROOT / f"{name}_minecraft_master.png").convert("RGBA")
    # Remove any solid-green pixels left by small color variations in the
    # generated chroma background before calculating the subject bounds.
    cleaned_pixels = []
    for red, green, blue, alpha in source.getdata():
        if green > 120 and green > red + 60 and green > blue + 60:
            cleaned_pixels.append((red, green, blue, 0))
        else:
            cleaned_pixels.append((red, green, blue, alpha))
    source.putdata(cleaned_pixels)

    alpha = source.getchannel("A")
    bbox = alpha.getbbox()
    if bbox is None:
        raise RuntimeError(f"{name}: source has no visible pixels")

    cropped = source.crop(bbox)
    target_box = SUBJECT_SIZE
    scale = min(target_box / cropped.width, target_box / cropped.height)
    size = (
        max(1, round(cropped.width * scale)),
        max(1, round(cropped.height * scale)),
    )
    sprite = cropped.resize(size, Image.Resampling.NEAREST)

    # Keep a strict logical pixel grid: nearest-neighbor only, with hard alpha.
    # A 32x32 canvas preserves the generated highlights that disappeared at 16x16.
    sprite_alpha = sprite.getchannel("A").point(lambda value: 255 if value >= 128 else 0)
    sprite = sprite.convert("RGB").quantize(
        colors=24,
        method=Image.Quantize.MEDIANCUT,
        dither=Image.Dither.NONE,
    ).convert("RGBA")
    sprite.putalpha(sprite_alpha)

    canvas = Image.new("RGBA", (CANVAS_SIZE, CANVAS_SIZE), (0, 0, 0, 0))
    position = (
        (CANVAS_SIZE - size[0]) // 2,
        (CANVAS_SIZE - size[1]) // 2,
    )
    canvas.alpha_composite(sprite, position)
    canvas.save(OUTPUT / f"{name}.png", optimize=False)


for texture_name in (
    "uncommon_ink_base",
    "rare_ink_base",
    "legendary_ink_base",
):
    downscale(texture_name)
