import { GenericToolSchema, StandardizedToolCall, ParameterDefinition } from '../../../types/tool';
import { OpenAIFunction, OpenAIToolCall } from './types';

export function convertToolSchema(schema: GenericToolSchema): OpenAIFunction {
  return {
    name: schema.name,
    description: schema.description,
    parameters: {
      type: 'object',
      properties: convertParameters(schema.parameters.properties),
      required: schema.parameters.required,
    },
  };
}

function convertParameters(params: Record<string, ParameterDefinition>): Record<string, ParameterDefinition> {
  const result: Record<string, ParameterDefinition> = {};
  for (const [key, value] of Object.entries(params)) {
    result[key] = convertParameterDefinition(value);
  }
  return result;
}

function convertParameterDefinition(param: ParameterDefinition): ParameterDefinition {
  const result: ParameterDefinition = { type: param.type };
  if (param.description) result.description = param.description;
  if (param.enum) result.enum = param.enum;
  if (param.items) result.items = convertParameterDefinition(param.items);
  if (param.properties) result.properties = convertParameters(param.properties);
  if (param.required) result.required = param.required;
  return result;
}

export function convertToolCall(call: OpenAIToolCall): StandardizedToolCall {
  try {
    const convertedCall = {
      name: call.function.name,
      arguments: JSON.parse(call.function.arguments || '{}'),
    };
    validateToolCall(convertedCall);
    return convertedCall;
  } catch (error) {
    throw new Error(`Failed to convert tool call: ${error instanceof Error ? error.message : String(error)}`);
  }
}

export function convertToolCalls(toolCalls: OpenAIToolCall[] | undefined): StandardizedToolCall[] {
  if (!toolCalls || toolCalls.length === 0) return [];
  return toolCalls.map(call => {
    try {
      return convertToolCall(call);
    } catch (error) {
      console.error('Error converting individual tool call', { call, error });
      return null;
    }
  }).filter((call): call is StandardizedToolCall => call !== null);
}

function validateToolCall(toolCall: StandardizedToolCall): void {
  if (typeof toolCall.name !== 'string' || toolCall.name.trim() === '') {
    throw new Error('Invalid tool call: name must be a non-empty string');
  }
  if (typeof toolCall.arguments !== 'object' || toolCall.arguments === null) {
    throw new Error('Invalid tool call: arguments must be an object');
  }
}