// ZB.MOM.WW.Theme nav-state.js — persists <details data-nav-key> open/closed
// state in localStorage so NavRailSection expand state survives navigation and
// reloads. Pure client-side; works with static Blazor SSR. Keyed per section.
// localStorage keys are prefixed with "zbnav:" to avoid collisions.
(function () {
    var PREFIX = "zbnav:";
    var INIT_ATTR = "data-zbnav-initialized";
    var TRANSIENT_ATTR = "data-zbnav-transient";

    // Mirror a section's native <details open> onto its <summary aria-expanded>
    // so tests and assistive tech have a stable, queryable attribute (issue #1).
    function syncAria(el) {
        var summary = el.querySelector("summary.rail-eyebrow-toggle");
        if (summary) summary.setAttribute("aria-expanded", el.open ? "true" : "false");
    }

    function wire(el) {
        el.setAttribute(INIT_ATTR, "");
        var key = PREFIX + el.getAttribute("data-nav-key");
        var saved = null;
        try { saved = window.localStorage.getItem(key); } catch (e) { saved = null; }
        if (saved === "1") el.open = true;
        else if (saved === "0") el.open = false;
        el.addEventListener("toggle", function () {
            syncAria(el);
            // An active-link reveal (issue #2) is a transient open that must NOT
            // overwrite the user's saved preference. The reveal flags the element
            // before flipping open; consume the flag here and skip persistence.
            if (el.getAttribute(TRANSIENT_ATTR) !== null) {
                el.removeAttribute(TRANSIENT_ATTR);
                return;
            }
            try { window.localStorage.setItem(key, el.open ? "1" : "0"); } catch (e) { /* ignore */ }
        });
    }

    function apply() {
        document.querySelectorAll("details.rail-section[data-nav-key]").forEach(function (el) {
            if (!el.hasAttribute(INIT_ATTR)) wire(el); // wire once — avoid duplicate listeners
            syncAria(el);                               // re-sync aria on every pass
        });

        // Reveal the section that holds the active link even if the user (or the
        // app) left it collapsed, so the nav always shows where the user is
        // (issue #2). Transient: flagged so the toggle handler does not persist it.
        document.querySelectorAll("details.rail-section a.rail-link.active").forEach(function (link) {
            var sec = link.closest("details.rail-section");
            if (sec && !sec.open) {
                sec.setAttribute(TRANSIENT_ATTR, "");
                sec.open = true;
                syncAria(sec);
            }
        });
    }

    if (document.readyState === "loading")
        document.addEventListener("DOMContentLoaded", apply);
    else
        apply();

    // Re-run after Blazor static-SSR enhanced navigation (or any re-render that
    // replaces the rail nodes) so freshly inserted sections are wired, restored,
    // and active-revealed (issue #3). The per-element INIT_ATTR guard keeps this
    // idempotent for nodes that survived the navigation.
    if (window.Blazor && typeof window.Blazor.addEventListener === "function") {
        window.Blazor.addEventListener("enhancedload", apply);
    }

    // Re-run whenever rail sections are (re)inserted into the DOM. Under an
    // interactive render mode (Blazor InteractiveServer/WebAssembly/Auto) the
    // prerendered <details> wired on DOMContentLoaded are replaced when the
    // runtime adopts the page, and `enhancedload` does NOT fire — so without this
    // the live sections are never wired (no persistence, no aria sync, no
    // active-reveal). A MutationObserver is the render-mode-agnostic backstop;
    // the per-element INIT_ATTR guard keeps re-applies idempotent, and the
    // childList-only filter (plus the active-reveal's `if (!sec.open)` guard)
    // avoids any observe→mutate→observe loop (issue #6).
    if (typeof MutationObserver === "function") {
        var observer = new MutationObserver(function (mutations) {
            for (var i = 0; i < mutations.length; i++) {
                var added = mutations[i].addedNodes;
                for (var j = 0; j < added.length; j++) {
                    var node = added[j];
                    if (node.nodeType !== 1) continue;
                    if ((node.matches && node.matches("details.rail-section")) ||
                        (node.querySelector && node.querySelector("details.rail-section"))) {
                        apply();
                        return;
                    }
                }
            }
        });
        observer.observe(document.documentElement, { childList: true, subtree: true });
    }
})();
