import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import express from 'express';
import { z } from 'zod';
import { createApp } from './create-app.js';
import { finalizeAddOns } from './add-ons.js';
import { createDefaultEnvironment } from './environment.js';
const tanStackReactAddOns = [
    {
        id: 'clerk',
        description: 'Enable authentication with Clerk',
    },
    {
        id: 'convex',
        description: 'Enable a database using Convex',
    },
    {
        id: 'form',
        description: 'Form handling library',
    },
    {
        id: 'netlify',
        description: 'Enable deployments to Netlify',
    },
    {
        id: 'sentry',
        description: 'Enable Sentry error tracking',
    },
    {
        id: 'shadcn',
        description: 'Enable integration of the Shadcn UI component library',
    },
    {
        id: 'start',
        description: 'Set this if you want a TanStack Start application that supports server functions or APIs',
    },
    {
        id: 'tanstack-query',
        description: 'Enable TanStack Query for data fetching',
    },
    {
        id: 'store',
        description: 'Enable the TanStack Store state management library',
    },
    {
        id: 'tanchat',
        description: 'Add an AI chatbot example to the application',
    },
];
const tanStackSolidAddOns = [
    {
        id: 'solid-ui',
        description: 'Enable integration of the Solid UI component library',
    },
    {
        id: 'form',
        description: 'Form handling library',
    },
    {
        id: 'sentry',
        description: 'Enable Sentry error tracking',
    },
    {
        id: 'store',
        description: 'Enable the TanStack Store state management library',
    },
    {
        id: 'start',
        description: 'Set this if you want a TanStack Start application that supports server functions or APIs',
    },
    {
        id: 'tanstack-query',
        description: 'Enable TanStack Query for data fetching',
    },
    {
        id: 'tanchat',
        description: 'Add an AI chatbot example to the application',
    },
];
function createServer({ appName, forcedAddOns = [], name, }) {
    const server = new McpServer({
        name: `${appName} Application Builder`,
        version: '1.0.0',
    });
    server.tool('listTanStackReactAddOns', {}, () => {
        return {
            content: [{ type: 'text', text: JSON.stringify(tanStackReactAddOns) }],
        };
    });
    server.tool('createTanStackReactApplication', {
        projectName: z
            .string()
            .describe('The package.json module name of the application (will also be the directory name)'),
        cwd: z.string().describe('The directory to create the application in'),
        addOns: z
            .array(z.enum([
            'clerk',
            'convex',
            'form',
            'netlify',
            'sentry',
            'shadcn',
            'start',
            'store',
            'tanstack-query',
            'tanchat',
        ]))
            .describe('The IDs of the add-ons to install'),
        targetDir: z
            .string()
            .describe('The directory to create the application in. Use the absolute path of the directory you want the application to be created in'),
    }, async ({ projectName, addOns, cwd, targetDir }) => {
        try {
            process.chdir(cwd);
            const chosenAddOns = await finalizeAddOns('react', 'file-router', Array.from(new Set([...addOns, ...forcedAddOns])));
            await createApp({
                projectName: projectName.replace(/^\//, './'),
                framework: 'react',
                typescript: true,
                tailwind: true,
                packageManager: 'pnpm',
                toolchain: 'none',
                mode: 'file-router',
                addOns: true,
                chosenAddOns,
                git: true,
                variableValues: {},
            }, {
                silent: true,
                environment: createDefaultEnvironment(),
                name,
                cwd: targetDir,
            });
            return {
                content: [{ type: 'text', text: 'Application created successfully' }],
            };
        }
        catch (error) {
            return {
                content: [
                    { type: 'text', text: `Error creating application: ${error}` },
                ],
            };
        }
    });
    server.tool('listTanStackSolidAddOns', {}, () => {
        return {
            content: [{ type: 'text', text: JSON.stringify(tanStackSolidAddOns) }],
        };
    });
    server.tool('createTanStackSolidApplication', {
        projectName: z
            .string()
            .describe('The package.json module name of the application (will also be the directory name)'),
        cwd: z.string().describe('The directory to create the application in'),
        addOns: z
            .array(z.enum([
            'solid-ui',
            'form',
            'sentry',
            'store',
            'tanstack-query',
            'tanchat',
        ]))
            .describe('The IDs of the add-ons to install'),
        targetDir: z
            .string()
            .describe('The directory to create the application in. Use the absolute path of the directory you want the application to be created in'),
    }, async ({ projectName, addOns, cwd, targetDir }) => {
        try {
            process.chdir(cwd);
            const chosenAddOns = await finalizeAddOns('solid', 'file-router', Array.from(new Set([...addOns, ...forcedAddOns])));
            await createApp({
                projectName: projectName.replace(/^\//, './'),
                framework: 'solid',
                typescript: true,
                tailwind: true,
                packageManager: 'pnpm',
                toolchain: 'none',
                mode: 'file-router',
                addOns: true,
                chosenAddOns,
                git: true,
                variableValues: {},
            }, {
                silent: true,
                environment: createDefaultEnvironment(),
                name,
                cwd: targetDir,
            });
            return {
                content: [{ type: 'text', text: 'Application created successfully' }],
            };
        }
        catch (error) {
            return {
                content: [
                    { type: 'text', text: `Error creating application: ${error}` },
                ],
            };
        }
    });
    return server;
}
export default async function runServer(sse, { forcedAddOns, appName, name, }) {
    let transport = null;
    const server = createServer({ appName, forcedAddOns, name });
    if (sse) {
        const app = express();
        app.get('/sse', (req, res) => {
            transport = new SSEServerTransport('/messages', res);
            server.connect(transport);
        });
        app.post('/messages', (req, res) => {
            if (transport) {
                transport.handlePostMessage(req, res);
            }
        });
        const port = process.env.PORT || 8080;
        app.listen(port, () => {
            console.log(`Server is running on port http://localhost:${port}/sse`);
        });
    }
    else {
        const transport = new StdioServerTransport();
        await server.connect(transport);
    }
}
