export class VariableResolver {
  /**
   * Resolve variables in an object by replacing ${variable} patterns
   * with actual values from the context
   */
  async resolveVariables(
    obj: any,
    context: Record<string, any>
  ): Promise<any> {
    if (typeof obj === 'string') {
      return this.resolveString(obj, context);
    }
    
    if (Array.isArray(obj)) {
      return Promise.all(obj.map(item => this.resolveVariables(item, context)));
    }
    
    if (obj && typeof obj === 'object') {
      const resolved: Record<string, any> = {};
      
      for (const [key, value] of Object.entries(obj)) {
        resolved[key] = await this.resolveVariables(value, context);
      }
      
      return resolved;
    }
    
    return obj;
  }

  /**
   * Resolve variables in a string
   */
  private resolveString(str: string, context: Record<string, any>): string {
    return str.replace(/\$\{([^}]+)\}/g, (match, path) => {
      const value = this.getValueByPath(context, path.trim());
      return value !== undefined ? String(value) : match;
    });
  }

  /**
   * Get a value from an object using a dot-notation path
   */
  private getValueByPath(obj: any, path: string): any {
    const parts = path.split('.');
    let current = obj;
    
    for (const part of parts) {
      if (current && typeof current === 'object' && part in current) {
        current = current[part];
      } else {
        return undefined;
      }
    }
    
    return current;
  }

  /**
   * Evaluate a condition expression
   */
  async evaluateCondition(
    condition: string,
    context: Record<string, any>
  ): Promise<boolean> {
    // First resolve any variables in the condition
    const resolvedCondition = this.resolveString(condition, context);
    
    try {
      // Simple expression evaluation
      // In production, use a proper expression evaluator like expr-eval
      
      // Handle basic comparisons
      const comparisonMatch = resolvedCondition.match(
        /^(.+?)\s*(===?|!==?|>=?|<=?)\s*(.+)$/
      );
      
      if (comparisonMatch) {
        const [, left, operator, right] = comparisonMatch;
        const leftValue = this.parseValue(left.trim(), context);
        const rightValue = this.parseValue(right.trim(), context);
        
        switch (operator) {
          case '==':
          case '===':
            return leftValue == rightValue;
          case '!=':
          case '!==':
            return leftValue != rightValue;
          case '>':
            return Number(leftValue) > Number(rightValue);
          case '>=':
            return Number(leftValue) >= Number(rightValue);
          case '<':
            return Number(leftValue) < Number(rightValue);
          case '<=':
            return Number(leftValue) <= Number(rightValue);
        }
      }
      
      // Handle boolean values
      if (resolvedCondition === 'true') return true;
      if (resolvedCondition === 'false') return false;
      
      // Check if it's a variable that evaluates to truthy
      const value = this.getValueByPath(context, resolvedCondition);
      return Boolean(value);
      
    } catch (error) {
      console.error('Error evaluating condition:', error);
      return false;
    }
  }

  /**
   * Parse a value that might be a literal or a variable reference
   */
  private parseValue(str: string, context: Record<string, any>): any {
    // Remove quotes if present
    if ((str.startsWith('"') && str.endsWith('"')) || 
        (str.startsWith("'") && str.endsWith("'"))) {
      return str.slice(1, -1);
    }
    
    // Check if it's a number
    if (!isNaN(Number(str))) {
      return Number(str);
    }
    
    // Check if it's a boolean
    if (str === 'true') return true;
    if (str === 'false') return false;
    
    // Try to get it as a variable
    const value = this.getValueByPath(context, str);
    return value !== undefined ? value : str;
  }

  /**
   * Evaluate a complex expression (for future enhancement)
   */
  async evaluateExpression(
    expression: string,
    context: Record<string, any>
  ): Promise<any> {
    // This could be enhanced to support:
    // - Mathematical expressions: ${price * quantity}
    // - Function calls: ${format(date, 'YYYY-MM-DD')}
    // - Array operations: ${items.filter(i => i.active).length}
    
    // For now, just resolve variables
    return this.resolveString(expression, context);
  }
}