"""Tests para image_compare_side_by_side."""

import sys
import os

sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))

import pytest

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

from PIL import Image
from image_compare_side_by_side import image_compare_side_by_side


def _black(w=16, h=16):
    return Image.new("RGB", (w, h), color=(0, 0, 0))


def _white(w=16, h=16):
    return Image.new("RGB", (w, h), color=(255, 255, 255))


# ---------------------------------------------------------------------------
# Grid shape
# ---------------------------------------------------------------------------

def test_grid_es_pil_image_con_dimensiones_correctas_show_diff_True():
    """grid es PIL.Image con dimensiones correctas show_diff=True"""
    w, h = 16, 16
    gap = 16
    result = image_compare_side_by_side(_black(w, h), _white(w, h), gap_px=gap, show_diff=True)

    grid = result["grid"]
    assert isinstance(grid, Image.Image), "grid debe ser PIL.Image.Image"

    expected_w = 3 * w + 4 * gap   # A + diff + B + 4 gaps
    expected_h = h + 2 * gap
    assert grid.size == (expected_w, expected_h), (
        f"Esperado ({expected_w}, {expected_h}), got {grid.size}"
    )


def test_grid_es_pil_image_sin_diff_show_diff_False():
    """grid es PIL.Image sin diff show_diff=False"""
    w, h = 16, 16
    gap = 8
    result = image_compare_side_by_side(_black(w, h), _white(w, h), gap_px=gap, show_diff=False)

    grid = result["grid"]
    assert isinstance(grid, Image.Image), "grid debe ser PIL.Image.Image"

    expected_w = 2 * w + 3 * gap   # A + B + 3 gaps
    expected_h = h + 2 * gap
    assert grid.size == (expected_w, expected_h), (
        f"Esperado ({expected_w}, {expected_h}), got {grid.size}"
    )


# ---------------------------------------------------------------------------
# MSE
# ---------------------------------------------------------------------------

def test_pixel_mse_positivo_para_imagenes_distintas():
    """pixel_mse positivo para imagenes distintas"""
    result = image_compare_side_by_side(_black(), _white())
    mse = result["pixel_mse"]
    assert isinstance(mse, float), f"pixel_mse debe ser float, got {type(mse)}"
    assert mse > 0.0, f"pixel_mse debe ser > 0 para imagenes distintas, got {mse}"


def test_pixel_mse_cero_para_imagen_identica():
    """pixel_mse cero para imagen identica"""
    img = _black()
    result = image_compare_side_by_side(img, img.copy())
    mse = result["pixel_mse"]
    assert mse == 0.0, f"pixel_mse debe ser 0.0 para imagenes identicas, got {mse}"


# ---------------------------------------------------------------------------
# pHash
# ---------------------------------------------------------------------------

def test_phash_none_si_imagehash_no_disponible():
    """phash None si imagehash no disponible"""
    try:
        import imagehash  # noqa: F401
        pytest.skip("imagehash esta instalado — test de fallback no aplica")
    except ImportError:
        pass

    result = image_compare_side_by_side(_black(), _white(), show_phash=True)
    assert result["phash_a"] is None, "phash_a debe ser None si imagehash no instalado"
    assert result["phash_b"] is None, "phash_b debe ser None si imagehash no instalado"
    assert result["phash_distance"] is None, "phash_distance debe ser None si imagehash no instalado"


def test_phash_presente_si_imagehash_disponible():
    """phash presente si imagehash disponible"""
    try:
        import imagehash  # noqa: F401
    except ImportError:
        pytest.skip("imagehash no instalado")

    result = image_compare_side_by_side(_black(), _white(), show_phash=True)
    assert isinstance(result["phash_a"], str), "phash_a debe ser str"
    assert isinstance(result["phash_b"], str), "phash_b debe ser str"
    assert isinstance(result["phash_distance"], int), "phash_distance debe ser int"
    assert len(result["phash_a"]) == 16, f"phash_a debe tener 16 hex chars, got {len(result['phash_a'])}"


# ---------------------------------------------------------------------------
# Campos del resultado
# ---------------------------------------------------------------------------

def test_resultado_tiene_todas_las_claves():
    """resultado tiene todas las claves esperadas"""
    result = image_compare_side_by_side(_black(), _white())
    for key in ("grid", "phash_a", "phash_b", "phash_distance", "pixel_mse"):
        assert key in result, f"Clave '{key}' faltante en resultado"


def test_show_phash_false_deja_phash_none():
    """show_phash=False deja phash* en None sin intentar import"""
    result = image_compare_side_by_side(_black(), _white(), show_phash=False)
    assert result["phash_a"] is None
    assert result["phash_b"] is None
    assert result["phash_distance"] is None
