"""Campaign read-model projections and batched child-Run loading."""

from datetime import datetime, timezone

from agenteval.evaluation.campaign_read_model import CampaignReadModel
from agenteval.models import Campaign, CampaignPlanEntry, EvalRun, RunStatus
from agenteval.storage.repository import CampaignRepository, RunRepository


def _campaign(session, campaign_id: str) -> Campaign:
    return CampaignRepository(session).create(Campaign(
        id=campaign_id,
        name=campaign_id,
        target_id="target-1",
        window_seconds=60,
        plan=[CampaignPlanEntry(scenario_id="scenario-1", offset_seconds=0)],
    ))


def _run(session, campaign_id: str, run_id: str) -> EvalRun:
    return RunRepository(session).create(EvalRun(
        id=run_id,
        target_id="target-1",
        scenario_id="scenario-1",
        campaign_id=campaign_id,
        status=RunStatus.COMPLETED,
        started_at=datetime(2026, 1, 1, tzinfo=timezone.utc),
        summary={"total_cases": 1, "passed_cases": 1, "pass_rate": 1.0},
    ))


def test_list_items_empty(db_session):
    assert CampaignReadModel(db_session).list_items() == []


def test_list_items_batches_runs_for_multiple_campaigns(db_session, monkeypatch):
    first = _campaign(db_session, "campaign-1")
    second = _campaign(db_session, "campaign-2")
    _run(db_session, first.id, "run-1")
    _run(db_session, second.id, "run-2")

    def reject_per_campaign_query(*args, **kwargs):
        raise AssertionError("list_items must not query child Runs per Campaign")

    monkeypatch.setattr(RunRepository, "list_by_campaign", reject_per_campaign_query)

    items = CampaignReadModel(db_session).list_items()

    progress_by_id = {item["id"]: item["progress"] for item in items}
    assert set(progress_by_id) == {first.id, second.id}
    assert progress_by_id[first.id]["completed_runs"] == 1
    assert progress_by_id[second.id]["completed_runs"] == 1


def test_markdown_projection_uses_json_report_projection(db_session):
    campaign = _campaign(db_session, "campaign-1")
    _run(db_session, campaign.id, "run-1")
    read_model = CampaignReadModel(db_session)

    json_report = read_model.report(campaign.id)
    markdown_projection = read_model.markdown_projection(campaign.id)

    assert json_report is not None
    assert markdown_projection is not None
    assert markdown_projection["report"] == {
        key: value for key, value in json_report.items() if key != "exploration"
    }
    assert markdown_projection["exploration"] == json_report.get("exploration")
