/**
 * Eronex Sliding Menu
 * Create a sliding menu functionality with nested panels and responsive behavior.
 */
(function ($) {
    var usedIds = [];

    $.fn.eronexSlideMenu = function (options) {
        // Default configuration
        var settings = $.extend({
            dropdownSelector: '', // Selector for dropdown trigger elements
            backMenuText: '' // Text for the "Back" button in submenus
        }, options);

        return this.each(function () {
            var menu = $(this);
            var menuWidth = menu.width();
            var wrapper, rootPanel, currentPanel;
            var panelsData;

            if (menu.hasClass('eronex-sliding-menu')) {
                return; // Avoid re-initializing the menu
            }

            // Process menu items and retrieve panel data
            panelsData = buildMenuPanels(menu, settings);

            // Initialize the menu structure
            menu.empty().addClass('eronex-sliding-menu');
            $(panelsData).each(function (index, panel) {
                if ($(panel).hasClass('eronex-menu-panel-root')) {
                    rootPanel = '#' + $(panel).attr('id');
                }
                $(panel).width(menuWidth);
                menu.append(panel);
            });

            rootPanel = $(rootPanel).addClass('eronex-menu-panel-root');
            currentPanel = rootPanel;
            menu.height(rootPanel.height());

            // Wrap menu panels in a sliding wrapper
            wrapper = $('<div></div>')
                .addClass('eronex-sliding-menu-wrapper')
                .width(panelsData.length * menuWidth);
            menu.wrapInner(wrapper);

            wrapper = $('.eronex-sliding-menu-wrapper', menu);

            updatePanelAccess(currentPanel);

            // Handle dropdown and back navigation clicks
            menu.on('click', '[data-slide-panel]', function (e) {
                e.preventDefault();
                var trigger = $(this);
                var targetId = trigger.data('slide-panel');
                var isBackAction = trigger.hasClass('eronex-slide-menu-back');
                var isRTL = $('body').hasClass('rtl');
                var marginProp = isRTL ? 'marginRight' : 'marginLeft';
                var marginCss = isRTL ? 'margin-right' : 'margin-left';
                var currentMargin = parseInt(wrapper.css(marginCss), 10);
                var animProps = {};

                if (isNaN(currentMargin)) {
                    currentMargin = 0;
                }

                var targetPanel = isBackAction
                    ? currentPanel.prev()
                    : $(targetId);

                if (isBackAction) {
                    animProps[marginProp] = currentMargin + menuWidth;
                    wrapper.animate(animProps, 'fast');
                    menu.find('[aria-expanded="true"]').last().attr('aria-expanded', 'false');
                } else {
                    targetPanel.insertAfter(currentPanel);
                    animProps[marginProp] = currentMargin - menuWidth;
                    wrapper.animate(animProps, 'fast');
                    trigger.attr('aria-expanded', 'true');
                }

                currentPanel = targetPanel;
                updatePanelAccess(currentPanel);
                menu.animate({ height: currentPanel.height() }, 'fast', function () {
                    var focusTarget = currentPanel.find('a[href], button:not([disabled])').first();
                    if (focusTarget.length) {
                        focusTarget.trigger('focus');
                    }
                });
            });

            /**
             * Keep only the visible panel in the keyboard tab order.
             * @param {jQuery} panel
             */
            function updatePanelAccess(panel) {
                if (!panel || !panel.length) {
                    return;
                }

                menu.find('ul').each(function () {
                    var isCurrent = this === panel[0];
                    this.inert = !isCurrent;
                    this.setAttribute('aria-hidden', isCurrent ? 'false' : 'true');

                    $(this).find('a[href], button:not([disabled])').each(function () {
                        if (!isCurrent) {
                            if (!this.hasAttribute('data-eronex-tabindex')) {
                                this.setAttribute('data-eronex-tabindex', this.hasAttribute('tabindex') ? this.getAttribute('tabindex') : '');
                            }
                            this.setAttribute('tabindex', '-1');
                        } else if (this.hasAttribute('data-eronex-tabindex')) {
                            var prev = this.getAttribute('data-eronex-tabindex');
                            this.removeAttribute('data-eronex-tabindex');
                            if (prev === '') {
                                this.removeAttribute('tabindex');
                            } else {
                                this.setAttribute('tabindex', prev);
                            }
                        } else {
                            this.removeAttribute('tabindex');
                        }
                    });
                });
            }

            // Adjust the menu on window resize
            $(window).on('resize', function () {
                var newMenuWidth = menu.width();
                if (newMenuWidth !== menuWidth) {
                    menuWidth = newMenuWidth;

                    wrapper.width(panelsData.length * menuWidth);
                    menu.find('.eronex-menu-panel').width(menuWidth);
                    menu.height(rootPanel.height());
                }
            });
        });

        /**
         * Builds the menu panels by processing the structure and adding necessary attributes.
         * @param {jQuery} menu - The menu element.
         * @param {Object} settings - Plugin settings.
         * @returns {Array} - Array of panel elements.
         */
        function buildMenuPanels(menu, settings) {
            var ulElements = menu.find('ul');
            var panels = [];

            ulElements.each(function (index, ul) {
                var panel = $(ul);
                var handler = panel.prev();

                if (settings.dropdownSelector) {
                    handler = handler.find(settings.dropdownSelector);
                }

                var uniqueId = generateUniqueId();
                handler.attr('data-slide-panel', `#eronex-menu-panel-${uniqueId}`);
                panel.attr('id', `eronex-menu-panel-${uniqueId}`);

                if (index === 0) {
                    panel.addClass('eronex-menu-panel-root');
                } else {
                    panel.addClass('eronex-menu-panel');
                    var backLabel = settings.backMenuText || 'Back';
                    var backButton = $(
                        `<li class="menu-item-back">
                            <button type="button" class="eronex-slide-menu-back" data-slide-panel="#eronex-menu-panel-back" aria-label="${backLabel}">${settings.backMenuText}</button>
                         </li>`
                    );
                    panel.prepend(backButton);
                }

                panels.push(panel[0]);
            });

            return panels;
        }

        /**
         * Generates a unique ID for menu panels.
         * @returns {string} - A unique ID.
         */
        function generateUniqueId() {
            var id;
            do {
                id = Math.random().toString(36).substring(3, 8);
            } while (usedIds.includes(id));

            usedIds.push(id);
            return id;
        }
    };
})(jQuery);