import { logger } from '../config/logger';
import { AppError } from '../utils/AppError';
import { financeTools } from './financeTools';
import type { ToolCall, ToolDefinition, ToolExecutionContext, ToolResult } from './types';

export class ToolRegistry {
  private readonly tools = new Map<string, ToolDefinition>();

  constructor(toolDefinitions: ToolDefinition[] = financeTools) {
    toolDefinitions.forEach((tool) => {
      this.tools.set(tool.name, tool);
    });
  }

  list(): ToolDefinition[] {
    return Array.from(this.tools.values());
  }

  async execute(call: ToolCall, context: ToolExecutionContext): Promise<ToolResult> {
    const tool = this.tools.get(call.name);
    if (!tool) {
      throw new AppError(`Tool ${call.name} does not exist.`, 400, 'TOOL_NOT_FOUND');
    }

    const startedAt = Date.now();
    const input = tool.parameters.parse(call.arguments);

    logger.info({ tool: call.name, arguments: input }, 'Executing tool');

    try {
      const data = await tool.execute(input, context);
      logger.info({ tool: call.name, durationMs: Date.now() - startedAt }, 'Tool executed');
      return {
        tool: call.name,
        success: true,
        data,
      };
    } catch (error) {
      logger.error({ tool: call.name, durationMs: Date.now() - startedAt, error }, 'Tool execution failed');
      return {
        tool: call.name,
        success: false,
        error: error instanceof Error ? error.message : error,
      };
    }
  }
}
