// ###############
// # CLAROMENTIS #
// #  ---------  #
// #   CONTINUE  #
// # > NEW GAME  #
// #  LOAD GAME  #
// #    OPTIONS  #
// #       QUIT  #
// #  ---------  #
// ###############

define(['jquery', './lib/requirejs/domReady.js'], function ($, domReady) {
    return function () {
        domReady(function () {

            var $body           = $('body');
            var $document       = $(document);
            var $window         = $(window);
            var windowWidth     = $window.width();
            var lastWindowWidth = $window.width();
            var currentPath = (window.location.pathname + window.location.search).replace(/\/$/, '');

            $.fn.orderChildren  = function (order) {
                this.each(function () {
                    var el = $(this);
                    for (var i = order.length; i >= 0; i--) {
                        el.prepend(el.children(order[i]));
                    }
                });
                return this;
            };

            // Rearranges the order of Navbar items when the menu switches to mobile view
            function arrangeNavItems(breakpoint) {
                if (breakpoint === 'mobile') {
                    $('#claroNav').orderChildren(['#head_searchbox', '.navbar-nav']);
                    $('.navbar-nav')
                        .orderChildren(['.nav-item-profile', '.nav-item-calendar', '.nav-item-company-links', '.nav-item-bookmarks', '.nav-item-applications', '.nav-item-whos-logged-in']);
                }

                if (breakpoint === 'desktop') {
                    $('#claroNav').orderChildren(['#head_searchbox', '.navbar-nav']);
                    $('.navbar-nav')
                        .orderChildren(['.nav-item-calendar', '.nav-item-company-links', '.nav-item-bookmarks', '.nav-item-applications', '.nav-item-notifications', '.nav-item-whos-logged-in', '.nav-item-profile']);
                }
            }

            // Initialise the navigation menu
            checkMenuUrl();

            // Adds title of previously clicked item to submenu title
            function mobiletitles() {
                $("li").removeClass("open-mobile");
                var menu = $('.js-claro-nav-items ul');
                $('a', menu).on('click', function () {
                    var menutitle  = $(this).text();
                    var menulink   = $(this).attr('href');
                    var menuappend = $(this).next('ul').children('li').first('.submenu-header').children('.submenu-header-link-wrap');

                    menuappend.html('<a class="submenu-header-link" href="' + menulink + '"' + '>' + menutitle + '</a>');

                });
                $('ul > li.has-sub > a').on('click', function (event) {
                    event.preventDefault();
                });
            }

            // Adds button to submenu items in side menu/desktop
            function addDesktopSubMenuButtons() {
                // TODO: These complicated selectors could do with simplification and cleaning up
                //       Additionally, these buttons are not only used for the side menu view, but for the horizontal menu also (body class is added by DesignTemplateSubscriber.php)
                //       Can we not keep the buttons in the DOM regardless of whether we're in desktop mode, and then hide them using CSS in mobile view?
                //       If they must stay in JS, then .js-claro-nav-items seems like a more appropriate selector, like much of the rest of the menu code
                if (!$('.desktop-sideview .header-menu-container li.has-sub button.desktop-toggle').length
                    && !$('.header-menu-container ul.main_menu__list ul li.has-sub button.desktop-toggle').length
                ) {
                    $(".desktop-sideview .header-menu-container li.has-sub, .header-menu-container ul.main_menu__list ul li.has-sub").prepend('<button class="desktop-toggle d-none d-md-block"></button>');
                }
            }

            // Opens sub menus
            function openSubMenuItems() {
                $(".js-claro-nav-items > ul > li a, .js-claro-nav-items > .main_menu__inner > ul > li a," +
                    " .js-claro-nav-items > ul > li button").on('click', function () {
                    $(this).parent("li").addClass("open-sub-menu");
                });
            }

            //Move the main menu's location depending on the screen breakpoint
            function moveMenu(breakpoint) {
                var claroNav = $('.js-claro-nav');
                var menu = $('.js-claro-menu-bar');
                var navContainerWrapper = $('.js-claro-nav-container-wrapper');

                if (breakpoint === 'desktop') {
                    navContainerWrapper.after(menu);
                }

                if (breakpoint === 'mobile') {
                    claroNav.append(menu);
                    menu.removeClass('d-none');
                }
            }

            // Add the .has-sub class to menu items with submenu items
            $('.js-claro-nav-items ul > li:has(ul)').addClass('has-sub');

            if (windowWidth <= 767) {
                mobiletitles();
                openSubMenuItems();
                arrangeNavItems('mobile');
                moveMenu('mobile');
            }

            if (windowWidth > 767) {
                addDesktopSubMenuButtons();
                arrangeNavItems('desktop');
            }


            //Expand sub menus when hovering over the expand/dropdown button
            $('.desktop-sideview .header-menu-container li.has-sub > button, .header-menu-container ul.main_menu__list ul li.has-sub > button').on('mouseover', _.debounce(function () {
                if (!$(this).parent('.has-sub').hasClass('open-sub-menu')) {
                    $(this).parent('.has-sub').addClass('open-sub-menu');
                } else {
                    $(this).parent('.has-sub').removeClass('open-sub-menu');
                }
            }, 250));

            // Adds top title li placeholder to sub menus
            $(".js-claro-nav-items ul ul").prepend($('<li class="submenu-header d-block d-md-none"><span class="submenu-header-back-button"></span><span class="submenu-header-link-wrap"></span></li>'));

            var lastWindowWidth = $window.width();

            $window.on('resize', function () {
                windowWidth = $window.width();
                if (lastWindowWidth !== windowWidth) {
                    if (windowWidth <= 767) {
                        mobiletitles();
                        openSubMenuItems();
                        arrangeNavItems('mobile');
                        moveMenu('mobile');
                    }

                    if (windowWidth > 767) {
                        addDesktopSubMenuButtons();
                        arrangeNavItems('desktop');
                        moveMenu('desktop');
                    }
                    lastWindowWidth = windowWidth;

                    //remove transition on window resize
                    $(".nav-toggle, .js-claro-nav-items").addClass('no-transition');
                }
            });

            //restore transition after window resize
            $window.on('resize', _.debounce(function () {
                $(".nav-toggle, .js-claro-nav-items").removeClass('no-transition');
            }, 1000));

            // Navbar navigation, notification and application menu buttons
            $(".nav-toggle, .mobile-notification .notification-toggle, .mobile-applications .application-toggle").on('click', function () {
                $("li").removeClass("open-sub-menu");
                $("html").toggleClass("no-scroll");
                $(".back-close").toggleClass("in");
            });


            //mobile nav event listeners
            $('.js-navbar-header').on('click','.js-mobile-nav-item',function() {
                var navItem = $(this).data('item');
                $('.js-mobile-nav-item').not($(this)).toggleClass("fade-out");

                switch (navItem) {
                    case "nav-toggle":
                        // Handle click on side menu / mobile menu toggle button
                        $(".js-nav-toggle, .js-claro-nav-items").toggleClass("in");
                        $(".head_nav").toggleClass("open");
                        break;
                    case "application-toggle":
                        // Handle click on the application menu toggle button
                        $(".js-nav-toggle, .js-claro-nav-items").removeClass("in");
                        $(".navbar-applications").toggleClass("show");
                        break;
                    case "notification-toggle":
                        // Handle click on the notifications toggle button
                        $(".js-nav-toggle, .js-claro-nav-items").removeClass("in");
                        $("#notifications").toggleClass("show");
                        break;
                }

            });

            // Compares current page url with link url
            function checkUrlPath(linkUrl, link) {
                if (currentPath === linkUrl) {
                    link.attr('aria-current', 'page');
                } else {
                    link.removeAttr('aria-current');
                }
            }

            // Checks menu items urls to include aria-current attribute
            function checkMenuUrl() {
                var menuLinks = $(".client-css-menu-item-link");

                menuLinks.each(function() {
                    var $link = $(this);
                    var linkUrl = new URL($link.attr('href'), window.location.origin);
                    var linkPath = (linkUrl.pathname + linkUrl.search).replace(/\/$/, '');

                    checkUrlPath(linkPath, $link);
                });
            }

            function mobileTitles() {
                if ($(window).width() <= 767) {
                    $("li").removeClass("open-mobile");

                    // Adds title of previously clicked item to submenu title
                    var menu = $('.claro-nav-items ul');

                    $('a', menu).on('click', function(){
                        var menutitle = $(this).text();
                        var menuUrl = new URL($(this).attr('href'), window.location.origin);
                        var menulink = (menuUrl.pathname + menuUrl.search).replace(/\/$/, '');
                        var menuappend = $(this).next('ul').children('li').first('.submenu-header').children('.submenu-header-link-wrap');

                        if (menulink[0] === '/') {
                            menuappend.html('<a class="submenu-header-link" href="' + menulink + '"' + '>'  + menutitle + '</a>');
                        } else {
                            menuappend.html('<span class="submenu-header-link">' + menutitle + '</span>');
                        }

                        var submenuLink = menuappend.find('.submenu-header-link');
                        checkUrlPath(menulink, submenuLink);
                    });

                    $('ul > li.has-sub > a').click(function (event) {
                        event.preventDefault();
                    });
                }
            }

            function desktopSidemenu() {
                if ($(window).width() >= 767) {
                    if (!$('button').hasClass('desktop-toggle')) {
                        $(".desktop-sideview .header-menu-container li.has-sub, .header-menu-container ul.main_menu__list ul li.has-sub").prepend('<button class="desktop-toggle d-none d-md-block"></button>');
                    }
                }
            }

            $('.desktop-sideview .header-menu-container li.has-sub > button, .header-menu-container ul.main_menu__list ul li.has-sub > button').on('click', function () {
                $(this).parent('.has-sub').toggleClass('open-mobile');
            });


            // Closes sub-menus individually
            $(".submenu-header-back-button").on('click', function () {
                $(this).parent('.submenu-header').parent("ul").parent("li").removeClass("open-sub-menu");
            });

            // Back fade out
            $(".back-close").on('click', function () {
                $(".nav-toggle, .js-claro-nav-items, .back-close, #notifications, .navbar-applications").removeClass("in");
                $("li").removeClass("open-sub-menu");
                $(".nav-toggle, .notification-toggle, .navbar-applications").removeClass("fade-out");
                $("html").removeClass("no-scroll");
                $(".head_nav").removeClass("open");
            });

            // Ensure the progressive menu is collapsed on page load
            $('#more').prop("checked", false);

            var suppressScrollCollapse = false;

            // Interchange more or less text on click
            $('.main_menu__link').on('click', function() {
                suppressScrollCollapse = true;

                setTimeout(function() {
                    suppressScrollCollapse = false;
                }, 300); // Slightly shorter than your scroll throttle

                if ( !$('#more').is(":checked") ) {
                    $(this).text(lmsg('main_menu.progressive_collapse.collapse')).addClass('after');
                    $('.js-menu-bar').addClass('menu-bar-expand');
                } else {
                    $(this).text(lmsg('main_menu.progressive_collapse.expand')).removeClass('after');
                    $('.js-menu-bar').removeClass('menu-bar-expand');
                }
            });

            // Dispatch an Event when the height of the navbar changes
            var navbar = document.querySelector('.navbar');

            if (navbar && typeof ResizeObserver !== 'undefined') {
                var lastHeight = navbar.offsetHeight;

                var observer = new ResizeObserver( function(entries) {
                    entries.forEach(function(entry)  {
                        var newHeight = entry.contentRect.height;
                        if (newHeight !== lastHeight) {
                            lastHeight = newHeight;

                            // Dispatch the custom event only when height changes
                            var event = new CustomEvent('navbarHeightChanged', {
                                detail: {
                                    newHeight: newHeight,
                                    hideHeader: $body.hasClass('hide-header'),
                                }
                            });
                            window.dispatchEvent(event);
                        }
                    });
                });

                observer.observe(navbar);
            }

            // Return the total width of all list items or all but the last one
            function checkMenuWidth(ignoreLast) {
                var totalMenuItemWidth = 0;

                $(".main_menu__list > li").each(function (index, value) {
                    //Ignore the last menu item when calculating width if ignore last is true
                    if (!(ignoreLast && index === $(".main_menu__list > li").length - 1)) {
                        totalMenuItemWidth += $(this).outerWidth()
                    }
                });

                return totalMenuItemWidth;
            }

            // Finds last item in main menu
            var lastMenuItem = $('.main_menu__list > li').last();

            // Allows for the 'more' button when calculating the difference between width of all list items and the wrapper
            var menuWrapperWidth = ($('.main_menu__inner').outerWidth() - 80);

            // Toggle the display of the progressive menu's 'more/less' depending on menu's width
            var progressiveMenuIsActive = false;

            function toggleProgressiveMenuButton(listItemsWidth){
                if (listItemsWidth < menuWrapperWidth) {
                    $('.main_menu__link').addClass('hide').removeClass('show');
                    progressiveMenuIsActive = false;
                } else {
                    $('.main_menu__link').addClass('show').removeClass('hide');
                    progressiveMenuIsActive = true;
                }
            }

            // Change the alignment of the last top level menu item's sub menu
            function alignLastItemSubmenu(itemsWidth) {
                if (itemsWidth + lastMenuItem.children('ul').width() > $(window).width() - 15 && progressiveMenuIsActive === false) {
                    lastMenuItem.children('ul').css('right', $(window).width() - $('.main_menu__list').width() - 16);
                } else {
                    lastMenuItem.children('ul').css('right', 'auto');
                }
            }

            toggleProgressiveMenuButton(checkMenuWidth(false));
            alignLastItemSubmenu(checkMenuWidth(true));

            // Animated menu - Show/hide menu when scrolling the page
            // Throttled to run every 250ms at most
            var lastScrollTop = 0,
                delta = 50,
                navbarHeight = $('.claro-navbar').outerHeight();

            $window.on('scroll', _.throttle(function() {
                if (suppressScrollCollapse) {
                    return;
                }


                if (lastWindowWidth <= 767) {
                    $body.removeClass('hide-header');
                    return;
                }

                var st = $(this).scrollTop();

                // Make sure they scroll more than delta
                if (Math.abs(lastScrollTop - st) <= delta) {
                    return;
                }

                // Collapse progressive menu
                $('.head_nav .toggle').prop("checked", false);
                $('.main_menu__link').text("More").removeClass('after');

                if (st > lastScrollTop && st > navbarHeight) {
                    // Scrolling down
                    if (!$('#menu-bar').hasClass('hide-header') && !$body.hasClass('desktop-sideview')) {
                        $body.removeClass('show-header').addClass('hide-header');
                    }
                } else {
                    // Scrolling up
                    if (st + $window.height() < $document.height()) {
                        if (!$('#menu-bar').hasClass('show-header')) {
                            $body.removeClass('hide-header').addClass('show-header');
                        }
                    }
                }

                var event = new CustomEvent('navbarHeightChanged', {
                    detail: {
                        hideHeader: $body.hasClass('hide-header'),
                    }
                })
                window.dispatchEvent(event)

                lastScrollTop = st;
            }, 200));

            // show hidden menu header when the page is not scrollable
            var observer = new MutationObserver(function(mutations) {
                mutations.forEach(function(mutation) {
                    if (mutation.type === 'childList') {
                        var body = document.body;

                        if (body.classList.contains('hide-header') && !isPageScrollable()) {
                            body.classList.remove('hide-header');
                            body.classList.add('show-header');
                        }
                    }
                });
            });

            // start observing the page change
            observer.observe(document.body, {childList: true, subtree: true});

            // stop observing to clean up resources
            window.addEventListener('beforeunload', function (event) {
                observer.disconnect();
            });

            function isPageScrollable() {
                var pageHeight = document.documentElement.scrollHeight;
                var viewportHeight = window.innerHeight;

                return pageHeight > viewportHeight;
            }

            var mainMenuExists = !!document.querySelector('.header-menu-container');

            if (!mainMenuExists) {
                document.querySelector("body").classList.add("no-main-menu");
            }

            // Navbar tooltips
            var tooltipTimeout; // Store the timeout for showing the last active tooltip
            var activeTooltip = null; // Store the last active tooltip

            $('.navbar-nav .nav-item .nav-link').on('shown.bs.tooltip', function () {
                activeTooltip = $(this); // Store the tooltip that was last shown
            });

            $(window).on('scroll', _.throttle(function() {
                if (activeTooltip)
                    activeTooltip.tooltip('hide'); // Hide the last active tooltip

                // Clear any existing timeout
                clearTimeout(tooltipTimeout);

                // Re-show the last active tooltip after scrolling stops
                tooltipTimeout = setTimeout(function() {
                    if (activeTooltip && (activeTooltip.is(':hover') || activeTooltip.is(':focus'))) {
                        // Fully remove and reinitialize the tooltip before showing
                        activeTooltip.tooltip('dispose').tooltip().tooltip('show');
                    }
                }, 300); // Adjust delay as needed
            }, 250));

            $('.navbar-nav .nav-item').on('show.bs.dropdown', function () {
                $('.tooltip').tooltip('hide');
            });
            //End of Navbar tooltips


            // Only run in non-Chrome browsers
            var ua = navigator.userAgent.toLowerCase();
            if ((ua.indexOf('chrome') === -1 || ua.indexOf('edg') !== -1 || ua.indexOf('opr') !== -1) && !$body.hasClass('desktop-sideview')) {
                var menuItems = document.querySelectorAll('.menu-bar .main_menu__list > li.has-sub');
                var activeTrigger = null;
                var activeSubmenu = null;

                function getSubmenu(trigger) {
                    return trigger.querySelector('a + ul');
                }

                function positionSubmenu(trigger, submenu) {
                    var rect = trigger.getBoundingClientRect();
                    submenu.style.top = (rect.top + rect.height) + 'px';
                    submenu.style.visibility = 'visible';
                }

                function updatePosition() {
                    if (activeTrigger && activeSubmenu) {
                        positionSubmenu(activeTrigger, activeSubmenu);
                    }
                }

                function showSubmenu(trigger) {
                    var submenu = getSubmenu(trigger);
                    if (!submenu) return;

                    activeTrigger = trigger;
                    activeSubmenu = submenu;

                    positionSubmenu(trigger, submenu);
                    window.addEventListener('scroll', updatePosition, true);
                }

                function hideSubmenu(trigger) {
                    var submenu = getSubmenu(trigger);
                    if (!submenu) return;

                    submenu.style.visibility = 'hidden';
                    activeTrigger = null;
                    activeSubmenu = null;

                    window.removeEventListener('scroll', updatePosition, true);
                }

                for (var i = 0; i < menuItems.length; i++) {
                    (function (item) {
                        item.addEventListener('mouseenter', function () {
                            showSubmenu(item);
                        });
                        item.addEventListener('mouseleave', function () {
                            hideSubmenu(item);
                        });
                    })(menuItems[i]);
                }
            }
        });
    };
});
