import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { forwardRef, useEffect, useRef, useState } from 'react';
import Icon, { registerIcon } from '../Icon';
import * as caretDownIcon from '../Icon/icons/caret-down.icon';
import * as timesIcon from '../Icon/icons/times.icon';
import { useConsolidatedRef, useElement, useI18n, useOuterEvent, useTestIds, useUID } from '../../hooks';
import { StyledFormControl } from '../FormControl';
import { getFocusables, withTestIds } from '../../utils';
import Flex from '../Flex';
import Button from '../Button';
import FormField from '../FormField';
import { FormDialog } from '../Dialog';
import { StyledCompositeInput, StyledInputButton, StyledInputContainer } from './CompositeInput.styles';
import { getCompositeInputTestIds } from './CompositeInput.test-ids';
registerIcon(caretDownIcon, timesIcon);
export default withTestIds(forwardRef(function CompositeInput(props, ref) {
    const uid = useUID();
    const { testId, id = uid, disabled, value, onClear, required, status, info, label, labelHidden, additionalInfo, dialog: { renderer: Renderer, rendererProps, onApply, onCancel }, ...restProps } = props;
    const testIds = useTestIds(testId, getCompositeInputTestIds);
    const t = useI18n();
    const [open, setOpen] = useState(false);
    const [popoverEl, setPopoverEl] = useElement(null);
    const containerRef = useConsolidatedRef(ref);
    const buttonRef = useRef(null);
    const formContentRef = useRef(null);
    const closePopover = () => {
        setOpen(false);
        buttonRef.current?.focus();
    };
    useOuterEvent('mousedown', [popoverEl, buttonRef], () => {
        if (open)
            onCancel({ close: closePopover });
    });
    useEffect(() => {
        if (open) {
            getFocusables(formContentRef)[0]?.focus();
        }
    }, [open, formContentRef.current]);
    const labelId = `${id}-label`;
    const Comp = (_jsxs(Flex, { as: StyledCompositeInput, forwardedAs: StyledFormControl, container: { alignItems: 'center' }, status: status, disabled: disabled, ref: containerRef, children: [_jsxs(Flex, { container: { alignItems: 'center' }, item: { grow: 1 }, as: StyledInputContainer, children: [_jsx(StyledInputButton, { "data-testid": testIds.control, ...restProps, id: id, disabled: disabled, "aria-haspopup": 'dialog', "aria-expanded": !disabled && open, "aria-describedby": info ? `${id}-info` : undefined, readOnly: true, required: required, onClick: () => {
                            if (!disabled) {
                                setOpen(true);
                            }
                        }, onKeyDown: e => {
                            if (e.key === 'Enter') {
                                e.preventDefault();
                                setOpen(true);
                            }
                        }, value: value ?? '', ref: buttonRef }), _jsx(Flex, { container: { justify: 'center', alignItems: 'center' }, style: { pointerEvents: value ? '' : 'none' }, children: value && !open ? (_jsx(Button, { icon: true, compact: true, variant: 'simple', label: t('clear'), onClick: onClear, children: _jsx(Icon, { name: 'times' }) })) : (_jsx(Icon, { name: 'caret-down' })) })] }), open && containerRef.current && (_jsx(FormDialog, { arrow: false, 
                // FIXME: The wrath of optional labels, as a ReactNode, strikes again...
                ariaLabel: label, ref: setPopoverEl, target: containerRef.current, placement: 'bottom-start', onCancel: () => onCancel({ close: closePopover }), onSubmit: {
                    text: t('apply'),
                    handler: () => onApply({ close: closePopover })
                }, children: _jsx(Flex, { container: { direction: 'column' }, ref: formContentRef, children: _jsx(Renderer, { ...rendererProps }) }) }))] }));
    return label ? (_jsx(FormField, { testId: testIds, label: label, labelHidden: labelHidden, id: id, info: info, status: status, required: required, disabled: disabled, labelId: labelId, additionalInfo: additionalInfo, children: Comp })) : (Comp);
}), getCompositeInputTestIds);
//# sourceMappingURL=CompositeInput.js.map