use axum::{extract::State, http::StatusCode, routing::post, Json, Router};

use crate::agent::r#loop::AgentRuntime;
use crate::resolve_project_id;
use crate::types::*;
use crate::AppState;

pub fn router() -> Router<AppState> {
    Router::new().route("/api/v1/agent/run", post(agent_run))
}

async fn agent_run(
    State(state): State<AppState>,
    Json(req): Json<AgentRunRequest>,
) -> Result<Json<ApiResponse<AgentRunResponse>>, StatusCode> {
    // 解析项目 ID
    let project_id = resolve_project_id(state.db, &req.project_id.to_string()).await?;

    // 将 AgentEntry 转换为任务类型字符串
    let task_type = match req.entry {
        AgentEntry::Tell => "tell",
        AgentEntry::Ask => "ask",
        AgentEntry::Analysis => "analysis",
        AgentEntry::Report => "report",
        AgentEntry::Reason => "reason",
        AgentEntry::Explore => "explore",
    };

    // 创建 Agent 运行时 - 优先使用 provider registry
    let runtime = if let Some(ref registry) = state.provider_registry {
        let workers = state.config.agent_workers.clone();
        AgentRuntime::with_provider(
            state.db,
            project_id,
            state.tx.clone(),
            registry,
            task_type,
            &workers,
            req.max_turns,
        )
        .ok_or_else(|| {
            tracing::error!("No LLM provider configured for task type: {}", task_type);
            StatusCode::INTERNAL_SERVER_ERROR
        })?
    } else {
        // Fallback to legacy behavior using deepseek_api_key
        let api_key = state.config.deepseek_api_key.as_ref().ok_or_else(|| {
            tracing::error!("Agent requires DeepSeek API key");
            StatusCode::INTERNAL_SERVER_ERROR
        })?;
        AgentRuntime::new(
            state.db,
            project_id,
            state.tx.clone(),
            api_key.clone(),
            req.max_turns,
        )
    };

    // 运行 Agent
    let result = runtime.run(&req.entry, &req.message).await.map_err(|e| {
        tracing::error!("Agent run failed: {}", e);
        StatusCode::INTERNAL_SERVER_ERROR
    })?;

    Ok(Json(ApiResponse::ok(AgentRunResponse {
        answer: result.answer,
        turns: result.turns,
        tool_calls: result.tool_calls,
        created_nodes: result.created_nodes,
        created_edges: result.created_edges,
        created_intents: result.created_intents,
    })))
}
