import random

from app.schemas.grade_1.join_pictures_with_quantity import (
    JoinPicturesWithQuantityProblem,
    NumberCard,
    PictureAsset,
    PictureContainer,
)


def join_pictures_with_quantity(
    available_pictures: list[dict],
    container_count_per_side: int = 5,
    min_quantity: int = 1,
    max_quantity: int = 10,
    seed: int | None = None,
) -> dict:
    """Generate a count-and-match picture problem.

    The caller only provides the picture assets that exist in the project. The
    function chooses unique quantities, assigns pictures to the left and right
    containers, and returns a JSON-ready validated problem structure.

    Each picture must have: id, name, image_path.
    """
    if seed is not None:
        random.seed(seed)

    pictures = [PictureAsset.model_validate(picture) for picture in available_pictures]
    available_quantities = list(range(min_quantity, max_quantity + 1))

    if container_count_per_side < 1:
        raise ValueError("container_count_per_side must be at least 1")

    if len(available_quantities) < container_count_per_side:
        raise ValueError(
            "quantity range must contain at least container_count_per_side values"
        )

    required_picture_count = container_count_per_side * 2
    if len(pictures) < required_picture_count:
        raise ValueError(
            f"available_pictures must contain at least {required_picture_count} pictures"
        )

    number_card_values = random.sample(available_quantities, container_count_per_side)
    left_quantities = random.sample(number_card_values, len(number_card_values))
    right_quantities = random.sample(number_card_values, len(number_card_values))
    selected_pictures = random.sample(pictures, required_picture_count)

    left_pictures = selected_pictures[:container_count_per_side]
    right_pictures = selected_pictures[container_count_per_side:]

    problem = JoinPicturesWithQuantityProblem(
        left_containers=[
            PictureContainer(
                position=index + 1, quantity=quantity, picture=left_pictures[index]
            )
            for index, quantity in enumerate(left_quantities)
        ],
        number_cards=[
            NumberCard(position=index + 1, value=value)
            for index, value in enumerate(number_card_values)
        ],
        right_containers=[
            PictureContainer(
                position=index + 1, quantity=quantity, picture=right_pictures[index]
            )
            for index, quantity in enumerate(right_quantities)
        ],
    )

    return problem.model_dump()
