#!/usr/bin/env node

/**
 * URL Builder MCP Server
 *
 * MCP server that provides URL building tools following project-specific rules
 */

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 { buildBookingUrl, buildInternalUrl, buildCompleteUrl, validateUrlParams } from './urlBuilder.js';
import { UrlParams } from './types.js';

class UrlBuilderServer {
  private server: Server;

  constructor() {
    this.server = new Server({
      name: 'url-builder-mcp',
      version: '1.0.0',
    });

    this.setupToolHandlers();
    this.setupErrorHandling();
  }

  private setupErrorHandling(): void {
    this.server.onerror = error => console.error('[MCP Error]', error);
    process.on('SIGINT', async () => {
      await this.server.close();
      process.exit(0);
    });
  }

  private setupToolHandlers(): void {
    this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: [
        {
          name: 'build_booking_url',
          description: 'Build external booking URL with query parameters',
          inputSchema: {
            type: 'object',
            properties: {
              checkIn: {
                type: 'string',
                description: 'Check-in date in YYYY-MM-DD format',
                pattern: '^\\d{4}-\\d{2}-\\d{2}$',
              },
              checkOut: {
                type: 'string',
                description: 'Check-out date in YYYY-MM-DD format',
                pattern: '^\\d{4}-\\d{2}-\\d{2}$',
              },
              guestName: {
                type: 'string',
                description: 'Guest name (required)',
              },
              guestPhone: {
                type: 'string',
                description: 'Guest phone (required)',
              },
              adults: {
                type: 'number',
                description: 'Number of adults (optional, default: 2)',
                minimum: 1,
                maximum: 20,
              },
              children: {
                type: 'number',
                description: 'Number of children (optional, default: 0)',
                minimum: 0,
                maximum: 10,
              },
              roomType: {
                type: 'string',
                description: 'Room type name (optional, e.g., "garden-deluxe")',
              },
              guestEmail: {
                type: 'string',
                description: 'Guest email (optional)',
              },
              addUtmTracking: {
                type: 'boolean',
                description: 'Add UTM tracking parameters for traffic analysis (default: true)',
              },
              utmCampaign: {
                type: 'string',
                description: 'Custom UTM campaign name (default: "url-builder-mcp")',
              },
              utmSource: {
                type: 'string',
                description: 'Custom UTM source (default: "claude-desktop")',
              },
              utmMedium: {
                type: 'string',
                description: 'Custom UTM medium (default: "ai-assistant")',
              },
            },
            required: ['checkIn', 'checkOut', 'guestName', 'guestPhone'],
          },
        },
        {
          name: 'build_internal_url',
          description: 'Build internal project URL with query parameters and UTM tracking',
          inputSchema: {
            type: 'object',
            properties: {
              checkIn: {
                type: 'string',
                description: 'Check-in date in YYYY-MM-DD format',
                pattern: '^\\d{4}-\\d{2}-\\d{2}$',
              },
              checkOut: {
                type: 'string',
                description: 'Check-out date in YYYY-MM-DD format',
                pattern: '^\\d{4}-\\d{2}-\\d{2}$',
              },
              adults: {
                type: 'number',
                description: 'Number of adults (optional, default: 2)',
                minimum: 1,
                maximum: 20,
              },
              children: {
                type: 'number',
                description: 'Number of children (optional, default: 0)',
                minimum: 0,
                maximum: 10,
              },
              roomType: {
                type: 'string',
                description: 'Room type name (optional)',
              },
              guestName: {
                type: 'string',
                description: 'Guest name (optional)',
              },
              guestEmail: {
                type: 'string',
                description: 'Guest email (optional)',
              },
              guestPhone: {
                type: 'string',
                description: 'Guest phone (optional)',
              },
              useBaseDomain: {
                type: 'boolean',
                description: 'Use base domain for complete URL (default: false)',
              },
              addUtmTracking: {
                type: 'boolean',
                description: 'Add UTM tracking parameters (default: true)',
              },
            },
            required: ['checkIn', 'checkOut'],
          },
        },
        {
          name: 'build_complete_url',
          description: 'Build complete URL using configurable base domain with UTM tracking',
          inputSchema: {
            type: 'object',
            properties: {
              relativePath: {
                type: 'string',
                description: 'Relative path to append to base domain (e.g., "/api/bookings")',
              },
              checkIn: {
                type: 'string',
                description: 'Check-in date in YYYY-MM-DD format (optional)',
                pattern: '^\\d{4}-\\d{2}-\\d{2}$',
              },
              checkOut: {
                type: 'string',
                description: 'Check-out date in YYYY-MM-DD format (optional)',
                pattern: '^\\d{4}-\\d{2}-\\d{2}$',
              },
              adults: {
                type: 'number',
                description: 'Number of adults (optional)',
                minimum: 1,
                maximum: 20,
              },
              children: {
                type: 'number',
                description: 'Number of children (optional)',
                minimum: 0,
                maximum: 10,
              },
              addUtmTracking: {
                type: 'boolean',
                description: 'Add UTM tracking parameters (default: true)',
              },
            },
            required: ['relativePath'],
          },
        },
        {
          name: 'validate_url_params',
          description: 'Validate URL parameters without building URLs',
          inputSchema: {
            type: 'object',
            properties: {
              checkIn: {
                type: 'string',
                description: 'Check-in date in YYYY-MM-DD format',
                pattern: '^\\d{4}-\\d{2}-\\d{2}$',
              },
              checkOut: {
                type: 'string',
                description: 'Check-out date in YYYY-MM-DD format',
                pattern: '^\\d{4}-\\d{2}-\\d{2}$',
              },
              adults: {
                type: 'number',
                description: 'Number of adults (optional)',
                minimum: 1,
                maximum: 20,
              },
              children: {
                type: 'number',
                description: 'Number of children (optional)',
                minimum: 0,
                maximum: 10,
              },
              roomType: {
                type: 'string',
                description: 'Room type name (optional, e.g., "garden-deluxe")',
              },
              guestName: {
                type: 'string',
                description: 'Guest name (optional)',
              },
              guestEmail: {
                type: 'string',
                description: 'Guest email (optional)',
              },
              guestPhone: {
                type: 'string',
                description: 'Guest phone (optional)',
              },
            },
            required: ['checkIn', 'checkOut'],
          },
        },
      ],
    }));

    this.server.setRequestHandler(CallToolRequestSchema, async request => {
      const { name, arguments: args } = request.params;

      try {
        switch (name) {
          case 'build_booking_url': {
            const { addUtmTracking, utmCampaign, utmSource, utmMedium, ...params } = args as any;

            // Build options with UTM parameters
            const options = {
              addUtmTracking: addUtmTracking !== false, // Default to true
              customUtm: {
                ...(utmCampaign && { utm_campaign: utmCampaign }),
                ...(utmSource && { utm_source: utmSource }),
                ...(utmMedium && { utm_medium: utmMedium }),
              },
            };

            const url = buildBookingUrl(params as UrlParams, options);
            return {
              content: [
                {
                  type: 'text',
                  text: `Booking URL with UTM tracking: ${url}`,
                },
              ],
            };
          }

          case 'build_internal_url': {
            const { useBaseDomain, addUtmTracking, ...params } = args as any;

            const options = {
              useBaseDomain: useBaseDomain || false,
              addUtmTracking: addUtmTracking !== false,
            };

            const url = buildInternalUrl(params as UrlParams, options);
            return {
              content: [
                {
                  type: 'text',
                  text: `Internal URL with UTM tracking: ${url}`,
                },
              ],
            };
          }

          case 'build_complete_url': {
            const { relativePath, addUtmTracking, ...params } = args as any;

            const options = {
              addUtmTracking: addUtmTracking !== false,
            };

            // Only pass params if they exist
            const urlParams = Object.keys(params).length > 0 ? (params as UrlParams) : undefined;
            const url = buildCompleteUrl(relativePath, urlParams, options);
            return {
              content: [
                {
                  type: 'text',
                  text: `Complete URL with UTM tracking: ${url}`,
                },
              ],
            };
          }

          case 'validate_url_params': {
            const params = args as unknown as UrlParams;
            const validation = validateUrlParams(params);
            return {
              content: [
                {
                  type: 'text',
                  text: validation.valid
                    ? 'Parameters are valid'
                    : `Validation errors: ${validation.errors.join(', ')}`,
                },
              ],
            };
          }

          default:
            throw new Error(`Unknown tool: ${name}`);
        }
      } catch (error) {
        return {
          content: [
            {
              type: 'text',
              text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
            },
          ],
          isError: true,
        };
      }
    });
  }

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

const server = new UrlBuilderServer();
server.run().catch(console.error);
