/**
 * Shared value comparison and display helpers.
 *
 * Extracted from components/settings.js so the logic can be unit-tested
 * (the settings.js IIFE is otherwise unreachable from tests).
 *
 * Exposes window.LdrValueHelpers. Consumers should destructure at the top
 * of their IIFE, e.g.
 *     const { areValuesEqual, formatPropertyName } = window.LdrValueHelpers;
 *
 * Note: embedding_settings.js intentionally retains its own local copies
 * of areValuesEqual and formatValueForDisplay because their semantics
 * differ visibly (different truncation lengths, array handling, and
 * equality rules). Unifying them would cause UX drift.
 */
(function() {
    'use strict';

    /**
     * Compare two values for equality, handling different types.
     * @param {any} value1
     * @param {any} value2
     * @returns {boolean}
     */
    function areValuesEqual(value1, value2) {
        // Handle null/undefined
        if (value1 === null && value2 === null) return true;
        if (value1 === undefined && value2 === undefined) return true;
        if (value1 === null && value2 === undefined) return true;
        if (value1 === undefined && value2 === null) return true;

        // If one is null/undefined but the other isn't
        if ((value1 === null || value1 === undefined) && (value2 !== null && value2 !== undefined)) return false;
        if ((value2 === null || value2 === undefined) && (value1 !== null && value1 !== undefined)) return false;

        // Handle different types
        const type1 = typeof value1;
        const type2 = typeof value2;

        // If types are different, they're not equal
        // Except for numbers and strings that might be equivalent
        if (type1 !== type2) {
            // Special case for numeric strings vs numbers
            if ((type1 === 'number' && type2 === 'string') || (type1 === 'string' && type2 === 'number')) {
                return String(value1) === String(value2);
            }
            return false;
        }

        // Handle objects (including arrays)
        if (type1 === 'object') {
            // Handle arrays
            if (Array.isArray(value1) && Array.isArray(value2)) {
                if (value1.length !== value2.length) return false;
                return JSON.stringify(value1) === JSON.stringify(value2);
            }

            // Handle objects
            return JSON.stringify(value1) === JSON.stringify(value2);
        }

        // Handle primitives
        return value1 === value2;
    }

    /**
     * Deep-compare two objects using areValuesEqual for each value.
     * @param {Object} obj1
     * @param {Object} obj2
     * @returns {boolean}
     */
    function areObjectsEqual(obj1, obj2) {
        const keys1 = Object.keys(obj1);
        const keys2 = Object.keys(obj2);

        if (keys1.length !== keys2.length) return false;

        for (const key of keys1) {
            if (!Object.hasOwn(obj2, key)) return false;
            if (!areValuesEqual(obj1[key], obj2[key])) return false;
        }

        return true;
    }

    /**
     * Convert a snake_case property name to Title Case.
     * @param {string} name
     * @returns {string}
     */
    function formatPropertyName(name) {
        return name.split('_')
            .map(word => word.charAt(0).toUpperCase() + word.slice(1))
            .join(' ');
    }

    /**
     * Format a value for display in settings notifications.
     * Strings are quoted, long strings are truncated, objects are elided.
     * @param {any} value
     * @returns {string}
     */
    function formatValueForDisplay(value) {
        if (value === null || value === undefined) {
            return 'empty';
        } else if (typeof value === 'boolean') {
            return value ? 'enabled' : 'disabled';
        } else if (typeof value === 'object') {
            // For objects, show a simplified representation
            return '{...}';
        } else if (typeof value === 'string' && value.length > 20) {
            // Truncate long strings
            return `"${value.substring(0, 18)}..."`;
        } else if (typeof value === 'string') {
            return `"${value}"`;
        }
        return String(value);
    }

    window.LdrValueHelpers = {
        areValuesEqual,
        areObjectsEqual,
        formatPropertyName,
        formatValueForDisplay,
    };
})();
