"""Create FastAPI router for agent routes.

This module provides the main entry point for creating agent routes.
It uses handlers from .routes module to keep the code clean and maintainable.
"""

from __future__ import annotations

from typing import Any

from fastapi import APIRouter
from fastapi.responses import JSONResponse

from .schemas import (
    AgentRequest,
    AgentResponse,
    BatchAgentRequest,
    BatchAgentResponse,
    StreamUIRequest,
    ResumeRequest,
    AgentInfo,
    ToolInfo,
    ToolStatus,
    GraphDefinitionResponse,
    CacheStatsResponse,
    BillingStatsResponse,
    SpendRecordResponse,
    CreateChatSessionRequest,
    UpdateChatSessionRequest,
    ChatSession,
    ChatSessionsResponse,
    TaskRunActionResponse,
    FeedbackRequest,
    FeedbackResponse,
    OutcomeRequest,
    OutcomeResponse,
    DatasetBuildRequest,
    DatasetBuildResponse,
    PromptCreateRequest,
    PromptVersionCreateRequest,
    PromptPromoteRequest,
    PromptRollbackRequest,
    PromptExperimentCreateRequest,
    PromptOptimizeRequest,
    PromptRecommendationRequest,
    PromptInfoResponse,
    PromptExperimentResponse,
    PromptOptimizationResponse,
    PromptRecommendationResponse,
    RetrievalSourceScoresResponse,
    RetrievalSourceDocumentsResponse,
    RetrievalForceReindexRequest,
    RetrievalReindexTriggersResponse,
    RetrievalTriggerActionRequest,
    RetrievalTriggerActionResponse,
    RetrievalReindexRequestsResponse,
    RetrievalReindexRequestResponse,
    RetrievalOpsSummaryResponse,
    RetrievalProfilesResponse,
    RetrievalForceReindexResponse,
    EvaluationScorecardResponse,
    EvaluationRegressionDatasetResponse,
    EvaluationJudgeDisagreementsRequest,
    EvaluationJudgeDisagreementsResponse,
    EvaluationContinuousJobCreateRequest,
    EvaluationContinuousJobsResponse,
    EvaluationContinuousIncidentsResponse,
    EvaluationContinuousTrendDeltaResponse,
    EvaluationContinuousIncidentSnapshotResponse,
    EvaluationContinuousIncidentActionRequest,
    EvaluationContinuousIncidentResponse,
    EvaluationContinuousJobResponse,
    EvaluationContinuousJobRunResponse,
    EvaluationChampionChallengerRequest,
    EvaluationChampionChallengerResponse,
    ImprovementRewardScoresResponse,
    ImprovementPolicyResponse,
    ImprovementTrainingExportResponse,
    ImprovementReflectionLessonsResponse,
)

from .routes import (
    # Agent
    run_handler,
    stream_handler,
    stream_ui_handler,
    resume_handler,
    batch_handler,
    # Chat
    list_sessions_handler,
    get_session_handler,
    create_session_handler,
    update_session_handler,
    delete_session_handler,
    cancel_task_run_handler,
    # Feedback
    capture_feedback_handler,
    capture_outcome_handler,
    # Learning
    build_dataset_handler,
    create_prompt_handler,
    create_prompt_version_handler,
    promote_prompt_handler,
    rollback_prompt_handler,
    create_experiment_handler,
    optimize_prompt_handler,
    get_recommendations_handler,
    get_prompt_info_handler,
    get_source_scores_handler,
    get_source_documents_handler,
    export_source_scores_handler,
    get_reindex_triggers_handler,
    acknowledge_trigger_handler,
    resolve_trigger_handler,
    close_trigger_handler,
    force_reindex_handler,
    get_reindex_requests_handler,
    get_reindex_request_handler,
    retry_reindex_request_handler,
    resume_reindex_request_handler,
    replay_reindex_request_handler,
    cancel_reindex_request_handler,
    get_reindex_summary_handler,
    get_profiles_handler,
    get_scorecard_handler,
    get_regression_dataset_handler,
    get_judge_disagreements_handler,
    create_eval_job_handler,
    get_eval_jobs_handler,
    get_restored_eval_jobs_handler,
    get_eval_incidents_handler,
    get_eval_trend_handler,
    get_incident_snapshot_handler,
    acknowledge_incident_handler,
    resolve_incident_handler,
    get_eval_job_handler,
    run_eval_job_handler,
    delete_eval_job_handler,
    champion_challenger_handler,
    get_reward_scores_handler,
    get_policy_handler,
    export_training_handler,
    get_reflection_lessons_handler,
)


