// shared/profile-menu.js — account menu in the header's upper-right.
//
// Replaces the old floating elevation toggle. Admin mode is now one item in
// this dropdown, alongside the signed-in email, Profile, and Access tokens.
// Mounts into the tool header's `.header-right` cluster (every tool ships one)
// and drives elevation via window.zddc.elevation, so the cookie / armed-chrome
// / ephemeral state machine stays in shared/elevation.js.
//
// No logout: authentication is the upstream proxy's concern (oauth2-proxy /
// Authelia) — ZDDC owns no session, so it doesn't touch sign-out.
//
// Server mode only: it reads /.profile/access for the email + can_elevate.
// On file:// (offline FS-Access mode) there's no server account, so nothing
// renders.
(function () {
    'use strict';

    if (!window.zddc) window.zddc = {};
    if (window.zddc.profileMenu) return;

    function el(tag, cls, text) {
        var e = document.createElement(tag);
        if (cls) e.className = cls;
        if (text != null) e.textContent = text;
        return e;
    }

    async function fetchAccess() {
        try {
            var r = await fetch('/.profile/access', {
                headers: { Accept: 'application/json' },
                credentials: 'same-origin',
                cache: 'no-cache'
            });
            if (!r.ok) return null;
            return await r.json();
        } catch (_e) { return null; }
    }

    var elevation = null;
    var panelEl = null, btnEl = null, adminInput = null;

    function isElevated() {
        return !!(elevation && elevation.isElevated && elevation.isElevated());
    }

    // Keep the button's armed ring + the menu checkbox in lockstep with the
    // elevation cookie (flipped here, by ?admin=, or by the banner's Drop).
    function syncArmed() {
        if (btnEl) btnEl.classList.toggle('profile-btn--armed', isElevated());
        if (adminInput) adminInput.checked = isElevated();
    }

    function closeMenu() {
        if (panelEl) panelEl.classList.remove('open');
        if (btnEl) btnEl.setAttribute('aria-expanded', 'false');
    }
    // The panel is position:fixed (to escape the app's stacking contexts), so
    // anchor it to the button rect — top just below it, right-aligned.
    function positionPanel() {
        var r = btnEl.getBoundingClientRect();
        panelEl.style.top = (r.bottom + 4) + 'px';
        panelEl.style.right = Math.max(4, window.innerWidth - r.right) + 'px';
        panelEl.style.left = 'auto';
    }
    function toggleMenu() {
        if (!panelEl) return;
        var open = panelEl.classList.toggle('open');
        if (open) positionPanel();
        btnEl.setAttribute('aria-expanded', open ? 'true' : 'false');
    }

    function linkItem(text, href) {
        var a = el('a', 'profile-menu__item', text);
        a.href = href;
        a.setAttribute('role', 'menuitem');
        return a;
    }

    function build(access) {
        var wrap = el('div', 'profile-menu');

        btnEl = el('button', 'btn btn-secondary profile-btn');
        btnEl.type = 'button';
        btnEl.id = 'profile-btn';
        btnEl.title = 'Account: ' + (access.email || 'signed in');
        btnEl.setAttribute('aria-haspopup', 'menu');
        btnEl.setAttribute('aria-expanded', 'false');
        var initial = ((access.email || '?').trim().charAt(0) || '?').toUpperCase();
        btnEl.appendChild(el('span', 'profile-btn__avatar', initial));
        btnEl.addEventListener('click', function (e) { e.stopPropagation(); toggleMenu(); });
        wrap.appendChild(btnEl);

        panelEl = el('div', 'profile-menu__panel');
        panelEl.setAttribute('role', 'menu');

        var id = el('div', 'profile-menu__id');
        id.appendChild(el('div', 'profile-menu__email', access.email || '(anonymous)'));
        if (access.is_super_admin) id.appendChild(el('div', 'profile-menu__role', 'super admin'));
        else if (access.has_any_admin_scope) id.appendChild(el('div', 'profile-menu__role', 'admin'));
        panelEl.appendChild(id);
        panelEl.appendChild(el('div', 'profile-menu__sep'));

        // Admin mode — only offered to principals who actually have admin
        // authority somewhere (can_elevate). Drops automatically on leave.
        if (access.can_elevate && elevation) {
            var row = el('label', 'profile-menu__item profile-menu__toggle');
            adminInput = document.createElement('input');
            adminInput.type = 'checkbox';
            adminInput.className = 'profile-menu__check';
            adminInput.checked = isElevated();
            adminInput.addEventListener('change', function () {
                if (adminInput.checked) elevation.setOn(); else elevation.setOff();
            });
            row.appendChild(adminInput);
            var txt = el('span', 'profile-menu__toggle-label');
            txt.appendChild(el('span', null, 'Admin mode'));
            txt.appendChild(el('span', 'profile-menu__hint', 'bypass WORM/ACL — drops when you leave the page'));
            row.appendChild(txt);
            panelEl.appendChild(row);
            panelEl.appendChild(el('div', 'profile-menu__sep'));
        }

        panelEl.appendChild(linkItem('Profile', '/.profile'));
        panelEl.appendChild(linkItem('Access tokens', '/.tokens'));
        // No "Sign out": authentication is the upstream proxy's concern
        // (oauth2-proxy / Authelia). ZDDC doesn't own a session, so it
        // doesn't render a logout affordance.

        // Portal the panel to <body>, not inside the header: the app's
        // layout creates stacking contexts that trap even a fixed+high
        // z-index panel below the content. As a direct body child it sits in
        // the root stacking context and reliably overlays everything.
        // position:fixed + positionPanel() keep it anchored to the button.
        document.body.appendChild(panelEl);
        return wrap;
    }

    async function init() {
        if (window.location.protocol === 'file:') return;
        elevation = window.zddc.elevation || null;
        var access = await fetchAccess();
        if (!access || !access.email) return; // unauthenticated / non-zddc backend
        var host = document.querySelector('.header-right');
        if (!host) return;

        host.appendChild(build(access));
        syncArmed();

        document.addEventListener('click', function (e) {
            if (panelEl && panelEl.classList.contains('open')
                && !panelEl.contains(e.target) && !btnEl.contains(e.target)) closeMenu();
        });
        document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeMenu(); });
        window.addEventListener('zddc:elevationchange', syncArmed);

        window.zddc.profileMenu = { close: closeMenu };
    }

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