(function () {
    'use strict';

    document.addEventListener('DOMContentLoaded', function () {
        var menuButton = document.getElementById('menu-toggle');
        var mainNav = document.getElementById('site-navigation');
        var menuWrapper = mainNav ? mainNav.querySelector('.menu-wrapper') : null;

        if (!menuButton || !mainNav) {
            return;
        }

        var navStrings = window.nxtEventPlannerNavigation || {};
        var toggleText = navStrings.toggle || 'Toggle submenu';
        var expandText = navStrings.expand || toggleText;
        var collapseText = navStrings.collapse || toggleText;
        var focusableSelector = 'a, button:not([disabled]), [tabindex]:not([tabindex="-1"])';

        var menuItemsWithChildren = Array.prototype.slice.call(mainNav.querySelectorAll('.menu-item-has-children'));

        function getFocusableElements() {
            if (!menuWrapper) {
                return [];
            }
            return Array.prototype.slice.call(menuWrapper.querySelectorAll(focusableSelector));
        }

        function closeMenu(shouldFocusToggle) {
            mainNav.classList.remove('toggled');
            menuButton.classList.remove('toggled');
            document.body.classList.remove('mobile-menu-open');
            menuButton.setAttribute('aria-expanded', 'false');

            if (shouldFocusToggle) {
                menuButton.focus();
            }
        }

        function setMenuOpen(opened) {
            mainNav.classList.toggle('toggled', opened);
            menuButton.classList.toggle('toggled', opened);
            document.body.classList.toggle('mobile-menu-open', opened);
            menuButton.setAttribute('aria-expanded', opened ? 'true' : 'false');
        }

        function getFocusTrapElements() {
            var elements = getFocusableElements();
            elements.push(menuButton);
            return elements.filter(function (el) {
                return el && el.offsetParent !== null;
            });
        }

        function setSubmenuState(item, toggle, expanded) {
            var submenu = item.querySelector(':scope > ul');
            var parentLink = item.querySelector(':scope > a');

            if (!submenu || !toggle) {
                return;
            }

            toggle.setAttribute('aria-expanded', expanded ? 'true' : 'false');
            item.classList.toggle('submenu-open', expanded);

            if (parentLink) {
                parentLink.setAttribute('aria-expanded', expanded ? 'true' : 'false');
            }

            var labelBase = toggle.dataset.linkLabel || '';
            var ariaLabel = labelBase
                ? labelBase + ' ' + (expanded ? collapseText : expandText)
                : (expanded ? collapseText : expandText);

            toggle.setAttribute('aria-label', ariaLabel);

            var srText = toggle.querySelector('.screen-reader-text');
            if (srText) {
                srText.textContent = expanded ? collapseText : expandText;
            }
        }

        function closeAllSubmenus() {
            menuItemsWithChildren.forEach(function (item) {
                var toggle = item.querySelector(':scope > .submenu-toggle');
                if (toggle) {
                    setSubmenuState(item, toggle, false);
                }
            });
        }

        function maybeFocusFirstMenuItem() {
            setTimeout(function () {
                var focusables = getFocusableElements();
                if (focusables.length > 0) {
                    focusables[0].focus();
                }
            }, 100);
        }

        function createSubmenuToggle(item, link, submenu) {
            var toggle = document.createElement('button');
            var linkText = link ? link.textContent.trim() : '';

            toggle.className = 'submenu-toggle';
            toggle.type = 'button';
            toggle.setAttribute('aria-expanded', 'false');
            toggle.setAttribute('tabindex', '0');
            toggle.dataset.linkLabel = linkText;
            toggle.innerHTML = '<span class="submenu-toggle-icon" aria-hidden="true"></span><span class="screen-reader-text"></span>';

            toggle.addEventListener('click', function (event) {
                event.preventDefault();

                var expanded = toggle.getAttribute('aria-expanded') === 'true';
                var nextExpanded = !expanded;

                setSubmenuState(item, toggle, nextExpanded);
                item.classList.toggle('submenu-close', !nextExpanded);

                if (!nextExpanded) {
                    return;
                }

                var siblings = item.parentElement
                    ? item.parentElement.querySelectorAll(':scope > .menu-item-has-children')
                    : [];

                Array.prototype.forEach.call(siblings, function (sibling) {
                    if (sibling === item) {
                        return;
                    }

                    var siblingToggle = sibling.querySelector(':scope > .submenu-toggle');
                    if (siblingToggle) {
                        setSubmenuState(sibling, siblingToggle, false);
                    }
                });

                var firstSubmenuLink = submenu.querySelector('a, button');
                if (firstSubmenuLink) {
                    firstSubmenuLink.focus();
                }
            });

            if (link) {
                link.after(toggle);
            } else {
                item.insertBefore(toggle, submenu);
            }

            setSubmenuState(item, toggle, false);
            return toggle;
        }

        function bindLinkKeyboardControls(item, link, submenu, toggle) {
            link.setAttribute('aria-haspopup', 'true');
            link.setAttribute('aria-expanded', 'false');

            link.addEventListener('keydown', function (event) {
                var expanded = toggle.getAttribute('aria-expanded') === 'true';
                var isSpace = event.key === ' ' || event.key === 'Spacebar';

                if (event.key === 'ArrowDown') {
                    event.preventDefault();
                    if (!expanded) {
                        setSubmenuState(item, toggle, true);
                    }

                    var firstLink = submenu.querySelector('a, button:not(.submenu-toggle), [tabindex]:not([tabindex="-1"])');
                    if (firstLink) {
                        firstLink.focus();
                    }
                    return;
                }

                if (isSpace) {
                    event.preventDefault();
                    setSubmenuState(item, toggle, !expanded);

                    if (!expanded) {
                        var firstFocusable = submenu.querySelector('a, button:not(.submenu-toggle), [tabindex]:not([tabindex="-1"])');
                        if (firstFocusable) {
                            firstFocusable.focus();
                        }
                    }
                    return;
                }

                if (event.key === 'ArrowUp') {
                    if (!expanded) {
                        return;
                    }

                    event.preventDefault();
                    var focusable = Array.prototype.slice.call(submenu.querySelectorAll('a, button:not(.submenu-toggle), [tabindex]:not([tabindex="-1"])'));
                    if (focusable.length > 0) {
                        focusable[focusable.length - 1].focus();
                    }
                    return;
                }

                if (event.key === 'Escape') {
                    event.preventDefault();
                    setSubmenuState(item, toggle, false);
                }
            });
        }

        function bindItemFocusHandlers(item, toggle) {
            item.addEventListener('focusin', function () {
                item.classList.add('focus');
            });

            item.addEventListener('focusout', function () {
                setTimeout(function () {
                    if (item.contains(document.activeElement)) {
                        return;
                    }

                    item.classList.remove('focus');
                    setSubmenuState(item, toggle, false);
                }, 10);
            });
        }

        menuButton.addEventListener('click', function () {
            var currentlyOpen = mainNav.classList.contains('toggled');

            setMenuOpen(!currentlyOpen);

            if (currentlyOpen) {
                closeAllSubmenus();
                menuButton.focus();
                return;
            }

            maybeFocusFirstMenuItem();
        });

        document.addEventListener('keydown', function (event) {
            if (!mainNav.classList.contains('toggled')) {
                return;
            }

            if (event.key === 'Tab') {
                var trapElements = getFocusTrapElements();
                if (!trapElements.length) {
                    return;
                }

                var currentIndex = trapElements.indexOf(document.activeElement);
                var lastIndex = trapElements.length - 1;
                event.preventDefault();

                if (event.shiftKey) {
                    if (currentIndex <= 0) {
                        trapElements[lastIndex].focus();
                    } else {
                        trapElements[currentIndex - 1].focus();
                    }
                    return;
                }

                if (currentIndex === -1 || currentIndex >= lastIndex) {
                    trapElements[0].focus();
                } else {
                    trapElements[currentIndex + 1].focus();
                }
                return;
            }

            if (event.key === 'Escape') {
                closeMenu(true);
            }
        });

        document.addEventListener('click', function (event) {
            if (mainNav.classList.contains('toggled') && !mainNav.contains(event.target) && !menuButton.contains(event.target)) {
                closeMenu(false);
            }
        });

        menuItemsWithChildren.forEach(function (item) {
            var link = item.querySelector(':scope > a');
            var submenu = item.querySelector(':scope > ul');

            if (!submenu) {
                return;
            }

            var toggle = item.querySelector(':scope > .submenu-toggle');
            if (!toggle) {
                toggle = createSubmenuToggle(item, link, submenu);
            } else {
                setSubmenuState(item, toggle, false);
            }

            if (link) {
                bindLinkKeyboardControls(item, link, submenu, toggle);
            }

            bindItemFocusHandlers(item, toggle);
        });

        document.addEventListener('click', function (event) {
            if (!mainNav.contains(event.target)) {
                closeAllSubmenus();
            }
        });

        document.addEventListener('keydown', function (event) {
            if (event.key === 'Escape' && mainNav.contains(document.activeElement)) {
                closeAllSubmenus();
            }
        });
    });
})();
