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

/**
 * AST node for field definitions within type definitions
 * Represents: fieldName: type BEHAVES { ... } CACHE lazy
 */
export class FieldNode extends BaseNode {
  constructor(name, type, location = null) {
    super('Field', location);
    this.name = name;
    this.type = type;
    this.isArray = false;
    this.behavior = null;
    this.cacheDirective = null;
    this.isOptional = false;
    this.defaultValue = null;
  }

  /**
   * Set the behavior for this field
   * @param {BehaviorNode} behavior - Behavior to set
   */
  setBehavior(behavior) {
    this.behavior = behavior;
    this.addChild(behavior);
  }

  /**
   * Set the cache directive for this field
   * @param {string} directive - Cache directive ('lazy')
   */
  setCacheDirective(directive) {
    if (directive === 'eager') {
      if (!FieldNode._warnedEagerCacheDirective) {
        FieldNode._warnedEagerCacheDirective = true;
        console.warn('[FieldNode] CACHE eager is deprecated; treating as CACHE lazy.');
      }
      this.cacheDirective = 'lazy';
      return;
    }
    this.cacheDirective = directive;
  }

  /**
   * Mark this field as an array type
   * @param {boolean} isArray - Whether this is an array
   */
  setArray(isArray) {
    this.isArray = isArray;
  }

  /**
   * Set whether this field is optional
   * @param {boolean} optional - Whether field is optional
   */
  setOptional(optional) {
    this.isOptional = optional;
  }

  /**
   * Set default value for this field
   * @param {*} value - Default value
   */
  setDefaultValue(value) {
    this.defaultValue = value;
  }

  /**
   * Get the full type string including array notation
   * @returns {string} Full type string
   */
  getFullType() {
    let typeStr = this.type;
    if (this.isArray) {
      typeStr += '[]';
    }
    if (this.isOptional) {
      typeStr += '?';
    }
    return typeStr;
  }

  /**
   * Check if this field has decay behavior
   * @returns {boolean} True if field has decay behavior
   */
  hasDecayBehavior() {
    return this.behavior && this.behavior.type === 'decay';
  }

  /**
   * Check if this field has blur behavior
   * @returns {boolean} True if field has blur behavior
   */
  hasBlurBehavior() {
    return this.behavior && this.behavior.type === 'blur';
  }

  /**
   * Check if this field has TTL behavior
   * @returns {boolean} True if field has TTL behavior
   */
  hasTTLBehavior() {
    return this.behavior && this.behavior.type === 'ttl';
  }

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

    // Validate field name
    if (!this.name || typeof this.name !== 'string') {
      errors.push(`Invalid field name: ${this.name}`);
    }

    // Validate type
    if (!this.type || typeof this.type !== 'string') {
      errors.push(`Invalid field type: ${this.type}`);
    }

    // Validate behavior if present
    if (this.behavior) {
      const behaviorErrors = this.behavior.validate ? this.behavior.validate() : [];
      errors.push(...behaviorErrors);
    }

    // Validate cache directive
    if (this.cacheDirective && !['lazy'].includes(this.cacheDirective)) {
      errors.push(`Invalid cache directive: ${this.cacheDirective}`);
    }

    return errors;
  }

  toString() {
    return `Field(${this.name}: ${this.getFullType()})`;
  }
}
