//! Prompt handlers — prompts/list, prompts/get

use serde_json::Value;

use crate::protocol::errors::McpError;
use crate::protocol::types::JsonRpcResponse;
use crate::server::core::Server;
use crate::server::handler::{
    RequestContext, error_response, require_initialization, success_response,
};

impl Server {
    /// Handle prompts/list request (with pagination support)
    pub(crate) async fn handle_prompts_list(&self, ctx: RequestContext) -> JsonRpcResponse {
        if let Err(err) = require_initialization(&ctx) {
            return error_response(ctx.request.id, err.to_jsonrpc());
        }

        // Parse cursor if present
        let cursor = ctx
            .params()
            .and_then(|p| p.get("cursor"))
            .and_then(|c| c.as_str());

        let visibility_ctx = self.visibility_context(&ctx.session);
        let all_prompts = self
            .prompt_manager
            .list_for_session(&ctx.session, &visibility_ctx);

        // Apply pagination
        let result = crate::utils::paginate(&all_prompts, cursor, crate::utils::DEFAULT_PAGE_SIZE);

        // Build response (only include nextCursor if present)
        let mut response = serde_json::json!({"prompts": result.items});
        if let Some(next) = result.next_cursor {
            response["nextCursor"] = serde_json::Value::String(next);
        }
        success_response(ctx.request.id, response)
    }

    /// Handle prompts/get request
    pub(crate) async fn handle_prompts_get(&self, ctx: RequestContext) -> JsonRpcResponse {
        if let Err(err) = require_initialization(&ctx) {
            return error_response(ctx.request.id, err.to_jsonrpc());
        }

        // Parse prompt get params
        let params = ctx.params().cloned().unwrap_or(Value::Null);
        let prompt_name = match params.get("name").and_then(|v| v.as_str()) {
            Some(name) => name,
            None => {
                return error_response(
                    ctx.request.id,
                    McpError::validation("invalid_params", "Missing 'name' field").to_jsonrpc(),
                );
            }
        };

        let prompt_params = params.get("arguments").cloned().unwrap_or(Value::Null);

        // Call prompt
        let visibility_ctx = self.visibility_context(&ctx.session);
        match self
            .prompt_manager
            .call_for_session(
                prompt_name,
                prompt_params,
                &ctx.session,
                &self.logger,
                &visibility_ctx,
            )
            .await
        {
            Ok(result) => success_response(
                ctx.request.id,
                serde_json::to_value(result).expect("Failed to serialize prompt result"),
            ),
            Err(e) => error_response(
                ctx.request.id,
                McpError::internal("prompt_get_failed", e.to_string()).to_jsonrpc(),
            ),
        }
    }
}
