"""Judgment #22 — the transferred-straggler rule (T-MIG-006/012).

A transferred-but-not-invoiced row attaches to the EXISTING per-org
"Legacy transfers" invoice with a WARNING; the run NEVER aborts; if the
org somehow lacks the sentinel it is created with a louder warning. The
resulting old-vs-new diff is pinned row-for-row, exactly as the
allowlist rules require (spec.md)."""

from sqlalchemy import text

from harness.compare import DEFAULT_ALLOWLIST, load_allowlist, run_compare
from tests.migrate.conftest import INV_LEGACY, TE, U_RIAN, extract_both, rows, scalar

SHIPPED = load_allowlist(DEFAULT_ALLOWLIST)


def _make_straggler(engine, entry_id: str) -> None:
    with engine.begin() as conn:
        conn.execute(text(
            "UPDATE legacy.time_entries SET transferred_at = '2026-06-30T00:00:00Z',"
            " transferred_by = :uid, invoice_id = NULL, invoice_applied_at = NULL,"
            " invoice_applied_by = NULL WHERE id = :id"
        ), {"uid": U_RIAN, "id": entry_id})


def test_straggler_attaches_to_existing_sentinel_with_warning(
    mig_engine, mig_url, legacy_loaded, reload_fixture
):
    from app.services.migrate import run_all

    try:
        _make_straggler(mig_engine, TE[7])
        report = run_all(engine=mig_engine)

        # never aborts; reported + warned, not an error
        assert report.ok, report.render()
        assert report.straggler_count == 1
        assert report.straggler_entry_ids == [TE[7]]
        assert any("JUDGMENT #22" in w for w in report.warnings)
        # no escalation — the sentinel already existed
        assert not any("ESCALATION" in w for w in report.warnings)

        # attached to the EXISTING per-org sentinel; NO new invoice
        assert scalar(mig_engine, "SELECT count(*) FROM invoices") == 3
        attached = rows(
            mig_engine,
            "SELECT il.invoice_id::text, il.attached_at AT TIME ZONE 'UTC',"
            " u.idauth_username FROM time_entries te"
            " JOIN invoice_lines il ON il.id = te.invoice_line_id"
            " LEFT JOIN users u ON u.id = il.attached_by WHERE te.id = :id",
            id=TE[7],
        )[0]
        assert attached[0] == INV_LEGACY
        assert str(attached[1]) == "2026-06-30 00:00:00"  # transferred_at carries
        assert attached[2] == "rian"  # transferred_by re-keyed

        # the diff is explained row-for-row: exactly the sentinel-invoice
        # paths differ, and pinning them (as the allowlist doc requires)
        # turns the compare green
        old_doc, new_doc = extract_both(mig_url)
        report_diff = run_compare(old_doc, new_doc, SHIPPED)
        assert not report_diff.ok
        assert {d.path for d in report_diff.failures} == {
            f"invoices/{INV_LEGACY}/attached_entry_ids",
            f"invoices/{INV_LEGACY}/entry_count",
            f"invoices/{INV_LEGACY}/computed_total/CAD",
        }
        pinned = SHIPPED + [{
            "path": f"invoices/{INV_LEGACY}/*",
            "reason": f"judgment #22 straggler {TE[7]} attached by migration",
        }]
        assert run_compare(old_doc, new_doc, pinned).ok
    finally:
        reload_fixture()
        report = run_all(engine=mig_engine)
        assert report.ok and report.straggler_count == 0


def test_missing_sentinel_is_created_with_louder_warning(
    mig_engine, legacy_loaded, reload_fixture
):
    from app.services.migrate import run_all

    try:
        # strip the org's sentinel entirely: te-6 becomes a straggler and
        # the 'Legacy transfers' invoice is gone
        with mig_engine.begin() as conn:
            conn.execute(text(
                "UPDATE legacy.time_entries SET invoice_id = NULL,"
                " invoice_applied_at = NULL, invoice_applied_by = NULL"
                " WHERE id = :id"
            ), {"id": TE[6]})
            conn.execute(text(
                "DELETE FROM legacy.invoices WHERE id = :id"), {"id": INV_LEGACY})
        report = run_all(engine=mig_engine)

        assert report.ok, report.render()  # create-if-absent keeps it total
        assert report.straggler_count == 1
        assert any("ESCALATION" in w for w in report.warnings)
        name, status = rows(
            mig_engine,
            "SELECT i.name, i.status FROM time_entries te"
            " JOIN invoice_lines il ON il.id = te.invoice_line_id"
            " JOIN invoices i ON i.id = il.invoice_id WHERE te.id = :id",
            id=TE[6],
        )[0]
        assert (name, status) == ("Legacy transfers", "paid")
    finally:
        reload_fixture()
        report = run_all(engine=mig_engine)
        assert report.ok and report.straggler_count == 0
