import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useState, useEffect, useCallback, useMemo, useContext } from 'react';
import Button from '../Button';
import Grid from '../Grid';
import Icon from '../Icon';
import Image from '../Image';
import Link from '../Link';
import Tooltip from '../Tooltip';
import VisuallyHiddenText from '../VisuallyHiddenText';
import { useI18n, useElement } from '../../hooks';
import { isValidElement } from '../../utils';
import NavigationList from './NavigationList';
import AppShellContext, { AppShellDrawerContext } from './AppShellContext';
import AppShellDrawer from './Drawer';
import { AppShellSearch } from './AppShellSearch';
import { StyledAppInfo, StyledCaseTypes, StyledScrollWrap, StyledUtils, StyledNavCasesList, StyledCountIcon, StyledUtilIconCount, StyledAppShellTooltip, StyledUtilsSeparator, StyledAIAssistant, headerHeight } from './AppShell.styles';
export const CaseTypes = ({ caseTypes, mobileNavBar }) => {
    const t = useI18n();
    const transformedCaseTypes = caseTypes.map(caseType => {
        return {
            ...caseType,
            visual: caseType.icon ? _jsx(Icon, { name: caseType.icon }) : undefined,
            primary: caseType.name
        };
    });
    return useMemo(() => (_jsx(StyledCaseTypes, { children: _jsx(NavigationList, { items: [
                {
                    primary: t('app_shell_create'),
                    visual: _jsx(Icon, { name: 'plus' }),
                    items: transformedCaseTypes
                }
            ], mobileNavBar: mobileNavBar }) })), [caseTypes, mobileNavBar]);
};
export const Links = (props) => {
    const { links, mobileNavBar } = props;
    const [transformedLinks, setTransformedLinks] = useState([]);
    // TODO: Can this be a memo instead of a state and an effect?
    const mergedNavLinks = (items) => {
        return items.map((link) => {
            return {
                ...link,
                primary: link.name,
                'aria-current': link.active ? 'page' : null,
                visual: link.icon ? _jsx(Icon, { name: link.icon }) : null,
                onClick: link.links ? undefined : link.onClick,
                items: link.links ? mergedNavLinks(link.links) : undefined
            };
        });
    };
    useEffect(() => {
        setTransformedLinks(mergedNavLinks(links));
    }, [links]);
    if (!links.length)
        return null;
    return (_jsx("div", { children: _jsx(NavigationList, { items: transformedLinks, mobileNavBar: mobileNavBar }) }));
};
const AIAssistant = ({ agent }) => (_jsx(StyledAIAssistant, { children: _jsx(NavigationList, { items: [
            {
                id: agent.id,
                primary: agent.name,
                visual: agent.icon,
                'aria-current': agent.active ? 'page' : null,
                onClick: agent.onClick
            }
        ] }) }));
