# grantflow/tests/test_integration_pilot_quick_report.py

import gzip
import io
import json
import zipfile

from fastapi.testclient import TestClient

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

client = TestClient(app)


def _generate_done_pilot_quick_report_job_id() -> str:
    gen = client.post(
        "/generate/from-preset",
        json={
            "preset_key": "un_agencies_katch_evaluation_kyrgyzstan",
            "preset_type": "auto",
            "llm_mode": False,
            "hitl_enabled": False,
        },
    )
    assert gen.status_code == 200
    job_id = gen.json()["job_id"]
    status = wait_for_terminal_status(client, job_id)
    assert status["status"] == "done"
    return job_id


def test_status_pilot_quick_report_endpoint_exposes_compact_review_snapshot():
    job_id = _generate_done_pilot_quick_report_job_id()

    report = client.get(f"/status/{job_id}/pilot-quick-report")
    assert report.status_code == 200
    body = report.json()
    assert body["job_id"] == job_id
    assert body["status"] == "done"
    assert body["export_readiness_status"] in {"ready", "partial", "weak", "missing"}
    assert body.get("export_top_gap") is not None
    assert body.get("go_no_go_hint") in {"go", "conditional_go", "no_go"}
    assert isinstance(body.get("primary_blocker"), str)
    assert isinstance(body.get("recommended_next_action"), str)
    assert isinstance(body.get("review_workflow_summary_present"), bool)


def test_status_pilot_quick_report_export_supports_json_and_markdown():
    job_id = _generate_done_pilot_quick_report_job_id()

    exported_json = client.get(f"/status/{job_id}/pilot-quick-report/export?format=json")
    assert exported_json.status_code == 200
    assert exported_json.headers["content-type"].startswith("application/json")
    assert f"pilot_quick_report_{job_id}.json" in exported_json.headers.get("content-disposition", "")
    json_payload = json.loads(exported_json.text)
    assert json_payload["job_id"] == job_id
    assert json_payload.get("go_no_go_hint") in {"go", "conditional_go", "no_go"}

    exported_md = client.get(f"/status/{job_id}/pilot-quick-report/export?format=md")
    assert exported_md.status_code == 200
    assert exported_md.headers["content-type"].startswith("text/markdown")
    assert f"pilot_quick_report_{job_id}.md" in exported_md.headers.get("content-disposition", "")
    assert "# Pilot Quick Report" in exported_md.text
    assert "go_no_go_hint" in exported_md.text

    exported_csv = client.get(f"/status/{job_id}/pilot-quick-report/export?format=csv")
    assert exported_csv.status_code == 200
    assert exported_csv.headers["content-type"].startswith("text/csv")
    assert f"pilot_quick_report_{job_id}.csv" in exported_csv.headers.get("content-disposition", "")
    assert "job_id" in exported_csv.text.splitlines()[0]
    assert "go_no_go_hint" in exported_csv.text.splitlines()[0]


def test_status_pilot_quick_report_export_supports_gzip_json():
    job_id = _generate_done_pilot_quick_report_job_id()

    exported_gz = client.get(f"/status/{job_id}/pilot-quick-report/export?format=json&gzip=true")
    assert exported_gz.status_code == 200
    assert exported_gz.headers["content-type"].startswith("application/gzip")
    assert exported_gz.headers.get("content-disposition", "").endswith('.json.gz"')
    payload = json.loads(gzip.decompress(exported_gz.content).decode("utf-8"))
    assert payload["job_id"] == job_id


def test_status_pilot_quick_report_export_supports_gzip_markdown():
    job_id = _generate_done_pilot_quick_report_job_id()

    exported_gz = client.get(f"/status/{job_id}/pilot-quick-report/export?format=md&gzip=true")
    assert exported_gz.status_code == 200
    assert exported_gz.headers["content-type"].startswith("application/gzip")
    assert exported_gz.headers.get("content-disposition", "").endswith('.md.gz"')
    markdown = gzip.decompress(exported_gz.content).decode("utf-8")
    assert "# Pilot Quick Report" in markdown


def test_status_pilot_quick_report_export_supports_gzip_csv():
    job_id = _generate_done_pilot_quick_report_job_id()

    exported_gz = client.get(f"/status/{job_id}/pilot-quick-report/export?format=csv&gzip=true")
    assert exported_gz.status_code == 200
    assert exported_gz.headers["content-type"].startswith("application/gzip")
    assert exported_gz.headers.get("content-disposition", "").endswith('.csv.gz"')
    csv_text = gzip.decompress(exported_gz.content).decode("utf-8")
    assert "job_id" in csv_text.splitlines()[0]


def test_status_pilot_quick_report_export_rejects_unsupported_format():
    job_id = _generate_done_pilot_quick_report_job_id()

    bad = client.get(f"/status/{job_id}/pilot-quick-report/export?format=txt")
    assert bad.status_code == 400
    assert bad.json()["detail"]["code"] == "unsupported_format"


def test_status_pilot_evidence_pack_export_returns_zip_bundle():
    job_id = _generate_done_pilot_quick_report_job_id()

    exported_zip = client.get(f"/status/{job_id}/pilot-evidence-pack/export")
    assert exported_zip.status_code == 200
    assert exported_zip.headers["content-type"].startswith("application/zip")
    assert f"pilot_evidence_pack_{job_id}.zip" in exported_zip.headers.get("content-disposition", "")

    with zipfile.ZipFile(io.BytesIO(exported_zip.content), "r") as archive:
        names = set(archive.namelist())
        assert "README.md" in names
        assert "pilot_quick_report.json" in names
        assert "metrics.json" in names
        assert "quality.json" in names
        assert "review_workflow.json" in names
        assert "export_payload.json" in names

        quick_report = json.loads(archive.read("pilot_quick_report.json").decode("utf-8"))
        assert quick_report["job_id"] == job_id
        assert quick_report.get("go_no_go_hint") in {"go", "conditional_go", "no_go"}
        readme = archive.read("README.md").decode("utf-8")
        assert "# Pilot Evidence Pack" in readme
