import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useCallback, useRef, useMemo, useState } from 'react';
import Icon, { registerIcon } from '../Icon';
import * as barsIcon from '../Icon/icons/bars.icon';
import Popover from '../Popover';
import Menu from '../Menu';
import { useEscape, useFocusWithin, useI18n } from '../../hooks';
import { createStringMatcher } from '../../utils';
import { StyledTopNavItem } from './AppTopNav.styles';
registerIcon(barsIcon);
const FILTER_THRESHOLD = 5;
const linkToMenuItem = (link) => {
    const userOnClick = link.onClick;
    const children = link.links?.map(linkToMenuItem);
    const hasChildren = children && children.length > 0;
    return {
        id: link.id || link.name,
        primary: link.name,
        visual: link.icon ? _jsx(Icon, { name: link.icon }) : undefined,
        href: hasChildren ? undefined : link.href,
        // MenuItem uses `typeof selected !== 'boolean'` to decide expand vs click.
        selected: hasChildren ? undefined : link.active || undefined,
        onClick: userOnClick
            ? (_id, e) => {
                userOnClick(e);
            }
            : undefined,
        items: hasChildren ? children : undefined
    };
};
const TopNavMoreMenu = ({ items, label, active }) => {
    const t = useI18n();
    const triggerRef = useRef(null);
    const popoverRef = useRef(null);
    const [open, setOpen] = useState(false);
    const [filterValue, setFilterValue] = useState('');
    const close = useCallback(() => setOpen(false), []);
    useFocusWithin([triggerRef, popoverRef], useCallback((isFocused) => {
        if (!isFocused)
            setOpen(false);
    }, []));
    useEscape(useCallback((e) => {
        if (open) {
            setOpen(false);
            e.stopPropagation();
            triggerRef.current?.focus();
        }
    }, [open])
    // No target: attach to document so Escape works when focus is inside the
    // Popover portal (events from portal content don't bubble to the trigger element).
    );
    const allItems = useMemo(() => items.map(linkToMenuItem), [items]);
    const showFilter = items.length >= FILTER_THRESHOLD;
    const filterRegex = createStringMatcher(filterValue, 'contains');
    const menuItems = showFilter
        ? allItems.filter(it => filterRegex.test(String(it.primary ?? '')))
        : allItems;
    const handleTriggerClick = () => {
        if (!open)
            setFilterValue('');
        setOpen(v => !v);
    };
    return (_jsxs(_Fragment, { children: [_jsxs(StyledTopNavItem, { ref: triggerRef, "$active": active || open, "aria-haspopup": 'menu', "aria-expanded": open, onClick: handleTriggerClick, children: [_jsx(Icon, { name: 'bars' }), _jsx("span", { children: label ?? t('app_shell_more') })] }), open && (_jsx(Popover, { ref: popoverRef, target: triggerRef.current, placement: 'bottom-end', children: _jsx(Menu, { mode: 'action', variant: 'flyout', "aria-label": label ?? t('app_shell_more'), items: menuItems, onItemClick: close, focusControlEl: triggerRef.current ?? undefined, ...(showFilter
                        ? {
                            filterInputProps: {
                                value: filterValue,
                                onChange: (e) => setFilterValue(e.target.value)
                            }
                        }
                        : {}) }) }))] }));
};
export default TopNavMoreMenu;
//# sourceMappingURL=TopNavMoreMenu.js.map