import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { forwardRef, useRef, useLayoutEffect, useContext, useMemo, useState } from 'react';
import styled, { css } from 'styled-components';
import { transparentize } from 'polished';
import Button from '../Button';
import Icon, { registerIcon } from '../Icon';
import * as plusIcon from '../Icon/icons/plus.icon';
import { useDirection, useI18n } from '../../hooks';
import { defaultThemeProp } from '../../theme';
import { getActiveElement, getFocusables, tryCatch } from '../../utils';
import Flex from '../Flex';
import EmptyState from '../EmptyState';
import AdditionalInfo from '../AdditionalInfo';
import Text from '../Text';
import { nlpColors, readableHue } from '../../styles';
import { getIndexDetails } from './FieldGroupList.utils';
import FieldGroup, { StyledFieldGroup, StyledFieldGroupContent, StyledFieldGroupLegend, StyledGroupContainer, StyledFieldHeader } from './FieldGroup';
import FieldGroupListContext from './FieldGroupListContext';
registerIcon(plusIcon);
const StyledFieldGroupList = styled.ol(() => css `
    list-style: none;
  `);
StyledFieldGroupList.defaultProps = defaultThemeProp;
export const StyledListItem = styled.li(({ theme: { base: { spacing, palette, 'border-radius': borderRadius } }, depth, listGroupIndex, shouldHighlight }) => {
    const bgColor = tryCatch(() => readableHue(nlpColors[listGroupIndex % nlpColors.length], palette['app-background']), () => nlpColors[listGroupIndex % nlpColors.length]);
    return css `
      display: block;

      > ${StyledGroupContainer} {
        position: relative;
        padding-inline-end: ${spacing};

        &::before {
          content: '';
          position: absolute;
          inset-block-start: 0;
          bottom: 0;
          inset-inline-start: 0;
          width: calc(0.5 * ${spacing});
          background: ${transparentize(0.75, bgColor)};
        }

        ${depth > 1 &&
        css `
          margin-inline-end: -${spacing};
        `}

        ${shouldHighlight &&
        css `
          border-start-end-radius: calc(0.5 * ${borderRadius});
          border-end-end-radius: calc(0.5 * ${borderRadius});
          background: ${transparentize(0.95, palette['foreground-color'])};
        `}
      }

      > ${StyledGroupContainer} > ${StyledFieldGroup} {
        margin-block-start: 0;
        padding: ${spacing} 0;

        &:not(:last-of-type) {
          border-bottom: 0.0625rem solid ${palette['border-line']};
          margin-block-end: calc(2 * ${spacing});
        }

        legend {
          margin-block-end: 0;
        }
      }

      > ${StyledGroupContainer} > ${StyledFieldGroup} > ${StyledFieldGroupContent} {
        padding-inline-start: calc(1.5 * ${spacing});
      }

      > ${StyledGroupContainer} > ${StyledFieldGroup} > ${StyledFieldGroupLegend} {
        ${StyledFieldHeader} {
          margin-inline-start: calc(0.5 * ${spacing});
          padding-inline: ${spacing};
          height: calc(4 * ${spacing});
          border-start-end-radius: calc(0.5 * ${borderRadius});
          border-end-end-radius: calc(0.5 * ${borderRadius});
          background: ${transparentize(0.75, bgColor)};
        }
      }
    `;
});
StyledListItem.defaultProps = defaultThemeProp;
const StyledAddButton = styled(Button)(({ theme: { base: { spacing, 'hit-area': { 'mouse-min': hitAreaMouse } } } }) => css `
    display: inline-flex;
    align-items: center;
    min-height: ${hitAreaMouse};
    min-width: ${hitAreaMouse};
    width: fit-content;
    margin-inline-start: calc(2 * ${spacing});
  `);
StyledAddButton.defaultProps = defaultThemeProp;
const StyledFieldGroupListContainer = styled.div(({ theme: { base: { spacing, palette, 'border-radius': borderRadius } }, hasAdd }) => css `
    position: relative;
    margin-block-start: ${spacing};

    ${hasAdd &&
    css `
      &::before {
        content: '';
        position: absolute;
        inset-inline-start: 0;
        bottom: calc(1.5 * ${spacing});
        width: calc(1.5 * ${spacing});
        height: calc(2.5 * ${spacing});
        border-end-start-radius: calc(0.5 * ${borderRadius});
        border-inline-start: calc(0.5 * ${spacing}) solid ${palette['border-line']};
        border-bottom: calc(0.5 * ${spacing}) solid ${palette['border-line']};
      }
    `}
  `);
StyledFieldGroupListContainer.defaultProps = defaultThemeProp;
const StyledDivider = styled.div(({ theme: { base: { spacing, palette } } }) => css `
    flex: 1;
    height: calc(0.5 * ${spacing});
    background-color: ${palette['border-line']};
  `);
