"""Mosaic creation from extracted frames using Pillow."""

import os

from PIL import Image, ImageDraw, ImageFont

from .fonts import get_system_font

COLS = 4
ROWS = 5
TILE_WIDTH = 640
TILE_HEIGHT = 360
MOSAIC_WIDTH = COLS * TILE_WIDTH   # 2560
MOSAIC_HEIGHT = ROWS * TILE_HEIGHT  # 1800
LABEL_FONT_SIZE = 32
LABEL_PADDING = 8


def create_mosaic(frame_paths: list[str], output_path: str) -> str:
    """
    Combine frame images into a 4×5 mosaic with frame number labels.

    Parameters
    ----------
    frame_paths:
        Ordered list of exactly 20 frame image paths.
    output_path:
        Destination path for the mosaic image (JPEG).

    Returns
    -------
    The absolute path of the created mosaic image.
    """
    if len(frame_paths) != COLS * ROWS:
        raise ValueError(
            f"Expected {COLS * ROWS} frames, got {len(frame_paths)}."
        )

    mosaic = Image.new("RGB", (MOSAIC_WIDTH, MOSAIC_HEIGHT), color=(0, 0, 0))
    font = get_system_font(LABEL_FONT_SIZE, bold=True)

    for idx, frame_path in enumerate(frame_paths):
        col = idx % COLS
        row = idx // COLS
        x = col * TILE_WIDTH
        y = row * TILE_HEIGHT

        with Image.open(frame_path) as frame:
            frame = frame.resize((TILE_WIDTH, TILE_HEIGHT), Image.LANCZOS)
            mosaic.paste(frame, (x, y))

        draw = ImageDraw.Draw(mosaic)
        label = f"BILD {idx}"

        # Draw semi-transparent background for label readability
        bbox = draw.textbbox((x + LABEL_PADDING, y + LABEL_PADDING), label, font=font)
        draw.rectangle(
            [bbox[0] - 2, bbox[1] - 2, bbox[2] + 2, bbox[3] + 2],
            fill=(0, 0, 0, 180),
        )
        draw.text(
            (x + LABEL_PADDING, y + LABEL_PADDING),
            label,
            fill=(255, 255, 255),
            font=font,
        )

    mosaic.save(output_path, "JPEG", quality=90)
    return os.path.abspath(output_path)
