use crate::av_client::AvClient;
use axum::{http::StatusCode, response::{IntoResponse, Json}};
use serde::{Deserialize, Serialize};
use tracing::{info, warn};

#[derive(Deserialize)]
pub struct TestConnectionRequest {
    // This is the MCP endpoint URL
    pub api_url: String,
    // The API key is passed for validation but might not be used directly
    // in the MCP connection itself, depending on auth mechanism.
    pub api_key: Option<String>,
}

#[derive(Serialize)]
pub struct TestConnectionResponse {
    pub success: bool,
    pub message: String,
}

/// [POST /test]
/// Dynamically tests a connection to an MCP endpoint.
pub async fn test_connection(
    Json(payload): Json<TestConnectionRequest>,
) -> impl IntoResponse {
    info!("Testing connection to MCP endpoint: {}", payload.api_url);

    if payload.api_url.is_empty() {
        return (
            StatusCode::BAD_REQUEST,
            Json(TestConnectionResponse {
                success: false,
                message: "API URL (MCP Endpoint) cannot be empty.".to_string(),
            }),
        ).into_response();
    }

    // 要求传入 base MCP URL（不包含查询参数）与 api_key，然后按官方文档拼接 ?apikey=
    if payload.api_url.contains('?') {
        return (
            StatusCode::BAD_REQUEST,
            Json(TestConnectionResponse {
                success: false,
                message: "API URL 必须为基础地址（不可包含查询参数）".to_string(),
            }),
        ).into_response();
    }
    let Some(key) = &payload.api_key else {
        return (
            StatusCode::BAD_REQUEST,
            Json(TestConnectionResponse {
                success: false,
                message: "测试连接需要提供 api_key".to_string(),
            }),
        ).into_response();
    };
    let final_url = format!("{}?apikey={}", payload.api_url, key);
    info!("Testing MCP with final endpoint: {}", final_url);
    let mcp_client = match AvClient::connect(&final_url).await {
        Ok(client) => client,
        Err(e) => {
            warn!("Failed to establish MCP transport: {}", e);
            return (
                StatusCode::BAD_REQUEST,
                Json(TestConnectionResponse {
                    success: false,
                    message: format!("Failed to establish MCP transport: {}", e),
                }),
            ).into_response();
        }
    };

    // Call list_tools to verify the connection.
    match mcp_client.list_tools().await {
        Ok(tools) => {
            info!("MCP list_tools successful. Found {} tools.", tools.len());
            (
                StatusCode::OK,
                Json(TestConnectionResponse {
                    success: true,
                    message: format!("Successfully connected to MCP endpoint and found {} tools.", tools.len()),
                }),
            ).into_response()
        }
        Err(e) => {
            warn!("MCP list_tools failed: {}", e);
            (
                StatusCode::INTERNAL_SERVER_ERROR,
                Json(TestConnectionResponse {
                    success: false,
                    message: format!("MCP command 'list_tools' failed: {}", e),
                }),
            ).into_response()
        }
    }
}
