---
interface Props {
  heroMoreId: string;
  heroToggleId: string;
  sectionHeadSelector?: string;
  mobileBreakpoint?: number;
  autoCollapseDelta?: number;
}

const {
  heroMoreId,
  heroToggleId,
  sectionHeadSelector = ".glossary-portal-section__head",
  mobileBreakpoint = 860,
  autoCollapseDelta = 160,
} = Astro.props;
---

<script
  is:inline
  define:vars={{ heroMoreId, heroToggleId, sectionHeadSelector, mobileBreakpoint, autoCollapseDelta }}
>
  (() => {
    const boot = () => {
      const body = document.body;
      const root = document.documentElement;
      const hero = document.querySelector("[data-glossary-portal-hero]");
      const follow = document.getElementById("reading-follow");
      const heroMore = document.getElementById(heroMoreId);
      const heroToggle = document.getElementById(heroToggleId);

      if (!body || !root || !hero || !follow) return;

      const BODY_CLASS = "is-glossary-portal-page";
      const FOLLOW_ON_CLASS = "glossary-portal-follow-on";
      const EXPANDED_CLASS = "glossary-portal-hero-expanded";
      const mqMobile = window.matchMedia(`(max-width: ${mobileBreakpoint}px)`);

      let expandedAtY = null;
      let lastScrollY = window.scrollY || 0;
      let raf = 0;

      body.classList.add(BODY_CLASS);

      const heroHeight = () =>
        Math.max(0, Math.round(hero.getBoundingClientRect().height || 0));

      const stripLocalSticky = () => {
        document.querySelectorAll(sectionHeadSelector).forEach((el) => {
          el.classList.remove("is-sticky");
          el.removeAttribute("data-sticky-active");
        });
      };

      const computeFollowOn = () =>
        !mqMobile.matches &&
        follow.classList.contains("is-on") &&
        follow.style.display !== "none" &&
        follow.getAttribute("aria-hidden") !== "true";

      const applyLocalStickyHeight = () => {
        const h = mqMobile.matches ? 0 : heroHeight();

        if (typeof window.__archiSetLocalStickyHeight === "function") {
          window.__archiSetLocalStickyHeight(h);
        } else {
          root.style.setProperty("--glossary-local-sticky-h", `${h}px`);
        }
      };

      const syncFollowState = () => {
        const on = computeFollowOn();
        body.classList.toggle(FOLLOW_ON_CLASS, on);
        return on;
      };

      const collapseHero = () => {
        if (!body.classList.contains(EXPANDED_CLASS)) return;

        body.classList.remove(EXPANDED_CLASS);
        expandedAtY = null;

        if (heroMore) {
          heroMore.setAttribute("aria-hidden", "true");
        }

        if (heroToggle) {
          heroToggle.hidden = false;
          heroToggle.setAttribute("aria-expanded", "false");
        }

        try {
          window.__archiUpdateFollow?.();
        } catch {}

        schedule();
      };

      const expandHero = () => {
        body.classList.add(EXPANDED_CLASS);
        expandedAtY = window.scrollY || 0;

        if (heroMore) {
          heroMore.setAttribute("aria-hidden", "false");
        }

        if (heroToggle) {
          heroToggle.hidden = true;
          heroToggle.setAttribute("aria-expanded", "true");
        }

        try {
          window.__archiUpdateFollow?.();
        } catch {}

        schedule();
      };

      const syncHeroState = () => {
        const followOn = computeFollowOn();
        const expanded = body.classList.contains(EXPANDED_CLASS);
        const collapsed = followOn && !expanded;

        if (!followOn || mqMobile.matches) {
          body.classList.remove(EXPANDED_CLASS);
          expandedAtY = null;

          if (heroMore) {
            heroMore.setAttribute("aria-hidden", "false");
          }

          if (heroToggle) {
            heroToggle.hidden = true;
            heroToggle.setAttribute("aria-expanded", "false");
          }

          return;
        }

        if (heroMore) {
          heroMore.setAttribute("aria-hidden", collapsed ? "true" : "false");
        }

        if (heroToggle) {
          heroToggle.hidden = !collapsed;
          heroToggle.setAttribute("aria-expanded", expanded ? "true" : "false");
        }
      };

      const maybeAutoCollapseOnScroll = () => {
        if (mqMobile.matches) {
          lastScrollY = window.scrollY || 0;
          return;
        }

        if (!computeFollowOn()) {
          lastScrollY = window.scrollY || 0;
          return;
        }

        if (!body.classList.contains(EXPANDED_CLASS)) {
          lastScrollY = window.scrollY || 0;
          return;
        }

        if (expandedAtY == null) {
          lastScrollY = window.scrollY || 0;
          return;
        }

        const currentY = window.scrollY || 0;
        const scrollingDown = currentY > lastScrollY;
        const delta = currentY - expandedAtY;

        if (scrollingDown && delta >= autoCollapseDelta) {
          collapseHero();
        }

        lastScrollY = currentY;
      };

      const syncAll = () => {
        stripLocalSticky();
        syncFollowState();
        syncHeroState();
        applyLocalStickyHeight();
      };

      const schedule = () => {
        if (raf) return;
        raf = requestAnimationFrame(() => {
          raf = 0;
          requestAnimationFrame(syncAll);
        });
      };

      heroToggle?.addEventListener("click", expandHero);

      const onScroll = () => {
        maybeAutoCollapseOnScroll();
        schedule();
      };

      const followObserver = new MutationObserver(schedule);
      followObserver.observe(follow, {
        attributes: true,
        attributeFilter: ["class", "style", "aria-hidden"],
        subtree: false,
      });

      const heroResizeObserver =
        typeof ResizeObserver !== "undefined"
          ? new ResizeObserver(schedule)
          : null;

      heroResizeObserver?.observe(hero);

      window.addEventListener("scroll", onScroll, { passive: true });
      window.addEventListener("resize", schedule);
      window.addEventListener("pageshow", schedule);

      if (document.fonts?.ready) {
        document.fonts.ready.then(schedule).catch(() => {});
      }

      if (mqMobile.addEventListener) {
        mqMobile.addEventListener("change", schedule);
      } else if (mqMobile.addListener) {
        mqMobile.addListener(schedule);
      }

      schedule();
    };

    if (document.readyState === "loading") {
      document.addEventListener("DOMContentLoaded", boot, { once: true });
    } else {
      boot();
    }
  })();
