//! Initialize and ping handlers

use serde_json::Value;

use crate::protocol::capabilities::{InitializeRequest, InitializeResult};
use crate::protocol::errors::{ErrorType, McpError};
use crate::protocol::types::{Implementation, JsonRpcResponse};
use crate::protocol::version;
use crate::server::core::Server;
use crate::server::handler::{RequestContext, error_response, success_response};

impl Server {
    /// Handle initialize request
    pub(crate) async fn handle_initialize(&self, ctx: RequestContext) -> JsonRpcResponse {
        // Parse initialize params
        let params = ctx.params().cloned().unwrap_or(Value::Null);
        let req: InitializeRequest = match serde_json::from_value(params) {
            Ok(req) => req,
            Err(_) => {
                return error_response(
                    ctx.request.id,
                    McpError::validation("invalid_params", "Invalid initialize parameters")
                        .to_jsonrpc(),
                );
            }
        };

        // Negotiate protocol version
        let protocol_version = match version::negotiate_protocol_version(&req.protocol_version) {
            Ok(version) => version,
            Err(supported_versions) => {
                tracing::warn!(
                    client = %req.client_info.name,
                    requested = %req.protocol_version,
                    supported = ?supported_versions,
                    "Unsupported protocol version"
                );
                return error_response(
                    ctx.request.id,
                    McpError::builder(ErrorType::Validation, "unsupported_protocol_version")
                        .message("Unsupported protocol version")
                        .detail(
                            "supported",
                            serde_json::to_value(&supported_versions).unwrap(),
                        )
                        .detail("requested", req.protocol_version.clone())
                        .build()
                        .to_jsonrpc(),
                );
            }
        };

        // Log client connection
        tracing::info!(
            client = %req.client_info.name,
            version = %req.client_info.version,
            protocol = %protocol_version,
            "Client connected"
        );

        // Initialize session
        if let Some(mut session) = self.sessions.get_mut(&ctx.session.id) {
            session.initialize(req.client_info, req.capabilities, protocol_version.clone());
        }

        // Build response
        let result = InitializeResult {
            protocol_version,
            capabilities: (**self.capabilities.load()).clone(),
            server_info: Implementation::new(&self.name, &self.version),
            instructions: self.instructions(),
        };

        success_response(
            ctx.request.id,
            serde_json::to_value(result).expect("Failed to serialize InitializeResult"),
        )
    }

    /// Handle ping request
    pub(crate) async fn handle_ping(&self, ctx: RequestContext) -> JsonRpcResponse {
        success_response(ctx.request.id, serde_json::json!({}))
    }
}
