import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { forwardRef, Fragment, useEffect, useRef, useState } from 'react';
import styled, { css } from 'styled-components';
import { rgba } from 'polished';
import { useElement, useConsolidatedRef, useDirection } from '../../hooks';
import { defaultThemeProp } from '../../theme';
import { debounce, tryCatch } from '../../utils';
import Button, { StyledButton } from '../Button';
import Flex from '../Flex';
import Link, { StyledLink } from '../Link';
import Icon, { StyledIcon, registerIcon } from '../Icon';
import * as caretLeftIcon from '../Icon/icons/caret-left.icon';
import * as caretRightIcon from '../Icon/icons/caret-right.icon';
import MenuButton from '../MenuButton';
import Text, { StyledText } from '../Text';
import Tooltip from '../Tooltip/Tooltip';
registerIcon(caretLeftIcon, caretRightIcon);
const StyledSeparator = styled(Icon)(({ theme }) => {
    const color = tryCatch(() => rgba(theme.base.palette['foreground-color'], theme.base.transparency['transparent-2']));
    return css `
    color: ${color};
  `;
});
export const StyledBreadcrumbs = styled.div(({ oneItemRemaining, fixedLength }) => css `
    white-space: nowrap;
    overflow: visible;
    visibility: ${fixedLength ? undefined : 'hidden'};

    ${StyledIcon} {
      width: 1em;
      height: 1em;
    }

    ${StyledLink},
    ${StyledButton},
    ${StyledText} {
      flex-shrink: 1;

      &:last-child {
        ${oneItemRemaining
    ? css `
              flex-shrink: 1;
              text-overflow: ellipsis;
              overflow: hidden;
            `
    : css `
              flex-shrink: 0;
            `}
      }
    }
  `);
const getEllipsisStyles = ({ theme }) => {
    return css `
    min-width: ${theme.base['content-width'].xs};
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  `;
};
const StyledEllipsizedLink = styled(Link)(getEllipsisStyles);
StyledEllipsizedLink.defaultProps = defaultThemeProp;
const StyledEllipsizedButton = styled(Button)(getEllipsisStyles);
StyledEllipsizedButton.defaultProps = defaultThemeProp;
const StyledEllipsizedText = styled(Text)(getEllipsisStyles);
StyledEllipsizedText.defaultProps = defaultThemeProp;
const Breadcrumbs = forwardRef(function Breadcrumbs({ path, leafOnly = false, ...restProps }, ref) {
    const nodeRefs = useRef({});
    const [breadcrumbsEl, setBreadcrumbsEl] = useElement();
    const [numMenuItems, setNumMenuItems] = useState(leafOnly ? Math.max(path.length - 1, 0) : 0);
    const minInlineWidth = useRef(0);
    const breadcrumbRef = useConsolidatedRef(setBreadcrumbsEl, ref);
    // Update menu based on length
    useEffect(() => {
        if (leafOnly) {
            setNumMenuItems(Math.max(path.length - 1, 0));
        }
        else {
            setNumMenuItems(0);
        }
    }, [path, leafOnly]);
    // Manage Observers
    useEffect(() => {
        const debouncedResize = debounce((entries) => {
            if (entries[0].contentRect.width > minInlineWidth.current) {
                setNumMenuItems(curr => {
                    if (curr === 0)
                        return curr;
                    return curr - 1;
                });
            }
        }, 100);
        const resizeObserver = new ResizeObserver(debouncedResize);
        const intersectionObserver = new IntersectionObserver(entries => {
            if (entries[0].intersectionRatio < 1 && numMenuItems < path.length - 1) {
                if (entries[0].rootBounds)
                    minInlineWidth.current = entries[0].rootBounds.width + 1;
                setNumMenuItems(curr => {
                    if (curr === path.length - 1)
                        return curr;
                    return curr + 1;
                });
            }
            else if (breadcrumbsEl)
                breadcrumbsEl.style.visibility = 'visible';
        }, { root: breadcrumbsEl, threshold: 1 });
        if (!leafOnly && breadcrumbsEl && breadcrumbsEl.lastChild) {
            intersectionObserver.observe(breadcrumbsEl.lastChild);
            resizeObserver.observe(breadcrumbsEl);
        }
        return () => {
            intersectionObserver.disconnect();
            resizeObserver.disconnect();
        };
    }, [breadcrumbsEl, numMenuItems, leafOnly]);
    const { end } = useDirection();
    return (_jsxs(Flex, { ...restProps, container: { gap: 0.5, alignItems: 'center' }, as: StyledBreadcrumbs, oneItemRemaining: numMenuItems === path.length - 1, fixedLength: leafOnly, ref: breadcrumbRef, children: [numMenuItems > 0 && (_jsxs(_Fragment, { children: [_jsx(MenuButton, { text: 'Links', iconOnly: true, variant: 'link', icon: 'folder-hierarchy-solid', menu: { items: path.slice(0, numMenuItems).reverse() } }), _jsx(StyledSeparator, { name: `caret-${end}` })] })), path.slice(numMenuItems).map((crumb, index) => {
                const { id, primary, visual, href, onClick, ...restCrumbProps } = crumb;
                let Comp;
                if (href)
                    Comp = (_jsxs(Link, { href: href, as: primary.length >= 20 ? StyledEllipsizedLink : undefined, onClick: (e) => {
                            onClick?.(id, e);
                        }, ...restCrumbProps, ref: el => {
                            nodeRefs.current[id] = el;
                        }, children: [visual, " ", primary] }, id));
                else if (onClick)
                    Comp = (_jsxs(Button, { variant: 'link', as: primary.length >= 20 ? StyledEllipsizedButton : undefined, onClick: (e) => {
                            onClick(id, e);
                        }, ...restCrumbProps, ref: el => {
                            nodeRefs.current[id] = el;
                        }, children: [visual, " ", primary] }, id));
                else
                    Comp = (_jsxs(Text, { as: primary.length >= 20 ? StyledEllipsizedText : undefined, ...restCrumbProps, ref: el => {
                            nodeRefs.current[id] = el;
                        }, children: [visual, " ", primary] }, id));
                if (index === path.slice(numMenuItems).length - 1)
                    return Comp;
                return (_jsxs(Fragment, { children: [Comp, _jsx(Tooltip, { target: nodeRefs.current[id], smart: true, children: primary }), _jsx(StyledSeparator, { name: `caret-${end}` })] }, id));
            })] }));
});
export default Breadcrumbs;
//# sourceMappingURL=Breadcrumbs.js.map