"""Test the reconciliation logic in the assembly (DB-independent: monkeypatch
load_sku with a synthetic SKU)."""
import numpy as np

import forecast_v4.engine as eng


def _fake_sku():
    T = 60
    iso = [(i % 52) + 1 for i in range(T)]
    weeks = [202500 + i for i in range(T)]   # only weeks[-1] is used (for start_cw)
    retail = {"HR": (np.full(T, 200.0), np.full(T, 20.0)),
              "SI": (np.full(T, 30.0), np.full(T, 20.0))}
    web = {"HR": (np.full(T, 40.0), np.full(T, 20.0))}
    wholesale = {1: np.tile([0, 0, 0, 300.0], T // 4),   # ~monthly buyer
                 2: np.full(T, 50.0)}                      # weekly buyer
    return {"weeks": weeks, "iso": iso, "retail": retail, "web": web,
            "wholesale": wholesale, "promo_yws": set(), "covered_yws": set()}


def test_reconciled_leaves_sum_to_total(monkeypatch):
    monkeypatch.setattr(eng, "load_sku", lambda pid, max_yw=999999: _fake_sku())
    r = eng.forecast_sku(1, h=13, reconcile=True)
    leaf_sum = (sum(v["total13"] for v in r["retail"].values())
                + sum(v["total13"] for v in r["web"].values())
                + r["wholesale"]["total13"])
    assert abs(leaf_sum - r["total13"]) < 1.0, (leaf_sum, r["total13"])


def test_reconcile_off_uses_bottom_up(monkeypatch):
    monkeypatch.setattr(eng, "load_sku", lambda pid, max_yw=999999: _fake_sku())
    r = eng.forecast_sku(1, h=13, reconcile=False)
    assert abs(r["total13"] - r["bottom_up_total13"]) < 1e-6
    assert r["scale"] == 1.0


def test_regions_present(monkeypatch):
    monkeypatch.setattr(eng, "load_sku", lambda pid, max_yw=999999: _fake_sku())
    r = eng.forecast_sku(1, h=13)
    assert set(r["retail"]) == {"HR", "SI"}
    assert r["wholesale"]["n_buyers"] == 2
