/**
 * @file
 * This script watches the desktop version of the primary navigation. If it
 * wraps to two lines, it will automatically transition to a mobile navigation
 * and remember where it wrapped so it can transition back.
 */
((Drupal, once) => {
  /**
   * Handles the transition from mobile navigation to desktop navigation.
   *
   * @param {Element} navWrapper - The primary navigation's top-level <ul> element.
   * @param {Element} navItem - The first item within the primary navigation.
   */
  function transitionToDesktopNavigation(navWrapper, navItem) {
    document.body.classList.remove('is-always-mobile-nav');

    // Double check to see if the navigation is wrapping, and if so, re-enable
    // mobile navigation. This solves an edge cases where if the amount of
    // navigation items always causes the primary navigation to wrap, and the
    // page is loaded at a narrower viewport and then widened, the mobile nav
    // may not be enabled.
    if (navWrapper.clientHeight > navItem.clientHeight) {
      document.body.classList.add('is-always-mobile-nav');
    }
  }

  /**
   * Callback from Resize Observer. This checks if the primary navigation is
   * wrapping, and if so, transitions to the mobile navigation.
   *
   * @param {ResizeObserverEntry} entries - Object passed from ResizeObserver.
   */
  function checkIfDesktopNavigationWraps(entries) {
    const navItem = document.querySelector('.primary-nav__menu-item');

    if (
      Drupal.olivero.isDesktopNav() &&
      entries[0].contentRect.height > navItem.clientHeight
    ) {
      const navMediaQuery = window.matchMedia(
        `(max-width: ${window.innerWidth + 15}px)`, // 5px adds a small buffer before switching back.
      );
      document.body.classList.add('is-always-mobile-nav');

      // In the event that the viewport was resized, we remember the viewport
      // width with a one-time event listener ,so we can attempt to transition
      // from mobile navigation to desktop navigation.
      navMediaQuery.addEventListener(
        'change',
        () => {
          transitionToDesktopNavigation(entries[0].target, navItem);
        },
        { once: true },
      );
    }
  }

  /**
   * Set up Resize Observer to listen for changes to the size of the primary
   * navigation.
   *
   * @param {Element} primaryNav - The primary navigation's top-level <ul> element.
   */
  function init(primaryNav) {
    const resizeObserver = new ResizeObserver(checkIfDesktopNavigationWraps);
    resizeObserver.observe(primaryNav);
  }

  /**
   * Initialize the automatic navigation transition.
   *
   * @type {Drupal~behavior}
   *
   * @prop {Drupal~behaviorAttach} attach
   *   Attach context and settings for navigation.
   */
  Drupal.behaviors.automaticMobileNav = {
    attach(context) {
      once(
        'olivero-automatic-mobile-nav',
        '[data-drupal-selector="primary-nav-menu--level-1"]',
        context,
      ).forEach(init);
    },
  };
})(Drupal, once);
