"""Tests para image_grid — combina imagenes en grid NxM."""

import sys

sys.path.insert(0, "python/functions/ml")

import math
import pytest

PIL = pytest.importorskip("PIL", reason="Pillow no instalado — skipping")

from image_grid import image_grid


def _make_images(n: int, w: int = 16, h: int = 16):
    from PIL import Image
    return [Image.new("RGB", (w, h), color=(i * 10, i * 10, i * 10)) for i in range(n)]


def test_grid_4_imagenes_2_cols_dimensiones_correctas():
    """grid de 4 imagenes 16x16 cols=2 produce ancho/alto correcto"""
    images = _make_images(4, w=16, h=16)
    result = image_grid(images, cols=2, gap_px=0)

    # rows = ceil(4/2) = 2
    # canvas_w = 2*16 + 3*0 = 32 (con gap_px=0: cols*w + (cols+1)*0)
    # canvas_h = 2*16 + 3*0 = 32
    assert result.width == 32, f"Ancho esperado 32, got {result.width}"
    assert result.height == 32, f"Alto esperado 32, got {result.height}"


def test_grid_4_imagenes_2_cols_con_gap():
    """grid de 4 imagenes cols=2 gap_px=8 tiene dimensiones correctas con gap"""
    images = _make_images(4, w=16, h=16)
    gap = 8
    cols = 2
    rows = math.ceil(4 / cols)
    expected_w = cols * 16 + (cols + 1) * gap
    expected_h = rows * 16 + (rows + 1) * gap

    result = image_grid(images, cols=cols, gap_px=gap)
    assert result.width == expected_w, f"Ancho: expected {expected_w}, got {result.width}"
    assert result.height == expected_h, f"Alto: expected {expected_h}, got {result.height}"


def test_grid_1_imagen_1_col():
    """grid de 1 imagen 1 col = imagen sola mas gaps"""
    images = _make_images(1, w=32, h=32)
    result = image_grid(images, cols=1, gap_px=4)
    # rows=1, cols=1 → w = 1*32 + 2*4 = 40, h = 1*32 + 2*4 = 40
    assert result.width == 40
    assert result.height == 40


def test_grid_retorna_imagen_rgb():
    """el resultado es una imagen RGB"""
    from PIL import Image
    images = _make_images(2, w=8, h=8)
    result = image_grid(images, cols=2)
    assert isinstance(result, Image.Image)
    assert result.mode == "RGB"


def test_grid_con_labels_no_falla():
    """labels opcionales — no lanza excepcion"""
    images = _make_images(4, w=16, h=16)
    labels = ["a", "b", "c", "d"]
    result = image_grid(images, cols=2, labels=labels, gap_px=0)
    # Debe devolver imagen válida
    assert result.width > 0
    assert result.height > 0


def test_grid_sin_labels_no_falla():
    """sin labels funciona correctamente"""
    images = _make_images(3, w=16, h=16)
    result = image_grid(images, cols=3, labels=None, gap_px=0)
    assert result.width == 3 * 16
    assert result.height == 16  # 1 row


def test_grid_lista_vacia_levanta_value_error():
    """lista vacia levanta ValueError"""
    with pytest.raises(ValueError):
        image_grid([], cols=2)
