'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var _tslib = require('../../../_virtual/_tslib.js');
var React = require('react');
var reactPopper = require('react-popper');
var useClickOutside = require('../../../hooks/useClickOutside.js');
var useKeyPress = require('../../../hooks/useKeyPress.js');
var AlertCircle = require('../../../icons/AlertCircle.js');
var ChevronDown = require('../../../icons/ChevronDown.js');
var index = require('../../../utils/index.js');
var styles = require('../styles.js');
var styles$1 = require('./styles.js');
var MultiValueList = require('./components/MultiValueList.js');
var Checkbox = require('../checkbox/Checkbox.js');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var React__default = /*#__PURE__*/_interopDefaultLegacy(React);

function Dropdown(_a) {
    var _b;
    var { variant, id, name, label, required, placeholder, hasError = false, errorText, optionalText, prefix, assistText, options, onOpen, onClose, onFocus, onBlur, disabled = false, maxHeight = 300, touched, width, noMargin = false } = _a, props = _tslib.__rest(_a, ["variant", "id", "name", "label", "required", "placeholder", "hasError", "errorText", "optionalText", "prefix", "assistText", "options", "onOpen", "onClose", "onFocus", "onBlur", "disabled", "maxHeight", "touched", "width", "noMargin"]);
    const inputRef = React.useRef(null);
    const [referenceElement, setReferenceElement] = React.useState(null);
    const [popperElement, setPopperElement] = React.useState(null);
    const [popperWidth, setPopperWidth] = React.useState(0);
    const [visible, setVisibility] = React.useState(false);
    const [focusOption, setFocusOption] = React.useState(null);
    const [showError, setShowError] = React.useState(false);
    const { value, multivalue, onChange } = props;
    const [refElementHeight, setRefElementHeight] = React.useState(referenceElement === null || referenceElement === void 0 ? void 0 : referenceElement.clientHeight);
    React.useEffect(() => {
        const composeError = typeof touched === 'undefined' ? hasError : hasError && touched;
        setShowError(composeError);
    }, [hasError, touched]);
    const { styles: styles$2, attributes, forceUpdate } = reactPopper.usePopper(referenceElement, popperElement, {
        placement: 'bottom',
        modifiers: [
            {
                name: 'offset',
                options: {
                    offset: [0, 2],
                },
            },
            { name: 'preventOverflow', options: { padding: { top: 8 } } },
            { name: 'flip', options: { padding: { top: 8 } } },
        ],
    });
    const { containerRef } = useClickOutside.useOnClickOutside(() => setVisibility(false));
    const spacePressed = useKeyPress.useKeyPress('Space', containerRef);
    const openPopper = () => {
        if (disabled)
            return;
        setVisibility(true);
        onOpen && onOpen();
    };
    const closePopper = () => {
        if (disabled)
            return;
        setVisibility(false);
        setFocusOption(null);
        onClose && onClose();
    };
    const togglePopper = () => (visible ? closePopper() : openPopper());
    React.useEffect(() => {
        if (inputRef && inputRef.current) {
            if (visible) {
                inputRef.current.focus();
                onFocus && onFocus();
            }
            else {
                inputRef.current.blur();
            }
        }
    }, [visible]);
    React.useEffect(() => {
        if (containerRef && containerRef.current) {
            setPopperWidth(containerRef.current.clientWidth);
        }
    }, [(_b = containerRef.current) === null || _b === void 0 ? void 0 : _b.clientWidth]);
    const toggleMultivalueItem = (item) => {
        if (!multivalue) {
            return [];
        }
        const hasItem = value.find((v) => v.value === item.value);
        if (hasItem) {
            return [...value.filter((v) => v.value !== item.value)];
        }
        else {
            return [...value, item];
        }
    };
    React.useEffect(() => {
        if (spacePressed && focusOption) {
            if (!multivalue) {
                onChange(focusOption);
            }
            else {
                onChange(toggleMultivalueItem(focusOption));
            }
            !multivalue && closePopper();
        }
    }, [spacePressed]);
    React.useEffect(() => {
        !multivalue && setVisibility(false);
    }, [disabled, value, options, hasError, errorText]);
    const onRemove = (item) => {
        if (multivalue) {
            onChange([...value.filter((v) => String(v.value) !== String(item))]);
        }
    };
    const handleClick = (item) => {
        if (!multivalue) {
            onChange(item);
        }
        else {
            onChange(toggleMultivalueItem(item));
        }
        !multivalue && closePopper();
    };
    const onElementFocus = (op) => () => {
        setFocusOption(op);
    };
    React.useEffect(() => {
        setTimeout(() => {
            if ((referenceElement === null || referenceElement === void 0 ? void 0 : referenceElement.clientHeight) !== refElementHeight && multivalue) {
                setRefElementHeight(referenceElement === null || referenceElement === void 0 ? void 0 : referenceElement.clientHeight);
                if (typeof forceUpdate === 'function') {
                    forceUpdate();
                }
            }
        });
    }, [referenceElement === null || referenceElement === void 0 ? void 0 : referenceElement.clientHeight, refElementHeight, handleClick]);
    if (!id && label) {
        id = `input-${index.slugify(label)}`;
    }
    const appendTestId = index.getId(props['data-testid']);
    const appendTrackId = index.getId(props['data-trackid']);
    const getInput = () => {
        if (multivalue) {
            return (React__default['default'].createElement(MultiValueList.MultiValueList, { values: value, onRemove: onRemove, placeholder: placeholder }));
        }
        else if (!multivalue && value.label) {
            return value.label;
        }
        return placeholder;
    };
    return (React__default['default'].createElement(styles.Wrapper, { ref: containerRef, "data-testid": appendTestId('dropdown'), "data-trackid": appendTrackId('dropdown'), width: width, noMargin: noMargin },
        React__default['default'].createElement(styles.LabelWrapper, { disabled: disabled, hasLabel: Boolean(label === null || label === void 0 ? void 0 : label.length) },
            label && (React__default['default'].createElement(styles.Label, { htmlFor: id, disabled: disabled }, label)),
            !required && React__default['default'].createElement(styles.Text, null, optionalText)),
        React__default['default'].createElement(styles.Border, { hasError: showError, disabled: disabled },
            Boolean(prefix) && (React__default['default'].createElement(styles$1.DropdownPrefix, { "data-testid": appendTestId('prefix'), hasValue: Boolean(multivalue ? value.length > 0 : value.value) }, prefix)),
            React__default['default'].createElement(styles$1.SelectInput, { ref: setReferenceElement, id: id, role: "button", "data-testid": appendTestId(), "data-trackid": appendTrackId(), "aria-haspopup": "true", "aria-expanded": visible, onClick: togglePopper, variant: variant, disabled: disabled, "aria-label": label ? undefined : props['aria-label'], hasText: Boolean((multivalue ? value.length > 0 : value.label) || placeholder), onBlur: onBlur },
                getInput(),
                React__default['default'].createElement("input", { ref: inputRef, name: name, readOnly: true }),
                React__default['default'].createElement(ChevronDown['default'], { width: 20, height: 20 }))),
        visible && (React__default['default'].createElement(styles$1.OptionsPopper, Object.assign({ role: "listbox", ref: setPopperElement, width: popperWidth, maxHeight: maxHeight, style: styles$2.popper }, attributes.popper, { "data-testid": "options-dropdown" }), options.map((op) => !op.isHidden && (React__default['default'].createElement(styles$1.OptionItem, { tabIndex: 0, role: "option", isSelected: multivalue
                ? value.some((v) => v.value === op.value)
                : op.value === value.value, isDisabled: op.isDisabled, key: String(op.value), onClick: () => !op.isDisabled && handleClick(op), onFocus: onElementFocus(op), "data-trackid": op['data-trackid'], "data-testid": op['data-testid'], "aria-label": op['aria-label'], isMultivalue: multivalue },
            multivalue ? (React__default['default'].createElement(React__default['default'].Fragment, null,
                React__default['default'].createElement(Checkbox.Checkbox, { name: name || 'multi-select', value: String(op.value), checked: value.some((v) => v.value === op.value), onChange: () => !op.isDisabled && handleClick(op), tabIndex: -1 }),
                React__default['default'].createElement(styles$1.OptionItemLabel, { isMultivalue: true }, op.label))) : (React__default['default'].createElement(styles$1.OptionItemLabel, null, op.label)),
            op.altText && React__default['default'].createElement("div", null, op.altText)))))),
        React__default['default'].createElement(styles.SupportingText, { noMargin: noMargin },
            Boolean(errorText) && showError && !disabled && (React__default['default'].createElement(styles.ErrorMessage, null,
                React__default['default'].createElement(AlertCircle['default'], { width: 20, height: 20 }),
                errorText)),
            !showError &&
                (typeof assistText === 'string' ? (React__default['default'].createElement(styles.AssistMessage, null, assistText)) : (assistText)))));
}

exports.Dropdown = Dropdown;
