"""Reporting services exercised against the REAL sidecar data.

These are invariants and floors that hold whatever the data happens to
be — a partition identity, a latency budget, and a helper guard — so
they stay meaningful as rian's live books change underneath them.

The cent-exact **oracle equivalence** gate that used to live here was
retired in ADR #028. It diffed the live database against a frozen
`harness/out/e2e-new.json` baseline to prove the rebuild reproduced the
old app's arithmetic; once `with` became the system of record there was
no second system left to agree with, and the check could only ever
report that live data had moved on from a snapshot.
"""

from datetime import datetime

from app.services.reporting.entries import entry_totals
from app.services.reporting.filters import EntryFilters
from app.services.reporting.projects import project_summary
from app.services.reporting.summary import MonthWindow, summary_by_project


def month_window(month_key: str) -> MonthWindow:
    year, month = month_key.split("-")
    return MonthWindow(int(year), int(month))


def month_filters(month_key: str) -> EntryFilters:
    w = month_window(month_key)
    return EntryFilters(start=w.start, end=w.end, status="all")


def test_status_partition_on_real_data(real_session, real_rian):
    """pending + blocked + applied == all, over every real row."""
    counts = {
        status: entry_totals(
            real_session, real_rian, EntryFilters(status=status)
        )["row_count"]
        for status in ("all", "pending", "blocked", "applied")
    }
    assert counts["all"] >= 4593  # grows as the app takes new entries
    assert counts["pending"] + counts["blocked"] + counts["applied"] == counts["all"]
    transferred = entry_totals(
        real_session, real_rian, EntryFilters(status="transferred")
    )["row_count"]
    assert transferred == counts["applied"]


def test_perf_note_hot_endpoints_on_full_dataset(real_session, real_rian):
    """The M3 perf sanity floor (the real gate is the orchestrator's):
    totals/summary/rollup/list each finish well inside the budget on
    the full dataset."""
    import time

    budget_ms = 500
    timings = {}
    t0 = time.perf_counter()
    entry_totals(real_session, real_rian, EntryFilters(status="pending"))
    timings["entries_totals"] = (time.perf_counter() - t0) * 1000

    t0 = time.perf_counter()
    summary_by_project(real_session, real_rian, MonthWindow(2026, 6))
    timings["summary"] = (time.perf_counter() - t0) * 1000

    t0 = time.perf_counter()
    project_summary(real_session, real_rian, EntryFilters(status="all"))
    timings["projects"] = (time.perf_counter() - t0) * 1000

    from app.services.reporting.entries import list_entries

    t0 = time.perf_counter()
    list_entries(real_session, real_rian, EntryFilters(status="pending"))
    timings["entries_page"] = (time.perf_counter() - t0) * 1000

    slow = {k: v for k, v in timings.items() if v > budget_ms}
    assert not slow, f"over the {budget_ms}ms floor: {slow} (all: {timings})"


def test_datetime_boundary_sanity():
    """Guard the month_filters helper itself."""
    f = month_filters("2026-12")
    assert f.start == datetime(2026, 12, 1) and f.end == datetime(2027, 1, 1)
