"""Tests para correlation_ratio."""

import math
import random

from correlation_ratio import correlation_ratio


def test_high_eta_when_groups_separated():
    # Tres grupos con medias muy distintas y poca varianza intra-grupo -> eta alto.
    categories = ["A", "A", "A", "B", "B", "B", "C", "C", "C"]
    values = [1, 2, 1, 10, 11, 10, 20, 21, 20]
    eta = correlation_ratio(categories, values)
    assert eta > 0.8


def test_low_eta_when_random():
    # Categoria asignada al azar, valores gaussianos independientes -> eta bajo.
    random.seed(0)
    cats = [random.choice(["x", "y", "z"]) for _ in range(500)]
    vals = [random.gauss(0.0, 1.0) for _ in range(500)]
    eta = correlation_ratio(cats, vals)
    assert eta < 0.2


def test_single_group_returns_zero():
    # Menos de 2 grupos distintos -> 0.0
    assert correlation_ratio(["A", "A", "A"], [1.0, 2.0, 3.0]) == 0.0


def test_zero_total_variance_returns_zero():
    # Todos los valores iguales -> varianza total 0 -> 0.0
    assert correlation_ratio(["A", "B", "C"], [5.0, 5.0, 5.0]) == 0.0


def test_skips_none_and_nan_pairs():
    # Los pares con categoria None o valor None/NaN/no-numerico se descartan
    # sin afectar el resultado de los pares validos.
    base_cats = ["A", "A", "B", "B"]
    base_vals = [1.0, 1.0, 9.0, 9.0]
    clean = correlation_ratio(base_cats, base_vals)

    noisy_cats = ["A", "A", "B", "B", None, "C", "D"]
    noisy_vals = [1.0, 1.0, 9.0, 9.0, 7.0, float("nan"), "no-num"]
    noisy = correlation_ratio(noisy_cats, noisy_vals)

    assert math.isclose(clean, noisy, rel_tol=1e-9, abs_tol=1e-9)
    assert clean == 1.0  # grupos perfectamente separados y constantes -> eta = 1


def test_result_in_unit_range():
    random.seed(7)
    cats = [random.choice(["p", "q"]) for _ in range(200)]
    vals = [random.gauss(2.0, 3.0) for _ in range(200)]
    eta = correlation_ratio(cats, vals)
    assert 0.0 <= eta <= 1.0
