import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
  ListResourcesRequestSchema,
  ReadResourceRequestSchema
} from '@modelcontextprotocol/sdk/types.js';
import { AcuityClient } from './clients/acuity.js';
import { createAppointmentsTools } from './tools/appointments-tools.js';
import { createAvailabilityTools } from './tools/availability-tools.js';
import { createClientsTools } from './tools/clients-tools.js';
import { createCalendarsTools } from './tools/calendars-tools.js';
import { createProductsTools } from './tools/products-tools.js';
import { createFormsTools } from './tools/forms-tools.js';
import { createLabelsTools } from './tools/labels-tools.js';
import { createWebhooksTools } from './tools/webhooks-tools.js';
import { createCouponsTools } from './tools/coupons-tools.js';
import { createBlocksTools } from './tools/blocks-tools.js';

export class AcuityMCPServer {
  private server: Server;
  private client: AcuityClient;
  private allTools: Record<string, any> = {};

  constructor(userId: string, apiKey: string, oauth2Token?: string) {
    this.client = new AcuityClient({ userId, apiKey, oauth2Token });
    this.server = new Server(
      {
        name: 'acuity-scheduling-server',
        version: '1.0.0'
      },
      {
        capabilities: {
          tools: {},
          resources: {}
        }
      }
    );

    this.setupToolHandlers();
    this.setupResourceHandlers();
  }

  private setupToolHandlers(): void {
    // Aggregate all tools
    this.allTools = {
      ...createAppointmentsTools(this.client),
      ...createAvailabilityTools(this.client),
      ...createClientsTools(this.client),
      ...createCalendarsTools(this.client),
      ...createProductsTools(this.client),
      ...createFormsTools(this.client),
      ...createLabelsTools(this.client),
      ...createWebhooksTools(this.client),
      ...createCouponsTools(this.client),
      ...createBlocksTools(this.client)
    };

    // List tools handler
    this.server.setRequestHandler(ListToolsRequestSchema, async () => {
      return {
        tools: Object.entries(this.allTools).map(([name, tool]) => ({
          name,
          description: tool.description,
          inputSchema: tool.inputSchema
        }))
      };
    });

    // Call tool handler
    this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
      const tool = this.allTools[request.params.name];
      if (!tool) {
        throw new Error(`Unknown tool: ${request.params.name}`);
      }

      try {
        return await tool.handler(request.params.arguments || {});
      } catch (error: any) {
        return {
          content: [{
            type: 'text',
            text: JSON.stringify({
              error: error.message,
              statusCode: error.statusCode || 500
            }, null, 2)
          }],
          isError: true
        };
      }
    });
  }

  private setupResourceHandlers(): void {
    // List resources - MCP apps
    this.server.setRequestHandler(ListResourcesRequestSchema, async () => {
      return {
        resources: [
          {
            uri: 'acuity://apps/appointment-dashboard',
            name: 'Appointment Dashboard',
            description: 'Overview dashboard for appointments',
            mimeType: 'text/html'
          },
          {
            uri: 'acuity://apps/appointment-detail',
            name: 'Appointment Detail',
            description: 'Detailed view of a single appointment',
            mimeType: 'text/html'
          },
          {
            uri: 'acuity://apps/appointment-grid',
            name: 'Appointment Grid',
            description: 'Grid view of all appointments',
            mimeType: 'text/html'
          },
          {
            uri: 'acuity://apps/availability-calendar',
            name: 'Availability Calendar',
            description: 'Calendar showing available time slots',
            mimeType: 'text/html'
          },
          {
            uri: 'acuity://apps/client-detail',
            name: 'Client Detail',
            description: 'Detailed view of a client',
            mimeType: 'text/html'
          },
          {
            uri: 'acuity://apps/client-directory',
            name: 'Client Directory',
            description: 'Directory of all clients',
            mimeType: 'text/html'
          },
          {
            uri: 'acuity://apps/calendar-manager',
            name: 'Calendar Manager',
            description: 'Manage calendars',
            mimeType: 'text/html'
          },
          {
            uri: 'acuity://apps/product-catalog',
            name: 'Product Catalog',
            description: 'Browse products, add-ons, and packages',
            mimeType: 'text/html'
          },
          {
            uri: 'acuity://apps/form-responses',
            name: 'Form Responses',
            description: 'View intake form responses',
            mimeType: 'text/html'
          },
          {
            uri: 'acuity://apps/label-manager',
            name: 'Label Manager',
            description: 'Manage appointment labels',
            mimeType: 'text/html'
          },
          {
            uri: 'acuity://apps/coupon-manager',
            name: 'Coupon Manager',
            description: 'Manage coupons and discounts',
            mimeType: 'text/html'
          },
          {
            uri: 'acuity://apps/booking-flow',
            name: 'Booking Flow',
            description: 'Interactive booking interface',
            mimeType: 'text/html'
          },
          {
            uri: 'acuity://apps/schedule-overview',
            name: 'Schedule Overview',
            description: 'High-level schedule overview',
            mimeType: 'text/html'
          },
          {
            uri: 'acuity://apps/blocked-time-manager',
            name: 'Blocked Time Manager',
            description: 'Manage blocked time slots',
            mimeType: 'text/html'
          }
        ]
      };
    });

    // Read resource - serve MCP app HTML
    this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
      const appName = request.params.uri.replace('acuity://apps/', '');
      
      try {
        const { default: appHtml } = await import(`./ui/react-app/${appName}.js`);
        return {
          contents: [{
            uri: request.params.uri,
            mimeType: 'text/html',
            text: appHtml
          }]
        };
      } catch (error) {
        throw new Error(`App not found: ${appName}`);
      }
    });
  }

  async run(): Promise<void> {
    const transport = new StdioServerTransport();
    await this.server.connect(transport);
    console.error('Acuity Scheduling MCP server running on stdio');
  }
}
