/**
 * UserMenu — avatar button + flyout menu
 *
 * RBAC-gated items based on sw.can() / sw.isAdmin / sw.isTeamAdmin().
 * Surfaces mount this wherever they want; the shell does not own placement.
 *
 * Surface links (Notes, extensions) are auto-included and the CURRENT
 * surface is filtered out so every surface gets the same menu minus itself.
 *
 * Props:
 *   placement   — Menu direction: 'down-right' (default) | 'up-right' etc.
 *   onAction    — Override handler; if omitted, navigates via location.href
 *   extraItems  — Additional menu items inserted after surface links
 */
const { html } = window;
const { useState, useRef, useMemo, useEffect } = hooks;

import { Avatar } from '../primitives/avatar.js';
import { Menu } from '../primitives/menu.js';

/**
 * Detect current surface from body[data-surface].
 */
function _currentSurface() {
    return document.body?.dataset?.surface || '';
}

export function UserMenu({ placement = 'down-right', onAction, extraItems }) {
    const [open, setOpen] = useState(false);
    const [extSurfaces, setExtSurfaces] = useState([]);
    const btnRef = useRef(null);

    const sw = window.sw;
    const user = sw?.auth?.user;
    const authenticated = sw?.auth?.isAuthenticated;

    // Fetch installed surfaces once on mount.
    // Filter out core surfaces that have dedicated menu entries below.
    const CORE_IDS = new Set(['admin', 'settings', 'team-admin', 'workflow', 'workflow-landing']);

    useEffect(() => {
        if (!sw?.api?.surfaces?.list) return;
        sw.api.surfaces.list().then(data => {
            const raw = Array.isArray(data) ? data : data?.data || [];
            setExtSurfaces(raw.filter(s => !CORE_IDS.has(s.id)));
        }).catch(() => {});
    }, [authenticated]);

    const items = useMemo(() => {
        const current = _currentSurface();
        const list = [];

        // ── Surface links (from API — only installed surfaces) ──────
        const DEFAULT_ICON = '\ud83e\udde9';
        const surfaceItems = extSurfaces
            .filter(s => s.id !== current)
            .map(s => ({ label: s.title, action: s.id, icon: s.icon || DEFAULT_ICON }));

        if (surfaceItems.length) {
            list.push(...surfaceItems);
            list.push({ divider: true });
        }

        // ── Extra items from caller ────────────
        if (extraItems && extraItems.length) {
            list.push(...extraItems);
            list.push({ divider: true });
        }

        // ── Standard items ─────────────────────
        // Settings — skip if current surface IS settings
        if (current !== 'settings') {
            list.push({ label: 'Settings', action: 'settings', icon: '\u2699\ufe0f' });
        }

        // Admin — requires admin role
        if (authenticated && sw?.isAdmin && current !== 'admin') {
            list.push({ label: 'Admin', action: 'admin', icon: '\ud83d\udee1\ufe0f' });
        }

        // Team Admin — requires admin role on at least one team
        const hasTeamAdmin = sw?.auth?.teams?.some(t => t.my_role === 'admin');
        if (authenticated && hasTeamAdmin && current !== 'team-admin') {
            list.push({ label: 'Team Admin', action: 'team-admin', icon: '\ud83d\udc65' });
        }

        // Debug — admin only
        if (authenticated && sw?.isAdmin) {
            list.push({ label: 'Debug', action: 'debug', icon: '\ud83d\udc1b' });
        }

        list.push({ divider: true });
        list.push({ label: 'Sign Out', action: 'sign-out' });

        return list;
    }, [user, authenticated, extraItems, extSurfaces]);

    function handleSelect(action) {
        setOpen(false);
        if (onAction) return onAction(action);

        // Default routing
        const BASE = window.__BASE__ || '';
        switch (action) {
            case 'sign-out':
                window.sw?.auth?.logout().then(() => {
                    location.href = BASE + '/login';
                });
                break;
            case 'debug':
                window.dispatchEvent(new CustomEvent('debug:toggle'));
                break;
            default: {
                // Surfaces use their route from the API, or fall back to /{id}
                const ext = extSurfaces.find(s => s.id === action);
                location.href = BASE + (ext?.route || '/' + action);
                break;
            }
        }
    }

    const displayName = user?.display_name || user?.username || 'Demo User';
    const avatar = user?.avatar || null;

    return html`
        <div class="user-menu-wrap">
            <button class="user-btn" ref=${btnRef}
                    onClick=${() => setOpen(!open)} aria-label="User menu">
                <${Avatar} src=${avatar} name=${displayName} size="sm" />
                <span class="sb-label">${displayName}</span>
            </button>
            <${Menu}
                open=${open}
                anchor=${btnRef.current}
                direction=${placement}
                items=${items}
                onSelect=${handleSelect}
                onClose=${() => setOpen(false)}
            />
        </div>
    `;
}
