import { BaseNode } from './BaseNode.js';

/**
 * AST node for with clauses in pattern matching
 * Represents: with similarity > 0.7
 */
export class WithClauseNode extends BaseNode {
  constructor(location = null) {
    super('WithClause', location);
    this.condition = null; // ExpressionNode
    this.operator = null; // '>', '>=', '<', '<=', '==', '!='
    this.value = null; // Literal value
  }

  /**
   * Set the condition for this with clause
   * @param {ExpressionNode} condition - Condition to set
   */
  setCondition(condition) {
    this.condition = condition;
    this.addChild(condition);
  }

  /**
   * Set the operator for this with clause
   * @param {string} operator - Operator to set
   */
  setOperator(operator) {
    this.operator = operator;
  }

  /**
   * Set the value for this with clause
   * @param {*} value - Value to set
   */
  setValue(value) {
    this.value = value;
  }

  /**
   * Get the condition expression
   * @returns {ExpressionNode|null} Condition expression or null
   */
  getCondition() {
    return this.condition;
  }

  /**
   * Get the operator
   * @returns {string|null} Operator or null
   */
  getOperator() {
    return this.operator;
  }

  /**
   * Get the value
   * @returns {*} Value or null
   */
  getValue() {
    return this.value;
  }

  /**
   * Check if this is a greater than comparison
   * @returns {boolean} True if greater than
   */
  isGreaterThan() {
    return this.operator === '>';
  }

  /**
   * Check if this is a greater than or equal comparison
   * @returns {boolean} True if greater than or equal
   */
  isGreaterThanOrEqual() {
    return this.operator === '>=';
  }

  /**
   * Check if this is a less than comparison
   * @returns {boolean} True if less than
   */
  isLessThan() {
    return this.operator === '<';
  }

  /**
   * Check if this is a less than or equal comparison
   * @returns {boolean} True if less than or equal
   */
  isLessThanOrEqual() {
    return this.operator === '<=';
  }

  /**
   * Check if this is an equality comparison
   * @returns {boolean} True if equality
   */
  isEqual() {
    return this.operator === '==';
  }

  /**
   * Check if this is a not equal comparison
   * @returns {boolean} True if not equal
   */
  isNotEqual() {
    return this.operator === '!=';
  }

  /**
   * Get the comparison string
   * @returns {string} Comparison string
   */
  getComparisonString() {
    const condStr = this.condition ? this.condition.toString() : 'null';
    const valStr = this.value !== null ? this.value.toString() : 'null';
    return `${condStr} ${this.operator} ${valStr}`;
  }

  /**
   * Validate the with clause
   * @returns {string[]} Array of error messages
   */
  validate() {
    const errors = [];

    // Validate condition
    if (!this.condition) {
      errors.push('With clause must have a condition');
    } else {
      const condErrors = this.condition.validate ? this.condition.validate() : [];
      errors.push(...condErrors);
    }

    // Validate operator
    const validOperators = ['>', '>=', '<', '<=', '==', '!='];
    if (!this.operator || !validOperators.includes(this.operator)) {
      errors.push(`Invalid operator: ${this.operator}`);
    }

    // Validate value
    if (this.value === null) {
      errors.push('With clause must have a value');
    }

    return errors;
  }

  toString() {
    return `WithClause(${this.getComparisonString()})`;
  }
}
