"""Pipeline B: NOT_IN_835 visits → fresh 837Ps, batched by (member, ISO-week)."""
from datetime import date
from decimal import Decimal
from cyclone.rebill.pipeline_b import build_pipeline_b_batches
from cyclone.rebill.reconcile import VisitRow


def _v(date_, member, proc, amt):
    return VisitRow(date=date_, member_id=member, procedure=proc, billed=Decimal(amt))


def test_batches_split_by_member_and_iso_week():
    visits = [
        _v(date(2026, 6, 23), "J813715", "T1019", "2.32"),
        _v(date(2026, 6, 25), "J813715", "T1019", "2.32"),  # same week
        _v(date(2026, 6, 23), "OTHER",    "T1019", "2.32"),  # different member
        _v(date(2026, 6, 30), "J813715", "T1019", "2.32"),  # different week
    ]
    out = build_pipeline_b_batches(visits, as_of=date(2026, 7, 7), override=False)
    assert len(out) == 3
    sizes = sorted(len(b.visits) for b in out)
    assert sizes == [1, 1, 2]


def test_timely_filing_excludes_old_visits():
    visits = [
        _v(date(2026, 1, 1), "OLD", "T1019", "2.32"),  # 187 days old
        _v(date(2026, 6, 27), "NEW", "T1019", "2.32"), # 10 days old
    ]
    out = build_pipeline_b_batches(visits, as_of=date(2026, 7, 7), override=False)
    members = {b.member_id for b in out}
    assert "OLD" not in members
    assert "NEW" in members


def test_override_relaxes_timely_filing():
    visits = [_v(date(2026, 1, 1), "OLD", "T1019", "2.32")]
    out_default = build_pipeline_b_batches(visits, as_of=date(2026, 7, 7), override=False)
    out_overridden = build_pipeline_b_batches(visits, as_of=date(2026, 7, 7), override=True)
    assert out_default == []
    assert len(out_overridden) == 1


def test_override_flag_set_on_past_window_visit_batch():
    # Same member "OLD" with one past-window visit (187 days old, ISO
    # week 1) and one within-window visit (10 days old, ISO week 26).
    # With override=True the past-window visit survives and the batch
    # for week 1 must be flagged has_overridden_visits=True because the
    # override saved an otherwise-excluded visit.
    visits = [
        _v(date(2026, 1, 1), "OLD", "T1019", "2.32"),  # 187 days old (past window, W01)
        _v(date(2026, 6, 27), "OLD", "T1019", "2.32"),  # 10 days old (within window, W26)
    ]
    out_overridden = build_pipeline_b_batches(
        visits, as_of=date(2026, 7, 7), override=True,
    )
    # Two batches: one per (member, ISO-week) — the past-window visit and
    # the within-window visit land in different weeks.
    assert len(out_overridden) == 2
    by_week = {b.iso_week: b for b in out_overridden}
    assert by_week[1].member_id == "OLD"
    assert by_week[1].has_overridden_visits is True  # the override saved this batch
    assert by_week[26].member_id == "OLD"
    assert by_week[26].has_overridden_visits is False  # no override needed here

    # With override=False the past-window visit is dropped. The surviving
    # within-window batch (W26) must NOT carry the override flag, and the
    # past-window batch (W01) is absent.
    out_default = build_pipeline_b_batches(
        visits, as_of=date(2026, 7, 7), override=False,
    )
    assert len(out_default) == 1
    assert out_default[0].member_id == "OLD"
    assert out_default[0].iso_week == 26
    assert out_default[0].has_overridden_visits is False
