import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { remToPx, stripUnit } from 'polished';
import { useContext, useEffect, useRef, useState } from 'react';
import styled, { css } from 'styled-components';
import { tryCatch, createStringMatcher, isInstance } from '../../utils';
import { useDirection, useEscape, useOuterEvent, useTheme, useUID } from '../../hooks';
import Text, { StyledText } from '../Text';
import Tooltip from '../Tooltip';
import Popover from '../Popover';
import Menu from '../Menu';
import { StyledMenu, StyledMenuListContainer, StyledMenuListWrapper } from '../Menu/Menu.styles';
import { StyledEmptyState } from '../EmptyState';
import { StyledIcon } from '../Icon';
import { defaultThemeProp } from '../../theme';
import { calculateFontSize } from '../../styles';
import AppShellContext from './AppShellContext';
import { navContrastColors } from './style-utils';
const StyledNavigationPopover = styled.div(({ theme, mobileNavBar }) => {
    const { hoverBg, foreground, backgroundColor } = navContrastColors(theme);
    const headingFontSize = calculateFontSize(theme.base['font-size'], theme.base['font-scale']).s;
    return css `
      display: flex;
      background: ${backgroundColor};

      ${StyledMenu} {
        display: flex;
        flex-direction: column;
        ${mobileNavBar &&
        css `
          width: calc(100vw - (2 * ${theme.base.spacing}));
        `}
      }

      ${StyledMenuListWrapper} {
        overflow: auto;
      }

      &,
      ${StyledMenuListContainer} {
        background: ${backgroundColor};

        header {
          color: ${foreground};
          border-bottom: none;

          h2 {
            font-weight: ${theme.base['font-weight']['semi-bold']};
            font-size: ${headingFontSize};
          }
        }
      }

      ${StyledMenuListContainer} li {
        color: ${foreground};
        background-color: transparent;

        &:hover,
        &[data-current='true'] {
          background-color: ${hoverBg};
        }
      }

      ${StyledEmptyState} {
        ${StyledIcon}, ${StyledText} {
          color: ${foreground};
        }
      }
    `;
});
StyledNavigationPopover.defaultProps = defaultThemeProp;
const ListItemWrapper = props => {
    const { children, childElementRef, label, tooltipLabel, items, filterAt = 5, content, onMenuToggle, mobileNavBar } = props;
    const { navOpen, collapsedHoverMenus, headerEl } = useContext(AppShellContext);
    const popoverRef = useRef(null);
    const filterElRef = useRef(null);
    const isMenu = (Array.isArray(items) && items.length > 0) || !!content;
    const renderFilter = Array.isArray(items) && items.length >= filterAt;
    const [popoverOpen, setPopoverOpen] = useState(false);
    const [filterValue, setFilterValue] = useState('');
    const filterRegex = createStringMatcher(filterValue, 'contains');
    const { end } = useDirection();
    const mousedOverMenu = useRef(false);
    const hidePopoverTimeout = useRef();
    const theme = useTheme();
    const closePopover = (focusChildEl = false) => {
        if (popoverOpen) {
            setFilterValue('');
            setPopoverOpen(false);
            if (focusChildEl) {
                childElementRef.current?.focus();
            }
            if (hidePopoverTimeout.current) {
                clearTimeout(hidePopoverTimeout.current);
                hidePopoverTimeout.current = null;
            }
        }
    };
    const onMouseEnterContent = () => {
        if (collapsedHoverMenus) {
            mousedOverMenu.current = true;
        }
    };
    const onMouseLeaveContent = () => {
        if (mousedOverMenu.current && collapsedHoverMenus) {
            mousedOverMenu.current = false;
            closePopover();
        }
    };
    useOuterEvent('click', isMenu ? [popoverRef, childElementRef] : [], () => closePopover());
    useEffect(() => {
        const onClick = () => {
            if (isMenu) {
                if (!navOpen && !popoverOpen)
                    setPopoverOpen(true);
                else {
                    setTimeout(() => {
                        closePopover(true);
                    }, 0);
                }
            }
        };
        const onKeyDown = (e) => {
            if (e.key === 'Tab' && !content) {
                setPopoverOpen(false);
            }
        };
        const onMouseEnter = () => {
            if (isMenu && collapsedHoverMenus && !navOpen && !popoverOpen) {
                setPopoverOpen(true);
            }
        };
        const onMouseOut = (e) => {
            if (hidePopoverTimeout.current) {
                clearTimeout(hidePopoverTimeout.current);
                hidePopoverTimeout.current = null;
            }
            const tag = e.relatedTarget?.tagName.toLowerCase();
            // If the mouse is mousing out from this nav item onto another nav item
            if (tag && ['a', 'button', 'form'].includes(tag)) {
                closePopover();
            }
            else {
                hidePopoverTimeout.current = window.setTimeout(() => {
                    if (!mousedOverMenu.current) {
                        closePopover();
                    }
                }, 1000);
            }
        };
        const onBlur = (e) => {
            if (isInstance(e.relatedTarget, Node) && popoverRef.current?.contains(e.relatedTarget)) {
                return;
            }
            closePopover();
        };
        childElementRef.current?.addEventListener('blur', onBlur);
        childElementRef.current?.addEventListener('keydown', onKeyDown);
        if (collapsedHoverMenus) {
            childElementRef.current?.addEventListener('mouseenter', onMouseEnter);
            childElementRef.current?.addEventListener('mouseleave', onMouseOut);
        }
        else {
            childElementRef.current?.addEventListener('click', onClick);
        }
        return () => {
            childElementRef.current?.removeEventListener('blur', onBlur);
            childElementRef.current?.removeEventListener('keydown', onKeyDown);
            if (collapsedHoverMenus) {
                childElementRef.current?.removeEventListener('mouseenter', onMouseEnter);
                childElementRef.current?.removeEventListener('mouseleave', onMouseOut);
            }
            else {
                childElementRef.current?.removeEventListener('click', onClick);
            }
            if (hidePopoverTimeout.current) {
                clearTimeout(hidePopoverTimeout.current);
                hidePopoverTimeout.current = null;
            }
        };
    }, [isMenu, navOpen, closePopover, collapsedHoverMenus, popoverOpen]);
    useEffect(() => {
        onMenuToggle?.(popoverOpen ? 'open' : 'close');
    }, [popoverOpen]);
    useEscape(() => closePopover(true), childElementRef, [childElementRef]);
    useEscape(() => closePopover(true), popoverRef, [popoverRef]);
    const searchListId = useUID();
    const itemsToRender = renderFilter
        ? items.filter(item => {
            return filterRegex.test(item.primary);
        })
        : items ?? [];
    const filterInputProps = renderFilter
        ? {
            value: filterValue,
            ref: filterElRef,
            onChange: (e) => setFilterValue(e.target.value)
        }
        : undefined;
    return (_jsxs(_Fragment, { children: [children, !navOpen && (_jsxs(_Fragment, { children: [!popoverOpen && (_jsx(Tooltip, { target: childElementRef.current, placement: mobileNavBar ? 'top' : end, showDelay: 'none', hideDelay: 'none', children: tooltipLabel })), popoverOpen && isMenu && (_jsx(Popover, { target: childElementRef.current, placement: `${mobileNavBar ? 'top' : end}-start`, ref: popoverRef, as: StyledNavigationPopover, arrow: true, strategy: mobileNavBar ? 'absolute' : 'fixed', modifiers: [
                            ...(headerEl
                                ? [
                                    {
                                        name: 'preventOverflow',
                                        options: {
                                            padding: {
                                                top: headerEl.offsetHeight + 8,
                                                right: 8,
                                                bottom: 8,
                                                left: 8
                                            }
                                        }
                                    }
                                ]
                                : []),
                            ...(mobileNavBar
                                ? [
                                    {
                                        name: 'offset',
                                        options: {
                                            offset: [
                                                0,
                                                tryCatch(() => 5.5 + Number(stripUnit(remToPx(theme.base.spacing))), () => 5.5 + 8)
                                            ]
                                        }
                                    }
                                ]
                                : [])
                        ], onClick: (e) => {
                            e.stopPropagation();
                        }, mobileNavBar: mobileNavBar, children: content ? (_jsx("div", { onMouseEnter: onMouseEnterContent, onMouseLeave: onMouseLeaveContent, children: content })) : (_jsx(Menu, { mode: 'action', variant: 'flyout', focusControlEl: childElementRef.current ?? undefined, scrollAt: 99, listId: searchListId, filterInputProps: filterInputProps, items: itemsToRender.map(item => {
                                return {
                                    id: (item.primary || item.text),
                                    primary: (item.primary || item.text),
                                    href: item.href,
                                    onClick: (_, e) => {
                                        e.stopPropagation();
                                        item.onClick?.(e);
                                        setPopoverOpen(false);
                                    }
                                };
                            }), header: _jsx(Text, { variant: 'h2', children: label }), onMouseEnter: onMouseEnterContent, onMouseLeave: onMouseLeaveContent })) }))] }))] }));
};
export default ListItemWrapper;
//# sourceMappingURL=NavigationListItemWrapper.js.map