# grantflow/tests/test_integration_generate_presets.py

from fastapi.testclient import TestClient

from grantflow.api import runtime_state
from grantflow.api.app import app
from grantflow.tests.integration_helpers import wait_for_terminal_status

client = TestClient(app)


def test_generate_from_preset_auto_legacy_with_overrides():
    response = client.post(
        "/generate/from-preset",
        json={
            "preset_key": "usaid_gov_ai_kazakhstan",
            "preset_type": "auto",
            "llm_mode": False,
            "hitl_enabled": False,
            "architect_rag_enabled": False,
            "strict_preflight": False,
            "input_context_patch": {"project": "Preset Override Project", "country": "Kenya"},
            "client_metadata_patch": {"scenario": "integration-generate-from-preset"},
        },
    )
    assert response.status_code == 200
    body = response.json()
    assert body["status"] == "accepted"
    assert body["preset_key"] == "usaid_gov_ai_kazakhstan"
    assert body["preset_source"] == "legacy"
    job_id = body["job_id"]

    status = wait_for_terminal_status(client, job_id)
    assert status["status"] == "done"
    state = status["state"]
    input_context = state.get("input_context") or {}
    assert input_context.get("project") == "Preset Override Project"
    assert str(input_context.get("country") or "").strip().lower() == "kenya"
    stored_job = runtime_state.JOB_STORE.get(job_id) or {}
    metadata = stored_job.get("client_metadata") or {}
    assert metadata.get("demo_generate_preset_key") == "usaid_gov_ai_kazakhstan"
    assert metadata.get("demo_generate_preset_source") == "legacy"
    assert metadata.get("scenario") == "integration-generate-from-preset"


def test_generate_from_preset_rbm_resolves_sample_payload():
    response = client.post(
        "/generate/from-preset",
        json={
            "preset_key": "rbm-eu-youth-employment-jordan",
            "preset_type": "rbm",
            "llm_mode": False,
            "hitl_enabled": False,
            "architect_rag_enabled": False,
            "strict_preflight": False,
        },
    )
    assert response.status_code == 200
    body = response.json()
    assert body["status"] == "accepted"
    assert body["preset_source"] == "rbm"
    job_id = body["job_id"]

    status = wait_for_terminal_status(client, job_id)
    assert status["status"] == "done"
    state = status["state"]
    assert state["donor_id"] == "eu"
    input_context = state.get("input_context") or {}
    assert str(input_context.get("country") or "").strip().lower() == "jordan"
    stored_job = runtime_state.JOB_STORE.get(job_id) or {}
    metadata = stored_job.get("client_metadata") or {}
    assert metadata.get("demo_generate_preset_key") == "rbm-eu-youth-employment-jordan"
    assert metadata.get("demo_generate_preset_source") == "rbm"


def test_generate_from_preset_unknown_returns_404():
    response = client.post(
        "/generate/from-preset",
        json={"preset_key": "missing-generate-preset", "preset_type": "auto"},
    )
    assert response.status_code == 404
    detail = response.json().get("detail") or {}
    assert detail.get("code") == "preset_not_found"
    assert detail.get("preset_key") == "missing-generate-preset"
    assert "available" in detail


def test_generate_from_preset_batch_supports_partial_error_mode():
    response = client.post(
        "/generate/from-preset/batch",
        json={
            "continue_on_error": True,
            "items": [
                {
                    "preset_key": "usaid_gov_ai_kazakhstan",
                    "preset_type": "legacy",
                    "llm_mode": False,
                    "hitl_enabled": False,
                    "architect_rag_enabled": False,
                    "strict_preflight": False,
                },
                {
                    "preset_key": "missing-generate-preset",
                    "preset_type": "auto",
                },
                {
                    "preset_key": "rbm-eu-youth-employment-jordan",
                    "preset_type": "rbm",
                    "llm_mode": False,
                    "hitl_enabled": False,
                    "architect_rag_enabled": False,
                    "strict_preflight": False,
                },
            ],
        },
    )
    assert response.status_code == 200
    body = response.json()
    assert body["status"] == "partial_error"
    assert body["total"] == 3
    assert body["accepted_count"] == 2
    assert body["error_count"] == 1
    rows = body.get("results")
    assert isinstance(rows, list) and len(rows) == 3
    assert rows[0]["status"] == "accepted"
    assert rows[0]["preset_source"] == "legacy"
    assert rows[1]["status"] == "error"
    assert rows[1]["http_status"] == 404
    assert rows[2]["status"] == "accepted"
    assert rows[2]["preset_source"] == "rbm"

    for row in rows:
        if row.get("status") != "accepted":
            continue
        job_id = str(row.get("job_id") or "").strip()
        assert job_id
        status = wait_for_terminal_status(client, job_id)
        assert status["status"] == "done"


def test_generate_from_preset_batch_stops_when_continue_on_error_false():
    response = client.post(
        "/generate/from-preset/batch",
        json={
            "continue_on_error": False,
            "items": [
                {
                    "preset_key": "usaid_gov_ai_kazakhstan",
                    "preset_type": "legacy",
                    "llm_mode": False,
                    "hitl_enabled": False,
                    "architect_rag_enabled": False,
                    "strict_preflight": False,
                },
                {
                    "preset_key": "missing-generate-preset",
                    "preset_type": "auto",
                },
            ],
        },
    )
    assert response.status_code == 404
    detail = response.json().get("detail") or {}
    assert detail.get("reason") == "generate_from_preset_batch_item_failed"
    assert detail.get("index") == 1
    results = detail.get("results")
    assert isinstance(results, list) and len(results) == 2
    assert results[0]["status"] == "accepted"
    assert results[1]["status"] == "error"