StyledDivider.defaultProps = defaultThemeProp;
const ListItem = ({ item, index, isAddFocused, handleDelete, fieldGroupRef }) => {
    const { id, children, name = '', isDynamic, headingTag, ...restItemProps } = item;
    const t = useI18n();
    const { rtl } = useDirection();
    const { depth = 1, ancestorIndices = [], isAncestorHighlighted = false } = useContext(FieldGroupListContext);
    const [isItemFocused, setIsItemFocused] = useState(false);
    const [isDeleteHovered, setIsDeleteHovered] = useState(false);
    const listIndices = [...ancestorIndices, index];
    const { rootIndex, currentIndex, compoundIndex } = getIndexDetails(listIndices);
    const shouldHighlight = !isAncestorHighlighted && (isAddFocused || isDeleteHovered || isItemFocused);
    let formattedName;
    if (isDynamic) {
        formattedName = name;
    }
    else {
        formattedName = rtl ? `${currentIndex}\u200F ${name}` : `${currentIndex} ${name}`;
    }
    const contextualLabel = isDynamic ? name : `${name} ${compoundIndex}`;
    const ctxValue = useMemo(() => ({
        depth: depth + 1,
        isAncestorHighlighted: shouldHighlight || isAncestorHighlighted,
        ancestorIndices: listIndices
    }), [depth, index, shouldHighlight, isAncestorHighlighted, listIndices]);
    return (_jsx(StyledListItem, { depth: depth, listGroupIndex: rootIndex, shouldHighlight: shouldHighlight, onFocus: () => {
            setIsItemFocused(true);
        }, onBlur: () => {
            setIsItemFocused(false);
        }, children: _jsx(FieldGroupListContext.Provider, { value: ctxValue, children: _jsx(FieldGroup, { name: formattedName, contextualLabel: contextualLabel, headingTag: headingTag, ...restItemProps, actions: handleDelete
                    ? [
                        {
                            id: 'delete',
                            text: t('delete'),
                            icon: 'trash',
                            iconOnly: true,
                            onClick: () => {
                                handleDelete(id);
                            },
                            onMouseEnter: () => setIsDeleteHovered(true),
                            onMouseLeave: () => setIsDeleteHovered(false)
                        }
                    ]
                    : undefined, ref: fieldGroupRef, children: children }) }) }));
};
const FieldGroupList = forwardRef(function FieldGroupList({ label, additionalContext, items, onAdd, onDelete, contextualLabel, ...restProps }, ref) {
    const t = useI18n();
    const addBtnRef = useRef(null);
    const itemRefs = useRef([]);
    const deletedItemIndexRef = useRef(null);
    const [isAddFocused, setIsAddFocused] = useState(false);
    const focusElement = (itemRef, focusPreference) => {
        if (!itemRef)
            return;
        const focusables = getFocusables(itemRef);
        const groupItemLegend = itemRef.querySelector(':scope > legend');
        const groupActionButtons = focusables.filter(focusable => groupItemLegend?.contains(focusable));
        const groupContentFocusables = focusables.filter(focusable => !groupItemLegend?.contains(focusable));
        if (focusPreference === 'action') {
            (groupActionButtons[0] || groupContentFocusables[0])?.focus();
        }
        else {
            (groupContentFocusables[0] || groupActionButtons[0])?.focus();
        }
    };
    useLayoutEffect(() => {
        const currentActiveEl = getActiveElement();
        if (deletedItemIndexRef.current !== null) {
            const deletedIndex = deletedItemIndexRef.current;
            if (items.length === 0 && addBtnRef.current) {
                addBtnRef.current.focus();
            }
            else {
                const nextIndex = Math.min(deletedIndex, items.length - 1);
                const nextItemRef = itemRefs.current[nextIndex];
                focusElement(nextItemRef, 'action');
            }
            deletedItemIndexRef.current = null;
        }
        if (currentActiveEl === addBtnRef.current) {
            const lastIndex = items.length - 1;
            const lastItemRef = itemRefs.current[lastIndex];
            focusElement(lastItemRef, 'content');
        }
    }, [items.length]);
    return (_jsxs(Flex, { container: { direction: 'column', gap: 1 }, as: StyledFieldGroupListContainer, hasAdd: !!onAdd, onFocus: (e) => {
            e.stopPropagation();
        }, onBlur: (e) => {
            e.stopPropagation();
        }, children: [label && (_jsxs(Flex, { container: { gap: 0.5, alignItems: 'center' }, children: [_jsx(Text, { variant: 'h3', children: label }), additionalContext && (_jsx(AdditionalInfo, { contextualLabel: label, children: additionalContext })), _jsx(StyledDivider, { "aria-hidden": 'true' })] })), items.length === 0 ? (_jsx(EmptyState, {})) : (_jsx(Flex, { container: { direction: 'column', gap: 1 }, as: StyledFieldGroupList, ref: ref, ...restProps, children: items.map((item, index) => {
                    const handleDelete = onDelete || item.onDelete
                        ? (id) => {
                            deletedItemIndexRef.current = index;
                            item.onDelete?.(id);
                            onDelete?.(id);
                        }
                        : undefined;
                    return (_jsx(ListItem, { item: item, index: index, isAddFocused: isAddFocused, handleDelete: handleDelete, fieldGroupRef: (el) => {
                            itemRefs.current[index] = el;
                        } }, item.id));
                }) })), onAdd && (_jsxs(StyledAddButton, { variant: 'link', onClick: onAdd, onFocus: () => {
                    setIsAddFocused(true);
                }, onBlur: () => setIsAddFocused(false), ref: addBtnRef, children: [_jsx(Icon, { name: 'plus' }), contextualLabel ? t('add_noun', [contextualLabel]) : t('add')] }))] }));
});
export default FieldGroupList;
//# sourceMappingURL=FieldGroupList.js.map