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 { RipplingClient } from './clients/rippling.js';
import { createEmployeesTools } from './tools/employees-tools.js';
import { createCompaniesTools } from './tools/companies-tools.js';
import { createPayrollTools } from './tools/payroll-tools.js';
import { createTimeTools } from './tools/time-tools.js';
import { createBenefitsTools } from './tools/benefits-tools.js';
import { createATSTools } from './tools/ats-tools.js';
import { createLearningTools } from './tools/learning-tools.js';
import { createDevicesTools } from './tools/devices-tools.js';
import { createGroupsTools } from './tools/groups-tools.js';
import { createCustomObjectsTools } from './tools/custom-objects-tools.js';

export class RipplingMCPServer {
  private server: Server;
  private client: RipplingClient;
  private tools: Record<string, any>;

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

    // Initialize Rippling client
    this.client = new RipplingClient({
      apiKey: process.env.RIPPLING_API_KEY,
      accessToken: process.env.RIPPLING_ACCESS_TOKEN,
      baseUrl: process.env.RIPPLING_BASE_URL,
    });

    // Combine all tools
    this.tools = {
      ...createEmployeesTools(this.client),
      ...createCompaniesTools(this.client),
      ...createPayrollTools(this.client),
      ...createTimeTools(this.client),
      ...createBenefitsTools(this.client),
      ...createATSTools(this.client),
      ...createLearningTools(this.client),
      ...createDevicesTools(this.client),
      ...createGroupsTools(this.client),
      ...createCustomObjectsTools(this.client),
    };

    this.setupHandlers();
  }

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

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

      const tool = this.tools[name];
      if (!tool) {
        throw new Error(`Unknown tool: ${name}`);
      }

      try {
        return await tool.handler(args);
      } catch (error: any) {
        return {
          content: [
            {
              type: 'text',
              text: `Error: ${error.message}\n${error.details ? JSON.stringify(error.details, null, 2) : ''}`,
            },
          ],
          isError: true,
        };
      }
    });
  }

  async run() {
    const transport = new StdioServerTransport();
    await this.server.connect(transport);
    console.error('Rippling MCP server running on stdio');
  }
}
