/**
 * Behavior utilities for Vareon Calculator Suite Lite.
 */

/**
 * Whether auto-calc is enabled for a container (data attribute overrides global config).
 *
 * @param {HTMLElement} container
 * @returns {boolean}
 */
export function shouldAutoCalculate(container) {
    const root = container.closest('.vareoncalc-root');
    if (root) {
        if (root.dataset.autoCalculate === '0' || root.dataset.autoCalculate === 'false') {
            return false;
        }
        if (root.dataset.autoCalculate === '1' || root.dataset.autoCalculate === 'true') {
            return true;
        }
    }

    const cfg = (typeof window !== 'undefined' && window.VAREONCALC_CFG) || {};
    const a11y = cfg.accessibility || {};

    return !!a11y.autoCalculate;
}

/**
 * Auto-calc delay in milliseconds.
 *
 * @param {HTMLElement} container
 * @returns {number}
 */
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') {
        return a11y.autoCalculateDelay;
    }

    return 400;
}

/**
 * Wire auto-calc to inputs and return a cleanup function.
 *
 * @param {HTMLElement} container
 * @param {HTMLElement} calcButton
 * @param {HTMLElement[]} inputs
 * @param {Function} [validate] Must return true to trigger calc when provided.
 * @returns {Function}
 */
export function setupAutoCalc(container, calcButton, inputs, validate) {
    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 () => {
        clearTimeout(debounceTimer);
        inputs.forEach(input => {
            if (input) {
                input.removeEventListener('input', triggerCalc);
                input.removeEventListener('change', triggerCalc);
            }
        });
    };
}

/**
 * Debounce helper with a cancel method.
 *
 * @param {Function} func
 * @param {number} wait
 * @returns {Function}
 */
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
 * @param {HTMLElement} button
 * @param {number} minDuration
 */
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);
        }
    }
}
