/**
 * Xero MCP Server
 * Provides modular tools for Xero Accounting API operations
 */

import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
  Tool
} from '@modelcontextprotocol/sdk/types.js';
import { XeroClient } from './clients/xero.js';
import { getAllTools, handleToolCall as handleTool } from './tools/index.js';

export class XeroMCPServer {
  private server: Server;
  private client: XeroClient;
  private toolsCache: Tool[] | null = null;

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

    this.setupHandlers();
  }

  private setupHandlers(): void {
    this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: this.getTools()
    }));

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

      try {
        const result = await handleTool(name, args || {}, this.client);
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(result, null, 2)
            }
          ]
        };
      } catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify({ error: errorMessage }, null, 2)
            }
          ],
          isError: true
        };
      }
    });
  }

  private getTools(): Tool[] {
    if (this.toolsCache) {
      return this.toolsCache;
    }

    this.toolsCache = getAllTools(this.client);
    console.error(`Loaded ${this.toolsCache.length} Xero tools`);
    return this.toolsCache;
  }

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