"""Unit tests for the drift-check comparison logic (hermetic — no network). The
source fetch (check_cell) is not tested here; it runs on a networked box."""
import datetime
import math

import polars as pl
import pytest

import drift_check
from data import climate

_D = [datetime.date(2024, 1, d) for d in (1, 2, 3)]


def test_compare_values_stats():
    a = pl.DataFrame({"date": _D, "tmax": [70.0, 80.0, 90.0], "wind": [5.0, 6.0, 7.0]})
    b = pl.DataFrame({"date": _D, "tmax": [72.0, 78.0, 90.0], "wind": [5.0, 6.0, 7.0]})
    out = drift_check.compare_values(a, b, metrics=("tmax", "wind"))
    assert out["tmax"] == {"n": 3, "mad": pytest.approx(4 / 3, abs=1e-3),
                           "bias": pytest.approx(0.0), "max_abs": pytest.approx(2.0)}
    assert out["wind"] == {"n": 3, "mad": 0.0, "bias": 0.0, "max_abs": 0.0}


def test_compare_values_skips_nulls_and_missing_metric():
    a = pl.DataFrame({"date": _D, "tmax": [70.0, 80.0, 90.0]})
    b = pl.DataFrame({"date": _D, "tmax": [71.0, None, 90.0]})
    out = drift_check.compare_values(a, b, metrics=("tmax", "gust"))
    assert out["tmax"]["n"] == 2                     # the null day is dropped
    assert out["tmax"]["mad"] == pytest.approx(0.5)  # |70-71| and |90-90|
    assert "gust" not in out                         # metric absent from both frames


def _gradeable(n=800):
    """A finalized, gradeable multi-year frame (seasonal temp swing so windows have a
    real distribution)."""
    start = datetime.date(2019, 1, 1)
    dates = [start + datetime.timedelta(days=i) for i in range(n)]
    tmax = [70.0 + 15.0 * math.sin(i / 58.0) for i in range(n)]
    tmin = [t - 15.0 for t in tmax]
    return climate._finalize_frame(pl.DataFrame({
        "date": dates, "tmax": tmax, "tmin": tmin, "precip": [0.0] * n,
        "wind": [5.0] * n, "gust": [8.0] * n, "humid": [60.0] * n,
        "fmax": tmax, "fmin": tmin,
    }))


def test_grade_band_divergence_identical_is_zero():
    f = _gradeable()
    end = f["date"].max()
    start = end - datetime.timedelta(days=60)
    div = drift_check.grade_band_divergence(f, f, start, end)
    assert div                                        # some metrics were compared
    assert any(s["compared"] > 0 for s in div.values())
    assert all(s["differ"] == 0 for s in div.values())   # identical frames never diverge
    assert all(s["pct"] == 0.0 for s in div.values())
