// src/aiConditionHelper.ts
import { IWorkflowContext } from '@flowlab/core';
import { AIProviderRegistry, AIModelOptions } from './types';
import { aiProviderRegistry } from './providerRegistry'; // Use singleton

export class AIConditionHelper {
  // Use the shared registry
  private registry: AIProviderRegistry = aiProviderRegistry;
  // TODO: Integrate prompt rendering logic similar to BaseAINode

  /**
   * Evaluates a condition using an AI model, expecting a 'true' or 'false' response.
   * @param context Workflow context for variable access.
   * @param providerName Name of the AI provider.
   * @param promptTemplate Prompt guiding the AI to answer true/false.
   * @param options Model options.
   * @returns Promise<boolean>
   */
  async evaluateBoolean(
    context: IWorkflowContext,
    providerName: string,
    promptTemplate: string,
    options?: AIModelOptions
  ): Promise<boolean> {
    try {
      const provider = this.registry.getProvider(providerName);
      // Simplified rendering for example - use BaseAINode's logic ideally
      const renderedPrompt = this.renderPrompt(promptTemplate, context.variables);
      const { text } = await provider.generateText(renderedPrompt, { ...options, maxTokens: 10 }); // Limit tokens for boolean
      return text.trim().toLowerCase() === 'true';
    } catch (error) {
      console.error(`AI Boolean condition evaluation failed: ${error}`);
      return false; // Default to false on error? Or throw? Needs decision.
    }
  }

   /**
    * Asks AI to choose one option from a list based on the prompt.
    * @param context Workflow context.
    * @param providerName AI provider name.
    * @param promptTemplate Prompt guiding the AI to select a choice.
    * @param choices Array of possible string choices.
    * @param options Model options.
    * @returns Promise<string> The chosen string, or the first choice as fallback on error/mismatch.
    */
  async evaluateChoice(
    context: IWorkflowContext,
    providerName: string,
    promptTemplate: string,
    choices: string[],
    options?: AIModelOptions
 ): Promise<string> {
     if (!choices || choices.length === 0) return ''; // Return empty if no choices
     try {
         const provider = this.registry.getProvider(providerName);
         const renderedPrompt = this.renderPrompt(promptTemplate, context.variables); // Use shared render logic
         const promptWithChoices = `${renderedPrompt}\n\nChoose one of the following options exactly: ${choices.join(', ')}`;
         const { text } = await provider.generateText(promptWithChoices, options);
         const chosen = text.trim();
         // Find the choice that matches the AI output (case-insensitive, trim)
         const matchedChoice = choices.find(c => c.trim().toLowerCase() === chosen.toLowerCase());
         return matchedChoice || choices[0]; // Return matched or fallback to first choice
     } catch (error) {
         console.error(`AI Choice condition evaluation failed: ${error}`);
         return choices[0]; // Fallback to first choice on error
     }
 }

  // Placeholder for shared rendering logic (ideally import from utils)
  private renderPrompt(template: string, variables: Record<string, any>): string {
      let rendered = template;
      // Matches ${varName}
       rendered = rendered.replace(/\$\{(\w+)\}/g, (match, varName) => {
           return String(variables[varName] ?? '');
       });
      return rendered;
  }
}

// Default export for easy access
export const aiConditionHelper = new AIConditionHelper();