"""Tests para effect_size_cohens_d (tamano del efecto de dos grupos).

Importa el modulo hoja directamente (`effect_size_cohens_d`) para no depender de
que el paquete reexporte la funcion en su __init__ (lo integra el orquestador al
cerrar el grupo papers). El pytest del repo tiene pythonpath=["functions", ...],
asi que el modulo hoja se resuelve por su nombre directo.
"""

import math

from effect_size_cohens_d import effect_size_cohens_d


def test_golden_large_effect():
    # group_a: mean 3, var muestral 2.5; group_b: mean 5, var 2.5.
    # pooled_sd = sqrt(2.5) ~= 1.5811388.
    # cohens_d = (3-5)/1.5811388 ~= -1.264911.
    # J = 1 - 3/(4*10-9) = 1 - 3/31 = 0.9032258.
    # hedges_g = d * J = -1.2649111 * 0.9032258 ~= -1.142500.
    out = effect_size_cohens_d([1, 2, 3, 4, 5], [3, 4, 5, 6, 7])
    assert abs(out["cohens_d"] - (-1.26491)) < 1e-4
    assert abs(out["hedges_g"] - (-1.14250)) < 1e-4
    assert out["interpretation"] == "large"
    assert out["n_a"] == 5
    assert out["n_b"] == 5
    assert abs(out["mean_a"] - 3.0) < 1e-12
    assert abs(out["mean_b"] - 5.0) < 1e-12
    assert abs(out["pooled_sd"] - math.sqrt(2.5)) < 1e-9
    assert "note" not in out


def test_hedges_g_menor_en_magnitud_que_cohens_d():
    # La correccion J esta en (0, 1), asi que |g| < |d| siempre.
    out = effect_size_cohens_d([1, 2, 3, 4, 5], [3, 4, 5, 6, 7])
    assert abs(out["hedges_g"]) < abs(out["cohens_d"])


def test_interpretation_thresholds():
    # negligible: |d| < 0.2. Medias casi iguales con varianza grande.
    neg = effect_size_cohens_d([0, 10, 20, 30], [1, 11, 21, 31])
    assert neg["interpretation"] == "negligible"
    assert abs(neg["cohens_d"]) < 0.2

    # small: 0.2 <= |d| < 0.5.
    small = effect_size_cohens_d([0, 10, 20, 30], [4, 14, 24, 34])
    assert small["interpretation"] == "small"
    assert 0.2 <= abs(small["cohens_d"]) < 0.5

    # medium: 0.5 <= |d| < 0.8.
    medium = effect_size_cohens_d([0, 10, 20, 30], [9, 19, 29, 39])
    assert medium["interpretation"] == "medium"
    assert 0.5 <= abs(medium["cohens_d"]) < 0.8


def test_signo_positivo_cuando_a_mayor_que_b():
    out = effect_size_cohens_d([10, 12, 14, 16], [1, 2, 3, 4])
    assert out["cohens_d"] > 0
    assert out["interpretation"] == "large"


def test_varianza_cero_no_lanza():
    out = effect_size_cohens_d([5, 5, 5], [5, 5, 5])
    assert math.isnan(out["cohens_d"])
    assert math.isnan(out["hedges_g"])
    assert out["interpretation"] == "undefined"
    assert out["pooled_sd"] == 0.0
    assert "note" in out
    assert "varianza cero" in out["note"]


def test_n_insuficiente_no_lanza():
    out = effect_size_cohens_d([3], [1, 2, 3])
    assert math.isnan(out["cohens_d"])
    assert math.isnan(out["hedges_g"])
    assert out["interpretation"] == "undefined"
    assert out["n_a"] == 1
    assert out["n_b"] == 3
    assert "note" in out


def test_listas_vacias_no_lanza():
    out = effect_size_cohens_d([], [])
    assert math.isnan(out["cohens_d"])
    assert math.isnan(out["hedges_g"])
    assert out["interpretation"] == "undefined"
    assert out["n_a"] == 0
    assert out["n_b"] == 0
    assert "note" in out


def test_un_grupo_vacio_no_lanza():
    out = effect_size_cohens_d([1, 2, 3], [])
    assert math.isnan(out["cohens_d"])
    assert out["interpretation"] == "undefined"
    assert out["n_b"] == 0
    assert "note" in out