</script>

<style>
  :global(body.is-glossary-portal-page #reading-follow){
    z-index: 10;
  }

  :global(body.is-glossary-portal-page.glossary-portal-follow-on .glossary-portal-hero){
    margin-bottom: 0;
    padding: 12px 16px 14px;
    row-gap: 10px;
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
  }

  :global(body.is-glossary-portal-page.glossary-portal-follow-on .glossary-portal-hero h1){
    font-size: clamp(1.9rem, 3.2vw, 2.55rem);
  }

  :global(body.is-glossary-portal-page.glossary-portal-follow-on .glossary-portal-hero__intro){
    max-width: var(--portal-hero-follow-intro-max-w, 68ch);
    font-size: .98rem;
    line-height: 1.48;
  }

  :global(body.is-glossary-portal-page.glossary-portal-follow-on:not(.glossary-portal-hero-expanded) .glossary-portal-hero__more){
    max-height: 0;
    opacity: 0;
    overflow: hidden;
    pointer-events: none;
  }

  :global(body.is-glossary-portal-page.glossary-portal-follow-on:not(.glossary-portal-hero-expanded) .glossary-portal-hero__toggle){
    display: inline-flex;
  }

  :global(body.is-glossary-portal-page.glossary-portal-follow-on #reading-follow .reading-follow__inner){
    border-top-left-radius: 0;
    border-top-right-radius: 0;
  }

  :global(body.is-glossary-portal-page .glossary-portal-section__head.is-sticky),
  :global(body.is-glossary-portal-page .glossary-portal-section__head[data-sticky-active="true"]){
    position: static !important;
    top: auto !important;
    z-index: auto !important;
    padding: 0 !important;
    border: 0 !important;
    background: transparent !important;
    box-shadow: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
</style>