def _get_global_sessions_store() -> dict:
    """Get global chat sessions store."""
    from . import _CHAT_SESSIONS_STORE

    return _CHAT_SESSIONS_STORE


def _get_global_task_runs_store() -> dict:
    """Get global task runs store."""
    from . import _ACTIVE_TASK_RUNS

    return _ACTIVE_TASK_RUNS


def create_agent_routes(
    agent: Any,
    *,
    timeout: float = 120,
    runtime: Any | None = None,
    learning_store: Any | None = None,
    prompt_registry: Any | None = None,
    run_handler_override: Any | None = None,
    stream_handler_override: Any | None = None,
    stream_ui_handler_override: Any | None = None,
    chronos_poll_interval_seconds: float = 1.0,
    public_name: str | None = None,
    route_base: str = "",
) -> APIRouter:
    """Create FastAPI router for a single agent.

    This function creates all API routes for an agent, organized by functional area:
    - Agent execution (/run, /stream, /batch)
    - Chat sessions (/sessions/*)
    - Feedback capture (/feedback, /outcomes)
    - Learning routes (/learning/*)
    - Agent info (/info, /tools, /graph, /cache)

    Args:
        agent: The agent instance to create routes for
        timeout: Default timeout for agent execution
        runtime: Optional runtime for agent management
        learning_store: Optional learning store for feedback/datasets
        prompt_registry: Optional prompt registry for prompt management
        run_handler_override: Optional custom run handler
        stream_handler_override: Optional custom stream handler
        stream_ui_handler_override: Optional custom stream-ui handler
        chronos_poll_interval_seconds: Poll interval for Chronos runner
        public_name: Public name for the agent
        route_base: Base path for routes

    Returns:
        Configured APIRouter with all agent routes
    """
    router = APIRouter()

    agent_name = public_name or getattr(
        agent, "name", getattr(getattr(agent, "_config", None), "name", "unknown")
    )

    # =========================================================================
    # Agent Info Routes
    # =========================================================================

    @router.get("/info", response_model=AgentInfo)
    async def get_info():
        """Get agent information."""
        config = getattr(agent, "_config", None)
        provider_type = None
        provider_base_url = None

        if config and config.provider:
            provider_type = config.provider.type
            provider_base_url = config.provider.base_url

        model_name = config.model if config else None
        if model_name is not None and not isinstance(model_name, str):
            model_name = str(model_name)

        return AgentInfo(
            ui_contract_version=2,
            name=agent_name,
            model=model_name,
            system_prompt=config.system_prompt if config else None,
            provider_type=provider_type,
            provider_base_url=provider_base_url,
            supports_graph=hasattr(agent, "get_graph_definition"),
            supports_stream_ui=hasattr(agent, "stream_ui_events")
            or hasattr(agent, "stream_events"),
            supports_resume=hasattr(agent, "resume"),
            route_base=route_base,
        )

    @router.get("/tools", response_model=list[ToolInfo])
    async def list_tools():
        """List agent tools."""
        tools = getattr(agent, "_config", None)
        if tools and hasattr(tools, "tools"):
            return [
                ToolInfo(name=t.name, description=t.description, parameters=t.schema)
                for t in tools.tools
            ]
        return []

    @router.get("/tools/status", response_model=list[ToolStatus])
    async def get_tools_status():
        """Get tools status."""
        config = getattr(agent, "_config", None)
        if not config or not hasattr(config, "tools"):
            return []

        disabled = set(config.disabled_tools or [])
        return [
            ToolStatus(
                name=t.name,
                description=t.description,
                parameters=t.schema,
                enabled=t.name not in disabled,
            )
            for t in config.tools
        ]

    @router.post("/tools/{tool_name}/toggle")
    async def toggle_tool(tool_name: str, enabled: bool):
        """Toggle tool enabled state."""
        config = getattr(agent, "_config", None)
        if not config:
            return JSONResponse(status_code=404, content={"error": "config_not_found"})

        if enabled:
            if tool_name in (config.disabled_tools or []):
                config.disabled_tools.remove(tool_name)
        else:
            if tool_name not in (config.disabled_tools or []):
                config.disabled_tools.append(tool_name)

        return {"status": "ok", "tool": tool_name, "enabled": enabled}

    @router.get("/graph", response_model=GraphDefinitionResponse)
    async def get_graph():
        """Get graph definition."""
        if runtime is not None and hasattr(runtime, "get_graph"):
            definition = runtime.get_graph(agent_name)
            if definition:
                return GraphDefinitionResponse(**definition)

        if hasattr(agent, "get_graph_definition"):
            return GraphDefinitionResponse(**agent.get_graph_definition())

        return JSONResponse(
            status_code=404, content={"error": "not_found", "message": "Graph definition not found"}
        )

    @router.get("/cache/stats", response_model=CacheStatsResponse)
    async def get_cache_stats():
        """Get cache statistics."""
        backend = getattr(agent._config, "cache_backend", None)
        if not backend:
            return JSONResponse(status_code=404, content={"error": "cache_not_enabled"})
        stats = await backend.get_stats()
        total_entries = int(stats.get("total_entries", stats.get("size", 0)) or 0)
        total_hits = int(stats.get("total_hits", stats.get("hits", 0)) or 0)
        misses = int(stats.get("misses", 0) or 0)
        denominator = total_hits + misses
        hit_rate = (
            float(stats.get("hit_rate", total_hits / denominator))
            if denominator
            else float(stats.get("hit_rate", 0.0) or 0.0)
        )
        return CacheStatsResponse(
            backend=stats.get("backend"),
            total_entries=total_entries,
            total_hits=total_hits,
            hits=total_hits,
            misses=misses,
            size=total_entries,
            hit_rate=hit_rate,
        )

    @router.delete("/cache")
    async def clear_cache():
        """Clear cache."""
        backend = getattr(agent._config, "cache_backend", None)
        if not backend:
            return JSONResponse(status_code=404, content={"error": "cache_not_enabled"})
        await backend.clear()
        return {"status": "ok", "message": "Cache cleared"}

    @router.get("/stats/billing", response_model=BillingStatsResponse)
    async def get_billing_stats():
        """Get billing statistics."""
        from logos_adk.runtime import _default_runtime_holder

        runtime_obj = _default_runtime_holder.get() or runtime

        total_spent = 0.0
        by_agent = {}
        all_records = []

        if runtime_obj is not None and hasattr(runtime_obj, "list_agents"):
            agent_pool = [
                runtime_obj.get_agent(name)
                for name in runtime_obj.list_agents()
            ]
        else:
            agent_pool = [agent]

        for scoped_agent in agent_pool:
            if scoped_agent is None:
                continue
            ledger = getattr(scoped_agent, "_spend_ledger", None)
            if ledger:
                records = ledger.list_records(limit=100)
                for r in records:
                    total_spent += r.amount_usd
                    by_agent[r.agent_name] = by_agent.get(r.agent_name, 0.0) + r.amount_usd
                    all_records.append(
                        SpendRecordResponse(
                            agent_name=r.agent_name,
                            model=r.model,
                            amount_usd=r.amount_usd,
                            session_id=r.session_id,
                            created_at=r.created_at,
                        )
                    )

        all_records.sort(key=lambda x: x.created_at, reverse=True)

        return BillingStatsResponse(
            total_spent_usd=round(total_spent, 4),
            by_agent={k: round(v, 4) for k, v in by_agent.items()},
            recent_records=all_records[:50],
        )

    # =========================================================================
    # Agent Execution Routes
    # =========================================================================

    @router.post("/run", response_model=AgentResponse)
    async def run(request: AgentRequest):
        """Execute agent synchronously."""
        handler = run_handler_override or run_handler
        return await handler(
            agent=agent,
            request=request,
            timeout=timeout,
        )

    @router.post("/stream")
    async def stream(request: AgentRequest):
        """Execute agent with streaming."""
        handler = stream_handler_override or stream_handler
        return await handler(
            agent=agent,
            request=request,
            timeout=timeout,
        )

    @router.post("/batch", response_model=BatchAgentResponse)
    async def batch(request: BatchAgentRequest):
        """Execute agent in batch mode."""
        return await batch_handler(
            agent=agent,
            request=request,
            timeout=timeout,
        )

    @router.post("/stream-ui")
    async def stream_ui(request: StreamUIRequest):
        """Execute agent with streaming UI events."""
        if route_base and request.session_id:
            from .routes.chat import get_session_handler
            from fastapi.responses import JSONResponse

            try:
                await get_session_handler(request.session_id, route_agent_name=agent_name)
            except Exception:
                return JSONResponse(
                    status_code=404, content={"detail": {"error": "session_not_found"}}
                )

        handler = stream_ui_handler_override or stream_ui_handler
        return await handler(
            agent=agent,
            request=request,
            timeout=timeout,
        )

    @router.post("/stream-ui/continue")
    async def stream_ui_continue(request: StreamUIRequest):
        """Continue a paused stream-ui session."""
        if not request.session_id:
            return JSONResponse(
                status_code=400, content={"detail": {"error": "session_id required"}}
            )

        if route_base:
            from .routes.chat import get_session_handler

            try:
                await get_session_handler(request.session_id, route_agent_name=agent_name)
            except Exception:
                return JSONResponse(
                    status_code=404, content={"detail": {"error": "session_not_found"}}
                )

        return await resume_handler(
            agent=agent,
            request=request,
            timeout=timeout,
        )

    @router.post("/resume")
    async def resume(request: ResumeRequest):
        """Resume a paused runnable execution."""
        return await resume_handler(
            agent=agent,
            request=StreamUIRequest(
                prompt=request.prompt,
                prompt_parts=request.prompt_parts,
                session_id=request.session_id,
                correlation_id=request.correlation_id,
                task_run=request.task_run,
                task_run_id=request.task_run_id,
                user_input=request.user_input,
                continue_from_node=request.continue_from_node or request.node_name,
                continue_correlation_id=request.continue_correlation_id,
            ),
            timeout=timeout,
        )

    # =========================================================================
    # Chat Session Routes
    # =========================================================================

    @router.get("/sessions", response_model=ChatSessionsResponse)
    async def list_sessions(agent_name_filter: str | None = None, limit: int | None = None):
        """List all chat sessions."""
        if route_base:
            effective_agent = agent_name_filter if agent_name_filter else agent_name
        else:
            effective_agent = agent_name_filter
        return await list_sessions_handler(agent_name=effective_agent, limit=limit)

    @router.get("/sessions/{session_id}", response_model=ChatSession)
    async def get_session(session_id: str):
        """Get chat session by ID."""
        return await get_session_handler(
            session_id, route_agent_name=agent_name if route_base else None
        )

    @router.post("/sessions", response_model=ChatSession)
    async def create_session(request: CreateChatSessionRequest):
        """Create new chat session."""
        return await create_session_handler(
            request, route_agent_name=agent_name if route_base else None
        )

    @router.put("/sessions/{session_id}", response_model=ChatSession)
    async def update_session(session_id: str, request: UpdateChatSessionRequest):
        """Update chat session."""
        return await update_session_handler(
            session_id, request, route_agent_name=agent_name if route_base else None
        )

    @router.delete("/sessions/{session_id}")
    async def delete_session(session_id: str):
        """Delete chat session."""
        return await delete_session_handler(
            session_id, route_agent_name=agent_name if route_base else None
        )

    @router.post(
        "/sessions/{session_id}/task-runs/{task_run_id}/cancel",
        response_model=TaskRunActionResponse,
    )
    async def cancel_task_run(session_id: str, task_run_id: str):
        """Cancel task run."""
        return await cancel_task_run_handler(session_id, task_run_id)

    # =========================================================================
    # Feedback Routes
    # =========================================================================

    @router.post("/feedback", response_model=FeedbackResponse)
    async def capture_feedback(request: FeedbackRequest):
        """Capture user feedback."""
        return await capture_feedback_handler(request, learning_store)

    @router.post("/outcomes", response_model=OutcomeResponse)
    async def capture_outcome(request: OutcomeRequest):
        """Capture business outcome."""
        return await capture_outcome_handler(request, learning_store)

    # =========================================================================
    # Learning Routes - Dataset
    # =========================================================================

    @router.post("/learning/datasets/build", response_model=DatasetBuildResponse)
    async def build_dataset(request: DatasetBuildRequest):
        """Build dataset from feedback."""
        return await build_dataset_handler(request, learning_store)

    # =========================================================================
    # Learning Routes - Prompt
    # =========================================================================

    @router.post("/learning/prompts", response_model=PromptInfoResponse)
    async def create_prompt(request: PromptCreateRequest):
        """Create prompt registry entry."""
        return await create_prompt_handler(request, prompt_registry)

    @router.post("/learning/prompts/{prompt_name}/versions", response_model=PromptInfoResponse)
    async def create_prompt_version(prompt_name: str, request: PromptVersionCreateRequest):
        """Create prompt version."""
        return await create_prompt_version_handler(prompt_name, request, prompt_registry)

    @router.post("/learning/prompts/{prompt_name}/promote", response_model=PromptInfoResponse)
    async def promote_prompt(prompt_name: str, request: PromptPromoteRequest):
        """Promote prompt version."""
        return await promote_prompt_handler(prompt_name, request, prompt_registry)

    @router.post("/learning/prompts/{prompt_name}/rollback", response_model=PromptInfoResponse)
    async def rollback_prompt(prompt_name: str, request: PromptRollbackRequest):
        """Rollback prompt."""
        return await rollback_prompt_handler(prompt_name, request, prompt_registry)

    @router.post(
        "/learning/prompts/{prompt_name}/experiments", response_model=PromptExperimentResponse
    )
    async def create_experiment(prompt_name: str, request: PromptExperimentCreateRequest):
        """Create A/B experiment."""
        return await create_experiment_handler(prompt_name, request, prompt_registry)

    @router.post(
        "/learning/prompts/{prompt_name}/optimize", response_model=PromptOptimizationResponse
    )
    async def optimize_prompt(prompt_name: str, request: PromptOptimizeRequest):
        """Optimize prompt."""
        return await optimize_prompt_handler(prompt_name, request, prompt_registry)

    @router.post("/learning/prompts/recommendations", response_model=PromptRecommendationResponse)
    async def get_recommendations(request: PromptRecommendationRequest):
        """Get prompt recommendations."""
        return await get_recommendations_handler(request, prompt_registry)

    @router.get("/learning/prompts/{prompt_name}", response_model=PromptInfoResponse)
    async def get_prompt_info(prompt_name: str):
        """Get prompt information."""
        return await get_prompt_info_handler(prompt_name, prompt_registry)

    # =========================================================================
    # Learning Routes - Retrieval
    # =========================================================================

    @router.get("/learning/retrieval/source-scores", response_model=RetrievalSourceScoresResponse)
    async def get_source_scores(workspace_id: str | None = None):
        """Get retrieval source scores."""
        return await get_source_scores_handler(workspace_id, learning_store, agent)

    @router.get(
        "/learning/retrieval/source-documents",
        response_model=RetrievalSourceDocumentsResponse,
    )
    async def get_source_documents(
        workspace_id: str | None = None,
        source_key: str | None = None,
    ):
        """Get stored source-document snapshots."""
        return await get_source_documents_handler(workspace_id, source_key, learning_store, agent)

    @router.get("/learning/retrieval/source-scores/export")
    async def export_source_scores(format: str = "json", workspace_id: str | None = None):
        """Export source scores."""
        return await export_source_scores_handler(format, workspace_id, learning_store, agent)

    @router.get(
        "/learning/retrieval/reindex-triggers", response_model=RetrievalReindexTriggersResponse
    )
    async def get_reindex_triggers(workspace_id: str | None = None):
        """Get reindex triggers."""
        return await get_reindex_triggers_handler(workspace_id, learning_store, agent)

    @router.post(
        "/learning/retrieval/reindex-triggers/{trigger_id}/ack",
        response_model=RetrievalTriggerActionResponse,
    )
    async def acknowledge_trigger_alias(trigger_id: str, request: RetrievalTriggerActionRequest):
        """Acknowledge reindex trigger using short alias."""
        return await acknowledge_trigger_handler(trigger_id, request.note, learning_store, agent)

    @router.post(
        "/learning/retrieval/reindex-triggers/{trigger_id}/acknowledge",
        response_model=RetrievalTriggerActionResponse,
    )
    async def acknowledge_trigger(trigger_id: str, request: RetrievalTriggerActionRequest):
        """Acknowledge reindex trigger."""
        return await acknowledge_trigger_handler(trigger_id, request.note, learning_store, agent)

    @router.post(
        "/learning/retrieval/reindex-triggers/{trigger_id}/resolve",
        response_model=RetrievalTriggerActionResponse,
    )
    async def resolve_trigger(trigger_id: str, request: RetrievalTriggerActionRequest):
        """Resolve reindex trigger."""
        return await resolve_trigger_handler(trigger_id, request.note, learning_store, agent)

    @router.post(
        "/learning/retrieval/reindex-triggers/{trigger_id}/close",
        response_model=RetrievalTriggerActionResponse,
    )
    async def close_trigger(trigger_id: str, request: RetrievalTriggerActionRequest):
        """Close reindex trigger."""
        return await close_trigger_handler(trigger_id, request.note, learning_store, agent)

    @router.post("/learning/retrieval/force-reindex", response_model=RetrievalForceReindexResponse)
    async def force_reindex(request: RetrievalForceReindexRequest):
        """Force reindex source."""
        return await force_reindex_handler(
            request.source_key,
            request.workspace_id,
            request.reason,
            request.requested_by,
            request.metadata,
            learning_store,
            agent,
        )

    @router.get(
        "/learning/retrieval/reindex-requests", response_model=RetrievalReindexRequestsResponse
    )
    async def get_reindex_requests(workspace_id: str | None = None):
        """Get reindex requests."""
        return await get_reindex_requests_handler(workspace_id, learning_store, agent)

    @router.get(
        "/learning/retrieval/reindex-requests/{request_id}",
        response_model=RetrievalReindexRequestResponse,
    )
    async def get_reindex_request(request_id: str):
        """Get reindex request by ID."""
        return await get_reindex_request_handler(request_id, learning_store, agent)

    @router.post(
        "/learning/retrieval/reindex-requests/{request_id}/retry",
        response_model=RetrievalReindexRequestResponse,
    )
    async def retry_reindex_request(request_id: str, request: RetrievalTriggerActionRequest):
        """Retry failed reindex request."""
        return await retry_reindex_request_handler(request_id, request.note, learning_store, agent)

    @router.post(
        "/learning/retrieval/reindex-requests/{request_id}/resume",
        response_model=RetrievalReindexRequestResponse,
    )
    async def resume_reindex_request(request_id: str, request: RetrievalTriggerActionRequest):
        """Resume canceled reindex request."""
        return await resume_reindex_request_handler(
            request_id, request.note, learning_store, agent
        )

    @router.post(
        "/learning/retrieval/reindex-requests/{request_id}/replay",
        response_model=RetrievalReindexRequestResponse,
    )
    async def replay_reindex_request(request_id: str, request: RetrievalTriggerActionRequest):
        """Replay canceled reindex request as a fresh request."""
        return await replay_reindex_request_handler(
            request_id, request.note, learning_store, agent
        )

    @router.post(
        "/learning/retrieval/reindex-requests/{request_id}/cancel",
        response_model=RetrievalReindexRequestResponse,
    )
    async def cancel_reindex_request(request_id: str, request: RetrievalTriggerActionRequest):
        """Cancel queued or running reindex request."""
        return await cancel_reindex_request_handler(
            request_id, request.note, learning_store, agent
        )

    @router.get("/learning/retrieval/summary", response_model=RetrievalOpsSummaryResponse)
    async def get_reindex_summary(workspace_id: str | None = None):
        """Get retrieval operations summary."""
        return await get_reindex_summary_handler(workspace_id, learning_store, agent)

    @router.get("/learning/retrieval/profiles", response_model=RetrievalProfilesResponse)
    async def get_profiles(
        workspace_id: str | None = None,
        task_type: str | None = None,
        user_segment: str | None = None,
    ):
        """Get retrieval profiles."""
        return await get_profiles_handler(workspace_id, task_type, user_segment, learning_store, agent)

    # =========================================================================
    # Learning Routes - Evaluation
    # =========================================================================

    @router.get("/learning/evaluation/scorecard", response_model=EvaluationScorecardResponse)
    async def get_scorecard(
        workspace_id: str | None = None,
        agent_name: str | None = None,
        window_days: int = 7,
    ):
        """Get evaluation scorecard."""
        return await get_scorecard_handler(
            workspace_id,
            agent_name,
            window_days,
            learning_store,
        )

    @router.get(
        "/learning/evaluation/regression-dataset",
        response_model=EvaluationRegressionDatasetResponse,
    )
    async def get_regression_dataset(
        workspace_id: str | None = None,
        agent_name: str | None = None,
        limit: int = 100,
    ):
        """Get regression dataset."""
        return await get_regression_dataset_handler(
            workspace_id,
            agent_name,
            limit,
            learning_store,
        )

    @router.post(
        "/learning/evaluation/judge-disagreements",
        response_model=EvaluationJudgeDisagreementsResponse,
    )
    async def get_judge_disagreements(request: EvaluationJudgeDisagreementsRequest):
        """Get judge disagreements."""
        return await get_judge_disagreements_handler(request, agent, learning_store)

    @router.post("/learning/evaluation/jobs", response_model=EvaluationContinuousJobResponse)
    async def create_eval_job(request: EvaluationContinuousJobCreateRequest):
        """Create evaluation job."""
        return await create_eval_job_handler(request, agent, prompt_registry, learning_store)

    @router.get("/learning/evaluation/jobs", response_model=EvaluationContinuousJobsResponse)
    async def get_eval_jobs(workspace_id: str | None = None):
        """Get evaluation jobs."""
        return await get_eval_jobs_handler(workspace_id, agent, prompt_registry, learning_store)

    @router.get(
        "/learning/evaluation/restored-jobs",
        response_model=EvaluationContinuousJobsResponse,
    )
    async def get_restored_eval_jobs(workspace_id: str | None = None):
        """Get restored evaluation jobs."""
        return await get_restored_eval_jobs_handler(
            workspace_id,
            agent,
            prompt_registry,
            learning_store,
        )

    @router.get(
        "/learning/evaluation/incidents", response_model=EvaluationContinuousIncidentsResponse
    )
    async def get_eval_incidents(
        workspace_id: str | None = None,
        job_name: str | None = None,
        kind: str | None = None,
        status: str | None = None,
        limit: int = 50,
    ):
        """Get evaluation incidents."""
        return await get_eval_incidents_handler(
            workspace_id,
            job_name,
            kind,
            status,
            limit,
            agent,
            prompt_registry,
            learning_store,
        )

    @router.get(
        "/learning/evaluation/trend-delta", response_model=EvaluationContinuousTrendDeltaResponse
    )
    @router.get(
        "/learning/evaluation/trend-deltas", response_model=EvaluationContinuousTrendDeltaResponse
    )
    async def get_eval_trend(
        workspace_id: str | None = None,
        job_name: str | None = None,
        window_days: int = 7,
    ):
        """Get evaluation trend."""
        return await get_eval_trend_handler(
            workspace_id,
            job_name,
            window_days,
            agent,
            prompt_registry,
            learning_store,
        )

    @router.get(
        "/learning/evaluation/incidents/{incident_id}/snapshot",
        response_model=EvaluationContinuousIncidentSnapshotResponse,
    )
    async def get_incident_snapshot(incident_id: str):
        """Get incident snapshot."""
        return await get_incident_snapshot_handler(
            incident_id,
            None,
            None,
            None,
            20,
            agent,
            prompt_registry,
            learning_store,
        )

    @router.get(
        "/learning/evaluation/incident-snapshot",
        response_model=EvaluationContinuousIncidentSnapshotResponse,
    )
    async def get_incident_snapshot_summary(
        workspace_id: str | None = None,
        job_name: str | None = None,
        status: str | None = None,
        limit: int = 20,
    ):
        """Get aggregate incident snapshot."""
        return await get_incident_snapshot_handler(
            None,
            workspace_id,
            job_name,
            status,
            limit,
            agent,
            prompt_registry,
            learning_store,
        )

    @router.post(
        "/learning/evaluation/incidents/{incident_id}/acknowledge",
        response_model=EvaluationContinuousIncidentResponse,
    )
    async def acknowledge_incident(
        incident_id: str,
        request: EvaluationContinuousIncidentActionRequest | None = None,
    ):
        """Acknowledge incident."""
        payload = request or EvaluationContinuousIncidentActionRequest()
        return await acknowledge_incident_handler(
            incident_id,
            payload.actor,
            payload.note,
            agent,
            prompt_registry,
            learning_store,
        )

    @router.post(
        "/learning/evaluation/rollback-incidents/{incident_id}/ack",
        response_model=EvaluationContinuousIncidentResponse,
    )
    async def acknowledge_rollback_incident(
        incident_id: str,
        request: EvaluationContinuousIncidentActionRequest | None = None,
    ):
        """Acknowledge rollback incident."""
        payload = request or EvaluationContinuousIncidentActionRequest()
        return await acknowledge_incident_handler(
            incident_id,
            payload.actor,
            payload.note,
            agent,
            prompt_registry,
            learning_store,
        )

    @router.post(
        "/learning/evaluation/incidents/{incident_id}/resolve",
        response_model=EvaluationContinuousIncidentResponse,
    )
    async def resolve_incident(
        incident_id: str,
        request: EvaluationContinuousIncidentActionRequest | None = None,
    ):
        """Resolve incident."""
        payload = request or EvaluationContinuousIncidentActionRequest()
        return await resolve_incident_handler(
            incident_id,
            payload.actor,
            payload.note,
            agent,
            prompt_registry,
            learning_store,
        )

    @router.post(
        "/learning/evaluation/rollback-incidents/{incident_id}/resolve",
        response_model=EvaluationContinuousIncidentResponse,
    )
    async def resolve_rollback_incident(
        incident_id: str,
        request: EvaluationContinuousIncidentActionRequest | None = None,
    ):
        """Resolve rollback incident."""
        payload = request or EvaluationContinuousIncidentActionRequest()
        return await resolve_incident_handler(
            incident_id,
            payload.actor,
            payload.note,
            agent,
            prompt_registry,
            learning_store,
        )

    @router.get(
        "/learning/evaluation/rollback-incidents",
        response_model=EvaluationContinuousIncidentsResponse,
    )
    async def get_rollback_incidents(
        workspace_id: str | None = None,
        job_name: str | None = None,
        status: str | None = None,
        limit: int = 50,
    ):
        """Get rollback incidents."""
        return await get_eval_incidents_handler(
            workspace_id,
            job_name,
            None,
            status,
            limit,
            agent,
            prompt_registry,
            learning_store,
        )

    @router.get(
        "/learning/evaluation/jobs/{job_id}", response_model=EvaluationContinuousJobResponse
    )
    async def get_eval_job(job_id: str):
        """Get evaluation job by ID."""
        return await get_eval_job_handler(job_id, agent, prompt_registry, learning_store)

    @router.post(
        "/learning/evaluation/jobs/{job_id}/run", response_model=EvaluationContinuousJobRunResponse
    )
    async def run_eval_job(job_id: str):
        """Run evaluation job."""
        return await run_eval_job_handler(job_id, agent, prompt_registry, learning_store)

    @router.delete(
        "/learning/evaluation/jobs/{job_id}", response_model=EvaluationContinuousJobResponse
    )
    async def delete_eval_job(job_id: str):
        """Delete evaluation job."""
        return await delete_eval_job_handler(job_id, agent, prompt_registry, learning_store)

    @router.post(
        "/learning/evaluation/champion-challenger",
        response_model=EvaluationChampionChallengerResponse,
    )
    async def champion_challenger(request: EvaluationChampionChallengerRequest):
        """Run champion/challenger comparison."""
        return await champion_challenger_handler(request, agent, learning_store)

    # =========================================================================
    # Learning Routes - Improvement
    # =========================================================================

    @router.get(
        "/learning/improvement/reward-scores", response_model=ImprovementRewardScoresResponse
    )
    async def get_reward_scores(workspace_id: str | None = None, agent_name: str | None = None):
        """Get reward scores."""
        return await get_reward_scores_handler(workspace_id, agent_name, learning_store)

    @router.get("/learning/improvement/policy", response_model=ImprovementPolicyResponse)
    async def get_policy(
        workspace_id: str | None = None,
        task_type: str | None = None,
        user_segment: str | None = None,
    ):
        """Get learned policy."""
        return await get_policy_handler(workspace_id, task_type, user_segment, learning_store)

    @router.get(
        "/learning/improvement/export-training", response_model=ImprovementTrainingExportResponse
    )
    async def export_training(workspace_id: str | None = None, agent_name: str | None = None):
        """Export training data."""
        return await export_training_handler(workspace_id, agent_name, learning_store)

    @router.get(
        "/learning/improvement/reflection-lessons",
        response_model=ImprovementReflectionLessonsResponse,
    )
    async def get_reflection_lessons(
        workspace_id: str | None = None, agent_name: str | None = None
    ):
        """Get reflection lessons."""
        return await get_reflection_lessons_handler(workspace_id, agent_name, learning_store)

    return router


__all__ = ["create_agent_routes"]
