"""Tests para read_xlsx.

Se importa el modulo por path directo (sin tocar __init__.py) para no depender
del re-export del paquete. write_xlsx_sheets se importa igual para el round-trip.
"""

import importlib.util
import os

_HERE = os.path.dirname(os.path.abspath(__file__))


def _load(name):
    spec = importlib.util.spec_from_file_location(name, os.path.join(_HERE, f"{name}.py"))
    mod = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(mod)
    return mod


read_xlsx = _load("read_xlsx").read_xlsx
write_xlsx_sheets = _load("write_xlsx_sheets").write_xlsx_sheets


def test_round_trip_escribe_lee_compara(tmp_path):
    """Escribir con write_xlsx_sheets y leer con read_xlsx devuelve los mismos datos."""
    out = str(tmp_path / "rt.xlsx")
    write_xlsx_sheets(
        out,
        {
            "Ventas": [
                ["Producto", "Unidades", "Precio", "Activo"],
                ["Teclado", 12, 29.99, True],
                ["Raton", 30, 14.5, False],
                ["Monitor", None, 199.0, True],
            ],
        },
    )

    res = read_xlsx(out)
    assert res["status"] == "ok"
    assert list(res["sheets"].keys()) == ["Ventas"]

    ventas = res["sheets"]["Ventas"]
    assert ventas["headers"] == ["Producto", "Unidades", "Precio", "Activo"]
    assert ventas["rows"] == [
        ["Teclado", 12, 29.99, True],
        ["Raton", 30, 14.5, False],
        ["Monitor", None, 199.0, True],
    ]


def test_lee_solo_la_hoja_indicada(tmp_path):
    out = str(tmp_path / "multi.xlsx")
    write_xlsx_sheets(
        out,
        {
            "A": [["x"], [1]],
            "B": [["y"], [2]],
        },
    )

    res = read_xlsx(out, sheet="B")
    assert res["status"] == "ok"
    assert list(res["sheets"].keys()) == ["B"]
    assert res["sheets"]["B"]["headers"] == ["y"]
    assert res["sheets"]["B"]["rows"] == [[2]]


def test_max_rows_trunca_filas_de_datos(tmp_path):
    out = str(tmp_path / "trunc.xlsx")
    write_xlsx_sheets(
        out,
        {"S": [["n"], [1], [2], [3], [4], [5]]},
    )

    res = read_xlsx(out, sheet="S", max_rows=2)
    assert res["status"] == "ok"
    assert res["sheets"]["S"]["headers"] == ["n"]
    assert res["sheets"]["S"]["rows"] == [[1], [2]]


def test_header_false_no_consume_cabecera(tmp_path):
    out = str(tmp_path / "nohdr.xlsx")
    write_xlsx_sheets(out, {"S": [["a", "b"], [1, 2]]})

    res = read_xlsx(out, sheet="S", header=False)
    assert res["status"] == "ok"
    assert res["sheets"]["S"]["headers"] == []
    assert res["sheets"]["S"]["rows"] == [["a", "b"], [1, 2]]


def test_fecha_se_devuelve_como_iso(tmp_path):
    import datetime

    from openpyxl import Workbook

    out = str(tmp_path / "fechas.xlsx")
    wb = Workbook()
    ws = wb.active
    ws.title = "F"
    ws.append(["evento", "cuando"])
    ws.append(["solo_fecha", datetime.date(2026, 6, 16)])
    ws.append(["con_hora", datetime.datetime(2026, 6, 16, 14, 30, 0)])
    wb.save(out)

    res = read_xlsx(out, sheet="F")
    assert res["status"] == "ok"
    rows = res["sheets"]["F"]["rows"]
    assert rows[0] == ["solo_fecha", "2026-06-16"]
    assert rows[1] == ["con_hora", "2026-06-16T14:30:00"]


def test_formula_se_lee_como_valor_calculado(tmp_path):
    """data_only lee el valor cacheado de la formula si Excel/openpyxl lo guardo.

    openpyxl no calcula formulas; cuando escribimos la formula con openpyxl el
    valor cacheado es None hasta que un motor (Excel/LibreOffice) la evalua y
    guarda. El round-trip valido es escribir el VALOR (no la formula).
    """
    out = str(tmp_path / "calc.xlsx")
    # Escribimos el valor resultante directamente: read_xlsx con data_only lo lee.
    write_xlsx_sheets(out, {"C": [["total"], [42]]})
    res = read_xlsx(out, sheet="C")
    assert res["status"] == "ok"
    assert res["sheets"]["C"]["rows"] == [[42]]


def test_archivo_inexistente_devuelve_error():
    res = read_xlsx("/tmp/no_existe_seguro_123456.xlsx")
    assert res["status"] == "error"
    assert "no encontrado" in res["error"]


def test_hoja_inexistente_devuelve_error(tmp_path):
    out = str(tmp_path / "h.xlsx")
    write_xlsx_sheets(out, {"Real": [["x"], [1]]})
    res = read_xlsx(out, sheet="Fantasma")
    assert res["status"] == "error"
    assert "no existe" in res["error"]


def test_path_vacio_devuelve_error():
    res = read_xlsx("")
    assert res["status"] == "error"
