"""Tests for the retail/web per-region forecaster."""
import numpy as np

from forecast_v4.retail import forecast_retail, _apply_bounds, _seasonal


def test_stable_series_forecast_near_level():
    qty = np.full(40, 200.0)
    fc, model, up = forecast_retail(qty, h=13)
    assert len(fc) == 13
    assert np.all(np.abs(fc - 200) < 40), fc[:3]


def test_promo_deflated_before_forecast():
    # 40 normal weeks @300, 8 promo weeks @1500 at the end; forecast should track
    # the ~300 baseline, not the inflated promo level.
    qty = np.full(48, 300.0); qty[40:] = 1500.0
    mask = np.zeros(48, bool); mask[40:] = True
    fc, model, up = forecast_retail(qty, promo_mask=mask, h=13)
    assert up > 3.0
    assert np.all(fc < 600), f"forecast not deflated: {fc[:3]}"


def test_cap_prevents_runaway():
    y = np.full(20, 100.0)
    capped = _apply_bounds(np.full(13, 10000.0), y)
    assert np.all(capped <= 2.0 * 100 + 1e-6)


def test_floor_prevents_zero():
    y = np.full(20, 100.0)
    floored = _apply_bounds(np.zeros(13), y)
    assert np.all(floored >= 0.5 * 100 - 1e-6)


def test_seasonal_uses_week_index():
    # Strong weekly seasonality: even weeks high, odd low.
    weeks = np.array([(i % 52) + 1 for i in range(60)])
    y = np.where(weeks % 2 == 0, 300.0, 100.0)
    fc = _seasonal(y, weeks, start_cw=2, h=4)   # start on an even week
    assert fc[0] > fc[1], "seasonal index not applied"


def test_returns_valid_model_name():
    qty = np.full(40, 150.0)
    _, model, _ = forecast_retail(qty, h=13)
    assert model in ("ses", "wma", "seasonal")