const Cases = (props) => {
    const { cases } = props;
    const setupCases = (items) => {
        return items.map((item) => {
            const { id, primary, secondary, collapsedItemInfo, visual = _jsx(Icon, { name: 'case-solid' }), active, onClick, onDismiss, ...restProps } = item;
            return {
                ...restProps,
                id,
                'aria-current': active ? 'page' : undefined,
                primary,
                secondary,
                collapsedItemInfo,
                active: !!active,
                onClick,
                onDismiss,
                visual
            };
        });
    };
    return (_jsx(StyledNavCasesList, { children: _jsx(NavigationList, { items: setupCases(cases) }) }));
};
export const Utils = ({ items }) => {
    const { navOpen, navState, drawerOpen, setDrawerOpen, appHeaderEl } = useContext(AppShellContext);
    const [item, setItem] = useState();
    useEffect(() => {
        if (drawerOpen && item) {
            setItem(items?.find((utilItem) => !isValidElement(utilItem) && utilItem.name === item.name));
        }
    }, [items]);
    const transform = useCallback((utilItem) => {
        const uItem = { ...utilItem };
        delete uItem.onDrawerClose;
        delete uItem.onDrawerOpen;
        return {
            onClick: () => {
                if (utilItem.drawerView) {
                    setItem(utilItem);
                }
            },
            ...uItem,
            primary: utilItem.name,
            visual: utilItem.count ? (_jsxs(StyledUtilIconCount, { children: [utilItem.visual, _jsx(StyledCountIcon, { variant: 'urgent', id: `${utilItem.name}-count`, children: utilItem.count })] })) : (utilItem.visual),
            collapseItems: !navOpen
        };
    }, [navOpen]);
    const utilItems = useMemo(() => {
        return [
            ...(items ?? []).map(uItem => {
                return isValidElement(uItem) ? uItem : transform(uItem);
            })
        ];
    }, [items, transform]);
    useEffect(() => {
        if (item)
            setDrawerOpen(true);
    }, [item]);
    useEffect(() => {
        if (navState === 'closed' || navState === 'closing')
            setDrawerOpen(false);
    }, [navState]);
    // setDrawerOpen comes from AppShellContext (raw useState setter — stable reference).
    // setItem is the local useState setter — also stable. Neither needs to be in deps.
    // openDrawer and refreshDrawer have identical bodies: both spread `next` to create
    // a new object reference so useEffect([item]) always fires, even when the same item
    // is re-opened. The semantic distinction is: openDrawer starts a new drawer session
    // (useEffect triggers setDrawerOpen(true)); refreshDrawer replaces an already-open
    // item's content (setDrawerOpen(true) is a no-op when already open).
    const ctxValue = useMemo(() => ({
        drawerOpen,
        openItemName: item?.name,
        closeDrawer: () => {
            setDrawerOpen(false);
        },
        openDrawer: (next) => {
            setItem({ ...next });
        },
        refreshDrawer: (next) => {
            setItem({ ...next });
        }
    }), [drawerOpen, item?.name]);
    return (_jsxs(AppShellDrawerContext.Provider, { value: ctxValue, children: [_jsx(StyledUtils, { children: _jsx(NavigationList, { items: utilItems, collapsed: true }) }), item && (_jsx(AppShellDrawer, { drawerOpen: drawerOpen, setDrawerOpen: setDrawerOpen, content: item.drawerView, header: item.drawerHeader || item.name, topOffset: appHeaderEl ? headerHeight : '0', onDrawerClose: () => {
                    setItem(undefined);
                    item.onDrawerClose?.();
                }, onDrawerOpen: item.onDrawerOpen }))] }));
};
const AppInfo = ({ appInfo }) => {
    const [appInfoEl, setAppInfoEl] = useElement();
    const { navState } = useContext(AppShellContext);
    const { appName, portalName, href: appInfoHref, onClick: appInfoOnClick, imageSrc: logoSrc, appNameHidden, ...appInfoRestProps } = appInfo;
    let appInfoAs = 'div';
    if (appInfoHref)
        appInfoAs = Link;
    else if (appInfoOnClick)
        appInfoAs = Button;
    return (_jsxs(_Fragment, { children: [_jsxs(StyledAppInfo, { as: Grid, forwardedAs: appInfoAs, variant: 'link', href: appInfoHref, onClick: appInfoOnClick, "aria-label": `${appName}${portalName ? ` - ${portalName}` : ''}`, ...appInfoRestProps, container: {
                    alignItems: 'center',
                    areas: portalName ? '"logo app" "logo portal"' : '"logo app"'
                }, ref: setAppInfoEl, icon: true, children: [_jsx(Grid, { item: { area: 'logo' }, as: Image, src: logoSrc, alt: appName }), _jsx(Grid, { item: { area: 'app' }, as: appNameHidden ? VisuallyHiddenText : 'span', children: appName }), portalName && (_jsx(Grid, { item: { area: 'portal' }, as: 'span', children: portalName }))] }), navState === 'closed' && (!appNameHidden || portalName) && (_jsx(Tooltip, { target: appInfoEl, placement: 'right', as: StyledAppShellTooltip, showDelay: 'none', hideDelay: 'none', children: `${appNameHidden ? '' : appName} ${portalName ?? ''}`.trim() }))] }));
};
const AppNavigationPanel = ({ appInfo, navState, searchInput, searchLabel, onClick, caseTypes, links, cases, utils, agent }) => {
    return (_jsxs(_Fragment, { children: [appInfo && _jsx(AppInfo, { appInfo: appInfo }), searchInput && (_jsx(AppShellSearch, { searchLabel: searchLabel, collapsed: ['closed', 'closing'].includes(navState), searchInput: searchInput })), _jsxs(StyledScrollWrap, { container: { direction: 'column' }, item: { grow: 1 }, tabIndex: -1, onClick: (e) => {
                    // Ensure that clicks on the container (not on interactive child elements) trigger the onClick handler
                    if (e.target === e.currentTarget)
                        onClick?.();
                }, children: [caseTypes && caseTypes.length > 0 && _jsx(CaseTypes, { caseTypes: caseTypes }), links && _jsx(Links, { links: links }), cases && _jsx(Cases, { cases: cases }), ['open', 'opening'].includes(navState) && (_jsx(StyledUtilsSeparator, { navOpen: ['open', 'opening'].includes(navState) }))] }), ['closed', 'closing'].includes(navState) && _jsx(StyledUtilsSeparator, {}), _jsx(Utils, { items: utils }), agent && _jsx(AIAssistant, { agent: agent })] }));
};
export default AppNavigationPanel;
//# sourceMappingURL=AppNavigationPanel.js.map