/**
 * Behavior utilities for Vareon Calculator calculators
 * Provides helpers for auto-calculation and other interaction behaviors
 */

/**
 * Check if auto-calculate is enabled for a given container.
 * Reads from the closest .vareoncalc-root data attribute or global config.
 * Supports explicit enable ("1"/"true") and explicit disable ("0"/"false").
 * @param {HTMLElement} container - The calculator container element
 * @returns {boolean} Whether auto-calculate is enabled
 */
export function shouldAutoCalculate(container) {
  const root = container.closest('.vareoncalc-root');
  if (root) {
    // Explicit disable takes precedence
    if (root.dataset.autoCalculate === '0' || root.dataset.autoCalculate === 'false') {
      return false;
    }
    // Explicit enable
    if (root.dataset.autoCalculate === '1' || root.dataset.autoCalculate === 'true') {
      return true;
    }
  }

  // Fallback to global config
  const cfg = (typeof window !== 'undefined' && window.VAREONCALC_CFG) || {};
  const a11y = cfg.accessibility || {};

  return !!a11y.autoCalculate;
}

/**
 * Get the auto-calculate delay in milliseconds.
 * @param {HTMLElement} container - The calculator container element
 * @returns {number} Delay in milliseconds (default 400)
 */
export function getAutoCalcDelay(container) {
  const root = container.closest('.vareoncalc-root');
  if (root && root.dataset.autoCalcDelay) {
    const val = parseInt(root.dataset.autoCalcDelay, 10);
    if (!isNaN(val) && val >= 0) {
      return val;
    }
  }
  const cfg = (typeof window !== 'undefined' && window.VAREONCALC_CFG) || {};
  const a11y = cfg.accessibility || {};
  if (typeof a11y.autoCalculateDelay === 'number') {
    // Back-compat: legacy 300ms becomes 400ms (Lite uses 400ms).
    if (a11y.autoCalculateDelay === 300) {
      return 400;
    }
    return a11y.autoCalculateDelay;
  }
  return 400;
}

/**
 * Wire up auto-calculate behavior for inputs within a container.
 * Only attaches listeners if auto-calculate is enabled.
 * Returns a cleanup function to remove listeners (useful for dynamic re-renders).
 * @param {HTMLElement} container - The calculator container element
 * @param {HTMLElement} calcButton - The calculate button to trigger
 * @param {HTMLElement[]} inputs - Array of input elements to watch
 * @param {Function} [validate] - Optional validation function; if provided, must return true to trigger calc
 * @returns {Function} Cleanup function to remove event listeners
 */
export function setupAutoCalc(container, calcButton, inputs, validate) {
  // Prevent double-wiring if already attached
  if (container.dataset.vareoncalcAutoWired === 'true') {
    return () => {};
  }

  if (!shouldAutoCalculate(container)) {
    return () => {}; // Return no-op cleanup
  }

  if (!calcButton || !inputs || inputs.length === 0) {
    return () => {};
  }

  container.dataset.vareoncalcAutoWired = 'true';

  const delay = getAutoCalcDelay(container);
  let debounceTimer = null;

  const triggerCalc = () => {
    clearTimeout(debounceTimer);
    debounceTimer = setTimeout(() => {
      if (typeof validate === 'function') {
        if (!validate()) {
          return;
        }
      }
      calcButton.click();
    }, delay);
  };

  inputs.forEach(input => {
    if (input) {
      input.addEventListener('input', triggerCalc);
      input.addEventListener('change', triggerCalc);
    }
  });

  // Return cleanup function
  return () => {
    clearTimeout(debounceTimer);
    inputs.forEach(input => {
      if (input) {
        input.removeEventListener('input', triggerCalc);
        input.removeEventListener('change', triggerCalc);
      }
    });
  };
}

/**
 * Debounce helper with a cancel method.
 * @param {Function} func - Function to debounce
 * @param {number} wait - Debounce delay in ms
 * @returns {Function} Debounced function with .cancel() method
 */
export function debounce(func, wait = 300) {
  let timeoutId = null;

  const debounced = (...args) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => {
      func.apply(this, args);
    }, wait);
  };

  debounced.cancel = () => {
    clearTimeout(timeoutId);
  };

  return debounced;
}

/**
 * Run a calculation function immediately with an optional loading state.
 * @param {Function} calcFn - Calculation function to execute
 * @param {HTMLElement} button - Optional button to show loading state
 * @param {number} minDuration - Minimum duration for loading state (ms)
 */
export function runCalculation(calcFn, button = null, minDuration = 200) {
  const startTime = Date.now();

  if (button) {
    button.disabled = true;
    button.dataset.originalText = button.textContent;
    button.textContent = 'Calculating...';
  }

  try {
    calcFn();
  } finally {
    if (button) {
      const elapsed = Date.now() - startTime;
      const remaining = Math.max(0, minDuration - elapsed);

      setTimeout(() => {
        button.disabled = false;
        if (button.dataset.originalText) {
          button.textContent = button.dataset.originalText;
        }
      }, remaining);
    }
  }
}



