from copy import deepcopy

from fastapi.testclient import TestClient

from grantflow.api import runtime_state
from grantflow.api.app import app

client = TestClient(app)


def _base_fatal_flaws() -> list[dict]:
    return [
        {
            "finding_id": "bulk-f1",
            "code": "TOC_SCHEMA_INVALID",
            "severity": "high",
            "section": "toc",
            "status": "open",
            "message": "ToC invalid.",
            "source": "rules",
        },
        {
            "finding_id": "bulk-f2",
            "code": "LOGFRAME_BASELINE_MISSING",
            "severity": "medium",
            "section": "logframe",
            "status": "open",
            "message": "Missing baseline.",
            "source": "rules",
        },
        {
            "finding_id": "bulk-f3",
            "code": "TOC_ASSUMPTIONS_WEAK",
            "severity": "low",
            "section": "toc",
            "status": "acknowledged",
            "message": "Assumptions weak.",
            "source": "rules",
        },
    ]


def set_bulk_critic_job(job_id: str, *, fatal_flaws: list[dict] | None = None) -> None:
    runtime_state.JOB_STORE.set(
        job_id,
        {
            "status": "done",
            "state": {
                "quality_score": 6.0,
                "critic_score": 6.0,
                "needs_revision": True,
                "critic_notes": {
                    "engine": "rules",
                    "fatal_flaws": deepcopy(fatal_flaws if fatal_flaws is not None else _base_fatal_flaws()),
                    "rule_checks": [],
                },
            },
        },
    )


def critic_statuses(job_id: str) -> dict[str, str]:
    critic_resp = client.get(f"/status/{job_id}/critic")
    assert critic_resp.status_code == 200
    return {item["finding_id"]: item["status"] for item in critic_resp.json()["fatal_flaws"]}
