import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { forwardRef, useEffect, useRef, useState, useMemo, useLayoutEffect, useCallback, cloneElement } from 'react';
import { getActiveElement, withTestIds, isValidElement, hasProp } from '../../utils';
import Icon, { registerIcon } from '../Icon';
import { useConsolidatedRef, useEscape, useFocusTrap, useFocusWithin, useI18n, usePrevious, useTestIds, useUID } from '../../hooks';
import Grid from '../Grid';
import Flex from '../Flex';
import FieldValueList from '../FieldValueList';
import Actions from '../Actions';
import { StyledImage } from '../Image';
import * as pictureIcon from '../Icon/icons/picture.icon';
import { getSelectionCardTestIds } from './SelectionCard.test-ids';
import { StyledSelectionCard, StyledContentContainer, StyledImageContainer, StyledSelectionCardInline, StyledSelectionCardStacked, StyledValueList } from './SelectionCard.styles';
registerIcon(pictureIcon);
export const focusableSelector = 'a[href], button, input, textarea, select, details, video[controls], audio[controls]';
const useContentHeight = (ref) => {
    const [height, setHeight] = useState();
    useLayoutEffect(() => {
        if (!ref.current)
            return;
        const resizeObserver = new ResizeObserver(() => {
            setHeight(ref.current?.scrollHeight);
        });
        resizeObserver.observe(ref.current);
        return () => {
            resizeObserver.disconnect();
        };
    }, []);
    return height;
};
const SelectionCard = forwardRef(function SelectionCard(props, ref) {
    const uid = useUID();
    const { testId, id = uid, label, heading, disabled = false, image, fields = [], onClick, onKeyDown, actions, additionalInfo, ...restProps } = props;
    const t = useI18n();
    const contentRef = useRef(null);
    const containerRef = useConsolidatedRef(ref);
    const [focusOnInput, setFocusOnInput] = useState(false);
    const [hasInteractiveElements, setHasInteractiveElements] = useState(0);
    const [isBrokenImage, setIsBrokenImage] = useState(false);
    const prevImageSrc = usePrevious(image?.src);
    const testIds = useTestIds(testId, getSelectionCardTestIds);
    const contentHeight = useContentHeight(contentRef);
    const contentId = `${id}-content`;
    const hasAdditionalContent = fields.length > 0;
    useEffect(() => {
        const focusables = containerRef.current?.querySelectorAll(focusableSelector);
        setHasInteractiveElements(focusables?.length || 0);
        setFocusOnInput(focusables?.length === 1 && focusables?.[0] instanceof HTMLInputElement);
        focusables?.forEach(el => el.hasAttribute('data-main-focus')
            ? el.removeAttribute('tabindex')
            : el.setAttribute('tabindex', '-1'));
    }, [additionalInfo, fields, actions, contentHeight]);
    useFocusTrap(focusOnInput ? null : contentRef, false, [contentRef]);
    useFocusWithin([focusOnInput ? null : contentRef], focused => contentRef.current
        ?.querySelectorAll(focusableSelector)
        .forEach(el => (focused ? el.removeAttribute('tabindex') : el.setAttribute('tabindex', '-1'))));
    useEscape(() => containerRef.current?.focus(), focusOnInput ? null : containerRef, [
        containerRef
    ]);
    const handleKeyDown = useCallback((event) => {
        if (event.key === 'Enter' &&
            containerRef.current === getActiveElement() &&
            (!focusOnInput || (focusOnInput && hasInteractiveElements > 1))) {
            event.preventDefault();
            contentRef.current?.querySelectorAll(focusableSelector)[0]?.focus();
        }
        onKeyDown?.(event);
    }, [containerRef, contentRef]);
    const imageContent = useMemo(() => {
        if (image) {
            const imagery = (isBrokenImage && image.src === prevImageSrc) || image.src === undefined ? (_jsx(Icon, { name: 'picture', "aria-label": t('image_load_error') })) : (_jsx(StyledImage, { "data-testid": testIds.image, ...image, onError: () => setIsBrokenImage(true), onLoad: () => setIsBrokenImage(false) }));
            return (_jsx(Flex, { container: { justify: 'center', alignItems: 'center' }, as: StyledImageContainer, placement: image.placement, size: image.size, children: imagery }));
        }
    }, [isBrokenImage, image?.src, prevImageSrc, image?.placement, image?.size]);
    let asProp = StyledSelectionCard;
    if (image) {
        asProp = image.placement?.startsWith('block')
            ? StyledSelectionCardStacked
            : StyledSelectionCardInline;
    }
    const isFieldValueListItemProps = (item) => {
        return hasProp(item, 'name');
    };
    return (_jsxs(Grid, { "data-testid": testIds.root, ...restProps, id: id, onClick: onClick, as: asProp, placement: image?.placement, size: image?.size, container: { cols: '1fr', rows: 'auto' }, disabled: disabled, role: hasInteractiveElements ? 'group' : 'article', "aria-label": label, ref: containerRef, "data-main-focus": focusOnInput ? undefined : true, tabIndex: focusOnInput ? undefined : 0, onKeyDown: handleKeyDown, style: { '--content-height': `${contentHeight}px` }, children: [image && image.placement !== 'inline-end' && imageContent, _jsx("div", { children: _jsxs(Flex, { as: StyledContentContainer, container: { wrap: 'wrap', alignContent: 'start', justify: 'between' }, ref: contentRef, children: [isValidElement(heading) ? (cloneElement(heading, {
                            ...{
                                tabIndex: focusOnInput ? undefined : -1,
                                additionalInfo,
                                'data-main-focus': focusOnInput ? true : undefined,
                                'aria-details': hasAdditionalContent ? contentId : undefined
                            }
                        })) : (_jsx("span", { "aria-details": hasAdditionalContent ? contentId : undefined, children: heading })), actions && (_jsx(Actions, { "data-testid": testIds.actions, items: actions, menuAt: 1, disabled: disabled, contextualLabel: label })), hasAdditionalContent &&
                            (fields.every(field => isFieldValueListItemProps(field)) ? (_jsx(FieldValueList, { id: contentId, "data-testid": testIds.content, fields: fields })) : (_jsx(Flex, { container: { direction: 'column', gap: 1 }, as: StyledValueList, id: contentId, "data-testid": testIds.content, children: fields.map(field => (_jsx("li", { children: field.value }, field.id))) })))] }) }), image?.placement === 'inline-end' && imageContent] }));
});
export default withTestIds(SelectionCard, getSelectionCardTestIds);
//# sourceMappingURL=SelectionCard.js.map