"""HTTP contract for PATCH /api/projects/{id}/financials — the owner-only
income + billout-adjustment write surface (M8 last parity gap).

Runs over the shared migrated reporting scratch with REAL commits, so the
owner round-trip test RESTORES Site Rebuild's fixture financials in a
finally block (the other suites read those values)."""

SITE_REBUILD = "07000000-0000-0000-0000-000000000001"


def _site_row(client):
    rows = client.get("/api/projects", params={"status": "all"}).json()["rows"]
    return next(r for r in rows if r["project"] == "Site Rebuild")


def test_owner_financials_round_trip(as_rian):
    """Owner PATCH persists income + both adjustments; the rollup recomputes
    billout_adjusted + margin on the next fetch (verified feedback)."""
    before = _site_row(as_rian)
    try:
        resp = as_rian.patch(
            f"/api/projects/{SITE_REBUILD}/financials",
            json={
                "income": "20000",
                "billout_adjustment_pct": "20",
                "billout_adjustment_amount": "100",
            },
        )
        assert resp.status_code == 200, resp.text
        assert resp.json()["ok"] is True

        after = _site_row(as_rian)
        assert after["income"]["amount"] == "20000.00"
        # raw 142.50 * 1.20 + 100 = 271.00; margin = 20000 - cost 73.50
        assert after["billout"]["amount"] == "142.50"
        assert after["billout_adjusted"]["amount"] == "271.00"
        assert after["margin"]["amount"] == "19926.50"
    finally:
        # restore the fixture financials (income 12000 / pct 10 / amount 250)
        as_rian.patch(
            f"/api/projects/{SITE_REBUILD}/financials",
            json={
                "income": before["income"]["amount"],
                "billout_adjustment_pct": before["billout_adjustment_pct"],
                "billout_adjustment_amount": before["billout_adjustment_amount"]["amount"],
            },
        )
    restored = _site_row(as_rian)
    assert restored["income"]["amount"] == "12000.00"
    assert restored["billout_adjusted"]["amount"] == "406.75"


def test_manager_forbidden_structured(as_adi):
    """A manager (Adi) is refused with the structured owner-only triple —
    the write surface is owner-gated end-to-end."""
    resp = as_adi.patch(
        f"/api/projects/{SITE_REBUILD}/financials", json={"income": "1"}
    )
    assert resp.status_code == 403
    body = resp.json()
    assert body["error_code"] == "NOT_ALLOWED"
    assert body["summary"] == "Only an owner can edit project income."


def test_unknown_project_404(as_rian):
    resp = as_rian.patch(
        "/api/projects/00000000-0000-0000-0000-000000000000/financials",
        json={"income": "1"},
    )
    assert resp.status_code == 404
    assert resp.json()["error_code"] == "PROJECT_NOT_FOUND"


def test_negative_income_422(as_rian):
    resp = as_rian.patch(
        f"/api/projects/{SITE_REBUILD}/financials", json={"income": "-5"}
    )
    assert resp.status_code == 422
    assert resp.json()["error_code"] == "BAD_INCOME"
