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


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

    dry_run_resp = client.post(
        f"/status/{job_id}/critic/findings/bulk-status",
        headers={"X-Actor": "bulk_previewer"},
        json={"next_status": "resolved", "apply_to_all": True, "dry_run": True},
    )
    assert dry_run_resp.status_code == 200
    dry_run_body = dry_run_resp.json()
    assert dry_run_body["dry_run"] is True
    assert dry_run_body["persisted"] is False
    assert dry_run_body["matched_count"] == 2
    assert dry_run_body["changed_count"] == 2
    assert all(str(item.get("status") or "") == "resolved" for item in dry_run_body["updated_findings"])

    after_preview = critic_statuses(job_id)
    assert after_preview["dry-f1"] == "open"
    assert after_preview["dry-f2"] == "open"

    commit_resp = client.post(
        f"/status/{job_id}/critic/findings/bulk-status",
        headers={"X-Actor": "bulk_reviewer"},
        json={"next_status": "resolved", "apply_to_all": True},
    )
    assert commit_resp.status_code == 200
    commit_body = commit_resp.json()
    assert commit_body["dry_run"] is False
    assert commit_body["persisted"] is True
    assert commit_body["changed_count"] == 2

    after_commit = critic_statuses(job_id)
    assert after_commit["dry-f1"] == "resolved"
    assert after_commit["dry-f2"] == "resolved"


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

    dry_run_resp = client.post(
        f"/status/{job_id}/critic/findings/bulk-status",
        headers={"X-Actor": "bulk_finding_previewer"},
        json={
            "next_status": "acknowledged",
            "finding_ids": ["dry-selected-f1", "dry-selected-missing"],
            "dry_run": True,
        },
    )
    assert dry_run_resp.status_code == 200
    dry_run_body = dry_run_resp.json()
    assert dry_run_body["dry_run"] is True
    assert dry_run_body["persisted"] is False
    assert dry_run_body["requested_status"] == "acknowledged"
    assert dry_run_body["actor"] == "bulk_finding_previewer"
    assert dry_run_body["matched_count"] == 1
    assert dry_run_body["changed_count"] == 1
    assert dry_run_body["unchanged_count"] == 0
    assert dry_run_body["not_found_finding_ids"] == ["dry-selected-missing"]
    assert dry_run_body["updated_findings"][0]["finding_id"] == "dry-selected-f1"
    assert dry_run_body["updated_findings"][0]["status"] == "acknowledged"

    after_preview = critic_statuses(job_id)
    assert after_preview["dry-selected-f1"] == "open"
    assert after_preview["dry-selected-f2"] == "open"
