from grantflow.tests.critic_bulk_status_helpers import client, critic_statuses, set_bulk_critic_job


def test_status_critic_bulk_status_if_match_returns_conflict_without_changes():
    job_id = "critic-findings-bulk-if-match-1"
    set_bulk_critic_job(
        job_id,
        fatal_flaws=[
            {
                "finding_id": "bulk-if-f1",
                "code": "TOC_SCHEMA_INVALID",
                "severity": "high",
                "section": "toc",
                "status": "open",
                "message": "ToC invalid.",
                "source": "rules",
            },
            {
                "finding_id": "bulk-if-f2",
                "code": "LOGFRAME_BASELINE_MISSING",
                "severity": "medium",
                "section": "logframe",
                "status": "acknowledged",
                "message": "Missing baseline.",
                "source": "rules",
            },
        ],
    )

    conflict_resp = client.post(
        f"/status/{job_id}/critic/findings/bulk-status",
        json={"next_status": "resolved", "apply_to_all": True, "if_match_status": "open"},
        headers={"X-Actor": "bulk_reviewer"},
    )
    assert conflict_resp.status_code == 409
    conflict_body = conflict_resp.json()
    detail = conflict_body.get("detail") if isinstance(conflict_body, dict) else {}
    assert detail.get("code") == "finding_status_conflict"
    assert detail.get("if_match_status") == "open"
    assert int(detail.get("conflict_count") or 0) >= 1

    after_conflict = critic_statuses(job_id)
    assert after_conflict["bulk-if-f1"] == "open"
    assert after_conflict["bulk-if-f2"] == "acknowledged"

    success_resp = client.post(
        f"/status/{job_id}/critic/findings/bulk-status",
        json={"next_status": "resolved", "finding_ids": ["bulk-if-f2"], "if_match_status": "acknowledged"},
        headers={"X-Actor": "bulk_reviewer"},
    )
    assert success_resp.status_code == 200
    success_body = success_resp.json()
    assert success_body["changed_count"] == 1
    assert success_body["filters"]["if_match_status"] == "acknowledged"
    assert success_body["updated_findings"][0]["finding_id"] == "bulk-if-f2"
    assert success_body["updated_findings"][0]["status"] == "resolved"


def test_status_critic_bulk_status_request_id_is_idempotent():
    job_id = "critic-findings-bulk-request-id-1"
    set_bulk_critic_job(
        job_id,
        fatal_flaws=[
            {
                "finding_id": "bulk-rid-f1",
                "code": "TOC_SCHEMA_INVALID",
                "severity": "high",
                "section": "toc",
                "status": "open",
                "message": "ToC invalid.",
                "source": "rules",
            },
            {
                "finding_id": "bulk-rid-f2",
                "code": "LOGFRAME_BASELINE_MISSING",
                "severity": "medium",
                "section": "logframe",
                "status": "open",
                "message": "Missing baseline.",
                "source": "rules",
            },
        ],
    )

    first = client.post(
        f"/status/{job_id}/critic/findings/bulk-status",
        json={"next_status": "resolved", "apply_to_all": True, "request_id": "rid-bulk-1"},
        headers={"X-Actor": "bulk_reviewer"},
    )
    assert first.status_code == 200
    first_body = first.json()
    assert first_body["changed_count"] == 2
    assert first_body["request_id"] == "rid-bulk-1"
    assert first_body.get("idempotent_replay") is not True

    replay = client.post(
        f"/status/{job_id}/critic/findings/bulk-status",
        json={"next_status": "resolved", "apply_to_all": True, "request_id": "rid-bulk-1"},
        headers={"X-Actor": "bulk_reviewer"},
    )
    assert replay.status_code == 200
    replay_body = replay.json()
    assert replay_body["request_id"] == "rid-bulk-1"
    assert replay_body["idempotent_replay"] is True
    assert replay_body["changed_count"] == 2

    mismatch = client.post(
        f"/status/{job_id}/critic/findings/bulk-status",
        json={"next_status": "acknowledged", "apply_to_all": True, "request_id": "rid-bulk-1"},
        headers={"X-Actor": "bulk_reviewer"},
    )
    assert mismatch.status_code == 409
    mismatch_detail = mismatch.json().get("detail") or {}
    assert mismatch_detail.get("reason") == "request_id_reused_with_different_payload"
