/**
 * RSL Smart Sections - Balanced Layout System
 *
 * Implements an intelligent masonry-style layout that distributes items across
 * columns for visual balance. Items are placed in the shortest column to create
 * a more harmonious layout, especially when items have varying heights.
 *
 * @fileoverview Balanced layout system with smart item distribution
 * @version 1.0.0
 * @license MIT
 *
 * Key Features:
 * - Masonry-style column distribution
 * - Respects same breakpoints as layout.js
 * - Supports both data-cols-* and data-slots-* attributes
 * - Auto-recalculates on resize
 * - Minimal DOM manipulation (rebuilds only when column count changes)
 *
 * Usage:
 * <div class="responsive-slot-layout" data-layout="balanced" data-slots-xs="1" data-slots-md="2">
 *   <div class="slot-item">Card 1</div>
 *   <div class="slot-item">Card 2</div>
 * </div>
 *
 * Public API:
 * - RSL.initBalancedSlots() - Manually trigger balanced layout recalculation
 */

(function() {
    'use strict';

    // Initialize RSL namespace
    window.RSL = window.RSL || {};
    var RSL = window.RSL;

    // Selector for balanced layouts (must have data-layout="balanced")
    var BALANCED_SELECTOR = '.responsive-slot-layout[data-layout="balanced"]';

    /**
     * Safely read an integer from a data attribute
     *
     * @param {HTMLElement} el - The element to read from
     * @param {string} attrName - The data attribute name (e.g., 'data-cols-md')
     * @returns {number|null} Parsed integer or null if not present/invalid
     *
     * @example
     * getIntAttr(element, 'data-cols-md') // returns 3 or null
     */
    function getIntAttr(el, attrName) {
        var val = el.getAttribute(attrName);
        if (val === null || val === '') return null;
        var parsed = parseInt(val, 10);
        return Number.isNaN(parsed) ? null : parsed;
    }

    /**
     * Returns the first non-null/non-undefined value from arguments
     * Used for cascading breakpoint inheritance
     *
     * @param {...*} arguments - Values to check
     * @returns {*} First defined value or null
     *
     * @example
     * firstDefined(null, undefined, 3, 4) // returns 3
     */
    function firstDefined() {
        for (var i = 0; i < arguments.length; i++) {
            var v = arguments[i];
            if (v !== null && v !== undefined) {
                return v;
            }
        }
        return null;
    }

    /**
     * Calculate column count based on container width and data attributes
     *
     * Uses the same breakpoint logic as layout.js for consistency.
     * Supports both data-cols-* and data-slots-* attributes (data-slots-* takes precedence).
     *
     * @param {HTMLElement} container - The balanced layout container
     * @param {number} itemCount - Number of items in the layout
     * @returns {number} Number of columns to use
     *
     * Breakpoints:
     * - XS: 0-576px (mobile)
     * - SM: 577-768px (large mobile/small tablet)
     * - MD: 769-992px (tablet)
     * - LG: 993-1200px (small desktop)
     * - XL: 1201-1600px (desktop)
     * - XXL: 1601px+ (large desktop)
     */
    function getColumnCount(container, itemCount) {
        var width = container.offsetWidth || (window.innerWidth || document.documentElement.clientWidth);

        // Read all possible breakpoint attributes once
        // data-slots-* takes precedence over data-cols-*
        var colsXs = firstDefined(
            getIntAttr(container, 'data-slots-xs'),
            getIntAttr(container, 'data-cols-xs')
        );
        var colsSm = firstDefined(
            getIntAttr(container, 'data-slots-sm'),
            getIntAttr(container, 'data-cols-sm')
        );
        var colsMd = firstDefined(
            getIntAttr(container, 'data-slots-md'),
            getIntAttr(container, 'data-cols-md')
        );
        var colsLg = firstDefined(
            getIntAttr(container, 'data-slots-lg'),
            getIntAttr(container, 'data-cols-lg')
        );
        var colsXl = firstDefined(
            getIntAttr(container, 'data-slots-xl'),
            getIntAttr(container, 'data-cols-xl')
        );
        var colsXxl = firstDefined(
            getIntAttr(container, 'data-slots-xxl'),
            getIntAttr(container, 'data-cols-xxl')
        );

        var columns = 1;

        // Determine column count based on viewport width
        // Each breakpoint cascades down through smaller breakpoints
        if (width > 1600) {
            // XXL: 1601px+ (large desktop)
            columns = firstDefined(
                colsXxl,
                colsXl,
                colsLg,
                colsMd,
                colsSm,
                colsXs,
                Math.min(12, itemCount)
            );
        } else if (width > 1200) {
            // XL: 1201-1600px (desktop)
            columns = firstDefined(
                colsXl,
                colsLg,
                colsMd,
                colsSm,
                colsXs,
                Math.min(6, itemCount)
            );
        } else if (width > 992) {
            // LG: 993-1200px (small desktop)
            columns = firstDefined(
                colsLg,
                colsMd,
                colsSm,
                colsXs,
                Math.min(4, itemCount)
            );
        } else if (width > 768) {
            // MD: 769-992px (tablet)
            columns = firstDefined(
                colsMd,
                colsSm,
                colsXs,
                Math.min(3, itemCount)
            );
        } else if (width > 576) {
            // SM: 577-768px (large mobile/small tablet)
            columns = firstDefined(
                colsSm,
                colsXs,
                Math.min(2, itemCount)
            );
        } else {
            // XS: 0-576px (mobile-first default)
            columns = colsXs !== null ? colsXs : 1;
        }

        // Ensure at least 1 column
        if (!columns || columns < 1) {
            columns = 1;
        }

        return columns;
    }

    /**
     * Rebuild a single balanced layout container using masonry algorithm
     *
     * Items are distributed across columns by always placing the next item
     * in the currently shortest column. This creates a balanced, visually
     * harmonious layout even when items have varying heights.
     *
     * Performance optimization: Only rebuilds when column count changes.
     *
     * @param {HTMLElement} container - The responsive-slot-layout container
     *
     * Algorithm:
     * 1. Create N column wrapper divs
     * 2. For each item, find the shortest column
     * 3. Append item to shortest column
     * 4. Update column height tracking
     */
    function rebuildBalanced(container) {
        // Cache original slot items on first run
        // This prevents losing items on subsequent rebuilds
        if (!container.__rslOriginalSlotItems) {
            container.__rslOriginalSlotItems = Array.from(
                container.querySelectorAll('.slot-item')
            );
        }

        var items = container.__rslOriginalSlotItems;
        if (!items || !items.length) return;

        var itemCount = items.length;
        var cols = getColumnCount(container, itemCount);
        if (cols < 1) cols = 1;

        // Performance optimization: Skip rebuild if column count unchanged
        if (container.__rslLastColumnCount === cols && container.__rslSmartInitialized) {
            return;
        }
        container.__rslLastColumnCount = cols;

        // Clear container and create column wrappers
        container.innerHTML = '';
        var columns = [];
        var heights = [];

        for (var i = 0; i < cols; i++) {
            var col = document.createElement('div');
            col.className = 'rsl-smart-column';
            container.appendChild(col);
            columns.push(col);
            heights.push(0);
        }

        // Masonry algorithm: Place each item in shortest column
        items.forEach(function(item) {
            var shortestIndex = 0;

            // Find shortest column
            for (var j = 1; j < cols; j++) {
                if (heights[j] < heights[shortestIndex]) {
                    shortestIndex = j;
                }
            }

            // Append item to shortest column
            columns[shortestIndex].appendChild(item);

            // Update height tracking (force layout read for accuracy)
            heights[shortestIndex] += item.offsetHeight || 0;
        });

        container.__rslSmartInitialized = true;
    }

    /**
     * Update all balanced layouts on the page
     *
     * Finds all elements matching the balanced layout selector
     * and rebuilds them using the masonry algorithm.
     */
    function updateAllBalancedLayouts() {
        var containers = document.querySelectorAll(BALANCED_SELECTOR);
        containers.forEach(rebuildBalanced);
    }

    /**
     * Debounce utility to limit function execution frequency
     *
     * @param {Function} fn - Function to debounce
     * @param {number} delay - Delay in milliseconds
     * @returns {Function} Debounced function
     *
     * @example
     * var debouncedResize = debounce(handleResize, 150);
     * window.addEventListener('resize', debouncedResize);
     */
    function debounce(fn, delay) {
        var timer;
        return function() {
            clearTimeout(timer);
            timer = setTimeout(fn, delay);
        };
    }

    /**
     * Public API: Manually trigger balanced layout recalculation
     *
     * Useful for:
     * - Dynamic content changes
     * - After adding/removing items
     * - Custom resize handling
     *
     * @public
     * @memberof RSL
     *
     * @example
     * // After dynamically adding items
     * container.appendChild(newItem);
     * RSL.initBalancedSlots();
     */
    RSL.initBalancedSlots = function() {
        updateAllBalancedLayouts();
    };

    /**
     * Auto-initialize balanced layouts on DOM ready
     * and set up resize listener with debouncing
     */
    document.addEventListener('DOMContentLoaded', function() {
        RSL.initBalancedSlots();
        window.addEventListener('resize', debounce(RSL.initBalancedSlots, 150));
    });

})();
