import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { AcuityClient } from './clients/acuity.js';
import { appointmentTools } from './tools/appointments.js';
import { calendarTools } from './tools/calendars.js';
import { appointmentTypeTools } from './tools/appointment-types.js';
import { clientTools } from './tools/clients.js';
import { availabilityTools } from './tools/availability.js';
import { blockTools } from './tools/blocks.js';
import { productTools } from './tools/products.js';
import { certificateTools } from './tools/certificates.js';
import { couponTools } from './tools/coupons.js';
import { formTools } from './tools/forms.js';
import { labelTools } from './tools/labels.js';
import { packageTools } from './tools/packages.js';
import { subscriptionTools } from './tools/subscriptions.js';

const ACUITY_USER_ID = process.env.ACUITY_USER_ID;
const ACUITY_API_KEY = process.env.ACUITY_API_KEY;

if (!ACUITY_USER_ID || !ACUITY_API_KEY) {
  throw new Error('ACUITY_USER_ID and ACUITY_API_KEY environment variables are required');
}

const acuityClient = new AcuityClient({
  userId: ACUITY_USER_ID,
  apiKey: ACUITY_API_KEY,
});

// Combine all tools
const allTools = [
  ...appointmentTools,
  ...calendarTools,
  ...appointmentTypeTools,
  ...clientTools,
  ...availabilityTools,
  ...blockTools,
  ...productTools,
  ...certificateTools,
  ...couponTools,
  ...formTools,
  ...labelTools,
  ...packageTools,
  ...subscriptionTools,
];

export const server = new Server(
  {
    name: 'acuity-scheduling-server',
    version: '1.0.0',
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

// List available tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: allTools.map((tool) => ({
      name: tool.name,
      description: tool.description,
      inputSchema: tool.inputSchema,
    })),
  };
});

// Handle tool execution
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const toolName = request.params.name;
  const args = request.params.arguments || {};

  const tool = allTools.find((t) => t.name === toolName);

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

  try {
    return await tool.handler(args, acuityClient);
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : String(error);
    return {
      content: [
        {
          type: 'text',
          text: `Error: ${errorMessage}`,
        },
      ],
      isError: true,
    };
  }
});

export async function runServer() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error('Acuity Scheduling MCP server running on stdio');
}
