import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { SSESession } from './sse-mcp-server';
import { AuthHandler } from './auth-handler';

export interface MCPConfig {
  tools: any[];
  authHandler: AuthHandler;
}

export class MCPHandler {
  private server: Server;
  private config: MCPConfig;
  private registeredTools: Map<string, any> = new Map();

  constructor(config: MCPConfig) {
    this.config = config;
    this.server = new Server({
      name: 'trackex-mcp-server',
      version: '1.0.0',
      capabilities: {
        tools: {},
      },
    });
    this.setupTools();
  }

  private setupTools(): void {
    // Register all tools
    this.config.tools.forEach(tool => {
      this.registeredTools.set(tool.name, tool);
    });
  }

  public async handleRequest(session: SSESession, request: any): Promise<any> {
    // Check authentication for non-initialization requests
    if (request.method !== 'initialize' && 
        request.method !== 'auth/authenticate' && 
        !this.config.authHandler.isAuthenticated(session.id)) {
      throw new Error('Authentication required');
    }

    // Handle initialization
    if (request.method === 'initialize') {
      return this.handleInitialize(request);
    }

    // Handle authentication
    if (request.method === 'auth/authenticate') {
      return this.handleAuthentication(session, request);
    }

    // Handle tool calls
    if (request.method === 'tools/call') {
      return this.handleToolCall(request);
    }

    // Handle tool listing
    if (request.method === 'tools/list') {
      return this.handleToolList();
    }

    throw new Error('Unknown method');
  }

  private async handleInitialize(request: any): Promise<any> {
    return {
      protocolVersion: '2024-11-05',
      capabilities: {
        tools: {},
        logging: {}
      },
      serverInfo: {
        name: 'trackex-mcp-server',
        version: '1.0.0'
      }
    };
  }

  private async handleAuthentication(session: SSESession, request: any): Promise<any> {
    const apiKey = request.params?.apiKey;
    if (!apiKey) {
      throw new Error('API key required');
    }

    await this.config.authHandler.authenticate(session, apiKey);
    return { success: true };
  }

  private async handleToolCall(request: any): Promise<any> {
    const { name, args } = request.params;
    const tool = this.registeredTools.get(name);
    
    if (!tool) {
      throw new Error(`Tool ${name} not found`);
    }

    // Here you would implement the actual tool logic
    // For now, return a mock response
    return {
      success: true,
      result: `Called ${name} with args: ${JSON.stringify(args)}`
    };
  }

  private async handleToolList(): Promise<any> {
    return {
      tools: Array.from(this.registeredTools.values()).map(tool => ({
        name: tool.name,
        description: tool.description,
        parameters: tool.parameters
      }))
    };
  }
} 