/**
 * AIEO admin in-page TOC — smooth-scroll + scroll-spy.
 *
 * Used by the Analytics + AI Chat admin pages (the DMM page uses the
 * same CSS but its pills are page-level links — no anchor behavior).
 *
 * Two behaviors:
 *   1) Click on a `.aieo-dmm-subtab[href^="#"]` inside a
 *      `[data-aieo-toc-bar]` → smooth-scroll to the target heading,
 *      offset by the WP admin bar height so the heading isn't hidden
 *      behind it.
 *   2) Scroll position → IntersectionObserver tracks which target
 *      section is currently in the upper viewport band, flips
 *      `is-active` on the matching pill. Falls back to no scroll-spy
 *      on browsers without IO (graceful — clicks still work).
 *
 * Single file, no jQuery, ~80 LOC. Idempotent on multiple loads —
 * keyed off `__aieoPageTocBound` flag on each bar.
 */
(function () {
    'use strict';

    function getAdminBarOffset() {
        var bar = document.getElementById('wpadminbar');
        return bar ? bar.getBoundingClientRect().height : 0;
    }

    function bindBar(bar) {
        if (bar.__aieoPageTocBound) { return; }
        bar.__aieoPageTocBound = true;

        var pills = Array.prototype.slice.call(bar.querySelectorAll('a.aieo-dmm-subtab[href^="#"]'));
        if (!pills.length) { return; }

        // Build map id → pill for quick lookup during scroll spy.
        var pillById = {};
        var targets  = [];
        pills.forEach(function (pill) {
            var href = pill.getAttribute('href') || '';
            if (href.length < 2 || href.charAt(0) !== '#') { return; }
            var id   = href.slice(1);
            var node = document.getElementById(id);
            if (!node) { return; }
            pillById[id] = pill;
            targets.push(node);

            pill.addEventListener('click', function (e) {
                e.preventDefault();
                var offset = getAdminBarOffset() + 16;
                var top    = node.getBoundingClientRect().top + window.pageYOffset - offset;
                window.scrollTo({ top: top, behavior: 'smooth' });
                // Update URL hash without triggering an extra jump.
                if (history && history.replaceState) {
                    history.replaceState(null, '', href);
                }
                setActive(pill);
            });
        });

        function setActive(pill) {
            pills.forEach(function (p) { p.classList.remove('is-active'); });
            if (pill) { pill.classList.add('is-active'); }
        }

        // Scroll-spy via IntersectionObserver. rootMargin shrinks the
        // observer's viewport so a section counts as "active" only when
        // its heading is within the top ~30% of the screen — matches
        // user mental model better than "anywhere visible".
        if (!('IntersectionObserver' in window) || !targets.length) { return; }

        var spy = new IntersectionObserver(function (entries) {
            // Prefer the topmost intersecting entry (in document order).
            var topMost = null;
            entries.forEach(function (entry) {
                if (!entry.isIntersecting) { return; }
                if (!topMost || entry.boundingClientRect.top < topMost.boundingClientRect.top) {
                    topMost = entry;
                }
            });
            if (topMost && topMost.target && topMost.target.id) {
                var pill = pillById[topMost.target.id];
                if (pill) { setActive(pill); }
            }
        }, {
            // Top of section enters when it's ~80px below the admin bar;
            // bottom band excludes the lower 60% so only what's near the
            // top counts as "current."
            rootMargin: '-80px 0px -60% 0px',
            threshold:  0
        });
        targets.forEach(function (t) { spy.observe(t); });

        // Honor an initial #hash on page load — scroll into position +
        // mark the pill active. Default browser anchor-jump leaves the
        // heading hidden behind the WP admin bar, so we re-do it with
        // the correct offset.
        if (window.location.hash && window.location.hash.length > 1) {
            var initId   = window.location.hash.slice(1);
            var initNode = document.getElementById(initId);
            var initPill = pillById[initId];
            if (initNode && initPill) {
                // Defer one tick so layout has settled.
                setTimeout(function () {
                    var offset = getAdminBarOffset() + 16;
                    var top    = initNode.getBoundingClientRect().top + window.pageYOffset - offset;
                    window.scrollTo({ top: top, behavior: 'auto' });
                    setActive(initPill);
                }, 0);
            }
        }
    }

    function init() {
        var bars = document.querySelectorAll('[data-aieo-toc-bar]');
        Array.prototype.forEach.call(bars, bindBar);
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();
