/*
 * Site menu progressive enhancement.
 *
 * The menu is fully server-rendered (see modules/SiteMenu). This script only
 * layers on interactivity:
 *   - Desktop: regular dropdowns open on hover (CSS). Mega menus open on click.
 *   - Mobile (<= breakpoint): every parent item becomes a tap-to-open accordion.
 * There is no framework dependency; the markup works without JS.
 */

const MENU_BREAKPOINT = 1120;
const PARENT_TRIGGER = '.siteMenu__item--has-children > .siteMenu__link';

function isMobileMenu() {
    return window.matchMedia('(max-width: ' + MENU_BREAKPOINT + 'px)').matches;
}

/*
 * Mobile accordion. Selector is the trigger; its next sibling (the dropdown or
 * mega panel) is shown/hidden. Kept as an exported, reusable helper.
 */
export function showHideMenus(selector, breakpoint) {
    'use strict';
    // Also make it available globally for backward compatibility
    window.showHideMenus = showHideMenus;

    const $selector = $(selector);

    $selector.each(function () {

        const trigger = $(this);
        let section = trigger.next();

        if (typeof (trigger.data('target')) !== 'undefined') {
            section = $(trigger.data('target'));
        }

        if (section.length > 0 && !trigger.hasClass('directLink')) {
            // mobile: show / hide behaviour
            if (matchesMediaQuery(0, breakpoint) && !trigger.hasClass('isClickable')) {

                // initialise show / hide state
                section.hide();
                trigger.addClass('isClickable').attr('aria-expanded', 'false');
                // bind click
                trigger.on('click', function (e) {

                    let this_section = $(this).next();
                    const this_trigger = $(this);

                    e.preventDefault();

                    if (typeof (this_trigger.data('target')) !== 'undefined') {
                        this_section = $(this_trigger.data('target'));
                    }

                    this_section.toggleClass('open').stop(true, true).slideFadeToggle();
                    this_trigger.toggleClass('open');
                    this_trigger.attr('aria-expanded', this_trigger.hasClass('open') ? 'true' : 'false');
                });

            } else if (matchesMediaQuery(Number(breakpoint + 1)) && trigger.hasClass('isClickable')) {
                trigger.removeClass('isClickable');
                // disable click and remove classes
                trigger.removeClass('open').off('click').attr('aria-expanded', 'false');
                section.removeClass('open').css({
                    display: ''
                });
            }
        }

    });
}

/*
 * Desktop mega-menu: click the top-level link to toggle the panel; close on
 * mouse leave or when another mega opens. On mobile the accordion above handles
 * these items instead, so this early-returns.
 */
function initMegaMenus() {
    'use strict';

    const VISIBLE = 'siteMenu__mega--visible';

    function closeAll($except) {
        $('.siteMenu__mega.' + VISIBLE).each(function () {
            const $panel = $(this);
            if ($except && $panel.is($except)) {
                return;
            }
            $panel.removeClass(VISIBLE);
            $panel.siblings('.siteMenu__link').attr('aria-expanded', 'false');
        });
    }

    $('.siteMenu__item--mega').each(function () {
        const $item = $(this);
        const $link = $item.children('.siteMenu__link');
        const $panel = $item.children('.siteMenu__mega');

        if (!$panel.length) {
            return;
        }

        $link.off('click.smMega').on('click.smMega', function (e) {
            if (isMobileMenu()) {
                return; // mobile accordion handles this
            }
            e.preventDefault();
            const isOpen = $panel.hasClass(VISIBLE);
            closeAll();
            if (!isOpen) {
                $panel.addClass(VISIBLE);
                $link.attr('aria-expanded', 'true');
            }
        });

        $item.off('mouseleave.smMega').on('mouseleave.smMega', function () {
            if (isMobileMenu()) {
                return;
            }
            $panel.removeClass(VISIBLE);
            $link.attr('aria-expanded', 'false');
        });
    });

    // Close open mega panels on Escape or outside click.
    $(document).off('keyup.smMega').on('keyup.smMega', function (e) {
        if (e.key === 'Escape') {
            closeAll();
        }
    });
    $(document).off('click.smMegaOutside').on('click.smMegaOutside', function (e) {
        if (!$(e.target).closest('.siteMenu__item--mega').length) {
            closeAll();
        }
    });
}

/*
 * Desktop hover dropdowns are CSS-driven; keep aria-expanded in sync for a11y.
 */
function initHoverAria() {
    'use strict';
    $('.siteMenu__item--has-children').not('.siteMenu__item--mega').each(function () {
        const $item = $(this);
        const $link = $item.children('.siteMenu__link');

        $item.off('mouseenter.smAria mouseleave.smAria')
            .on('mouseenter.smAria', function () {
                if (!isMobileMenu()) {
                    $link.attr('aria-expanded', 'true');
                }
            })
            .on('mouseleave.smAria', function () {
                if (!isMobileMenu()) {
                    $link.attr('aria-expanded', 'false');
                }
            });
    });
}

function initSiteMenu() {
    if ($('.siteMenu__list').length) {
        showHideMenus(PARENT_TRIGGER, MENU_BREAKPOINT);
        initMegaMenus();
        initHoverAria();
    }
}

$(document).ready(function () {
    initSiteMenu();
});

$(window).on('resize', debouncer(function () {
    initSiteMenu();
})); // debounce
