'use strict';

const { Server } = require('@modelcontextprotocol/sdk/server/index.js');
const {
    StreamableHTTPServerTransport,
} = require('@modelcontextprotocol/sdk/server/streamableHttp.js');
const {
    CallToolRequestSchema,
    ListToolsRequestSchema,
} = require('@modelcontextprotocol/sdk/types.js');
const { registerAllTools } = require('./toolRegistry');

/**
 * Handle MCP HTTP request
 * This creates a stateless MCP server for each request
 */
async function handleMcpHttpRequest(req, res, user, apiToken) {
    try {
        // Create context for tools
        const context = {
            userId: user.id,
            user: user,
            apiToken: apiToken,
        };

        // Initialize MCP server
        const server = new Server(
            {
                name: process.env.MCP_SERVER_NAME || 'tududi',
                version: process.env.MCP_SERVER_VERSION || '1.0.0',
            },
            {
                capabilities: {
                    tools: {},
                },
            }
        );

        // Store tools registry
        const tools = [];

        // Register list tools handler
        server.setRequestHandler(ListToolsRequestSchema, async () => {
            return {
                tools: tools,
            };
        });

        // Register call tool handler
        server.setRequestHandler(CallToolRequestSchema, async (request) => {
            const toolName = request.params.name;
            const tool = tools.find((t) => t.name === toolName);

            if (!tool) {
                throw new Error(`Unknown tool: ${toolName}`);
            }

            try {
                const result = await tool.handler(
                    request.params.arguments || {},
                    context
                );
                return result;
            } catch (error) {
                console.error(`Error executing tool ${toolName}:`, error);
                return {
                    content: [
                        {
                            type: 'text',
                            text: `Error: ${error.message}`,
                        },
                    ],
                    isError: true,
                };
            }
        });

        // Register all tools
        registerAllTools(server, context, tools);

        // Create HTTP transport (stateless mode)
        const transport = new StreamableHTTPServerTransport({
            sessionIdGenerator: undefined, // Stateless mode
        });

        // Connect server to transport
        await server.connect(transport);

        // Handle the HTTP request
        await transport.handleRequest(req, res, req.body);

        // Update token last_used_at (fire and forget)
        apiToken
            .update({ last_used_at: new Date() })
            .catch((err) =>
                console.error('Failed to update token last_used_at:', err)
            );
    } catch (error) {
        console.error('MCP HTTP handler error:', error);

        // Only send response if headers haven't been sent
        if (!res.headersSent) {
            res.status(500).json({
                error: 'Internal server error',
                message: error.message,
            });
        }
    }
}

module.exports = {
    handleMcpHttpRequest,
};
