"""Unit tests for thumbnail generation utility."""

import io

from PIL import Image as PILImage

from app.thumbnail import generate_thumbnail


def _make_jpeg(width: int, height: int) -> bytes:
    buf = io.BytesIO()
    img = PILImage.new("RGB", (width, height), color=(128, 64, 32))
    img.save(buf, format="JPEG", quality=80)
    return buf.getvalue()


def _make_png_rgba(width: int, height: int) -> bytes:
    buf = io.BytesIO()
    img = PILImage.new("RGBA", (width, height), color=(10, 20, 30, 180))
    img.save(buf, format="PNG")
    return buf.getvalue()


def _make_gif(width: int, height: int) -> bytes:
    buf = io.BytesIO()
    img = PILImage.new("P", (width, height))
    img.save(buf, format="GIF")
    return buf.getvalue()


def test_thumbnail_is_webp():
    data = _make_jpeg(600, 400)
    result = generate_thumbnail(data, "image/jpeg")
    assert result[:4] == b"RIFF"
    assert result[8:12] == b"WEBP"


def test_thumbnail_fits_within_400px():
    data = _make_jpeg(800, 600)
    result = generate_thumbnail(data, "image/jpeg")
    img = PILImage.open(io.BytesIO(result))
    w, h = img.size
    assert w <= 400
    assert h <= 400


def test_thumbnail_preserves_aspect_ratio():
    original_w, original_h = 800, 300
    data = _make_jpeg(original_w, original_h)
    result = generate_thumbnail(data, "image/jpeg")
    img = PILImage.open(io.BytesIO(result))
    w, h = img.size
    original_ratio = original_w / original_h
    thumb_ratio = w / h
    assert abs(original_ratio - thumb_ratio) / original_ratio < 0.01


def test_thumbnail_handles_gif_first_frame():
    data = _make_gif(500, 500)
    result = generate_thumbnail(data, "image/gif")
    assert result[8:12] == b"WEBP"
    img = PILImage.open(io.BytesIO(result))
    assert not getattr(img, "is_animated", False)


def test_thumbnail_handles_png_with_alpha():
    data = _make_png_rgba(300, 300)
    result = generate_thumbnail(data, "image/png")
    assert result[8:12] == b"WEBP"
    img = PILImage.open(io.BytesIO(result))
    assert img.format == "WEBP"


def test_thumbnail_does_not_upscale():
    data = _make_jpeg(100, 100)
    result = generate_thumbnail(data, "image/jpeg")
    img = PILImage.open(io.BytesIO(result))
    w, h = img.size
    assert w <= 100
    assert h <= 100
