import React__default, { useState, useRef, useCallback, useEffect } from 'react';
import classnames from 'classnames';
import { C as Checkbox } from './Checkbox-es.js';
import { T as Text } from './Text-es.js';
import { I as Icon } from './Icon-es.js';

var styles$1 = {"multiSelectContainer":"bR1N0mdMeZU-","multiSelect":"_7naerR7479Q-","active":"SpV9TqBIR60-","small":"TdyW0RCheH4-","large":"eBeKgF0JxEQ-","spinning":"_8V1-KUyfAmg-"};

var styles = {"dropDownMenuContainer":"zossMHCpMPU-","option":"poS49c-LqiU-","active":"NxmdtEQX0fQ-","spinning":"mFFvx9SQyZo-"};

function DropDownMenu({ options, setOptions }) {
    const [highlightedIndex, setHighlightedIndex] = useState(0);
    const menuDiv = useRef(null);
    const handleOptionClick = useCallback((clickedOption) => {
        setOptions(current => current.map(option => {
            if (option.label == clickedOption.label) {
                return Object.assign(Object.assign({}, option), { checked: !clickedOption.checked });
            }
            return option;
        }));
    }, []);
    function handleOptionHover(event, index) {
        event.preventDefault();
        setHighlightedIndex(index);
    }
    function handleOptionFocus(index) {
        setHighlightedIndex(index);
        if (menuDiv.current) {
            const option = menuDiv.current.children[index].querySelector("input");
            option === null || option === void 0 ? void 0 : option.focus();
        }
    }
    function scrollMenuIfItemNotInView(menuDivElement, direction) {
        const itemDiv = menuDivElement.querySelector(`:nth-child(${highlightedIndex + 1})`);
        if (!itemDiv)
            return;
        const menuTop = menuDivElement.getBoundingClientRect().top;
        const { top: itemTop, height: itemHeight, bottom: itemBottom, } = itemDiv.getBoundingClientRect();
        const itemTrueBottom = itemBottom + itemHeight;
        const menuBottom = menuDivElement.getBoundingClientRect().bottom;
        if (direction == "up" && itemTop - itemHeight < menuTop) {
            menuDivElement.scrollTop -= itemHeight;
        }
        else if (direction == "down" && itemTrueBottom > menuBottom) {
            menuDivElement.scrollTop += itemHeight;
        }
    }
    function handleKeyDown(event) {
        const { key, metaKey, ctrlKey } = event;
        if (metaKey || ctrlKey)
            return;
        switch (key) {
            case "Enter": {
                if (highlightedIndex >= 0) {
                    handleOptionClick(options[highlightedIndex]);
                }
                break;
            }
            case "ArrowDown": {
                handlePressDown(event);
                break;
            }
            case "ArrowUp": {
                handlePressUp(event);
                break;
            }
        }
    }
    useEffect(() => {
        // focus first option
        handleOptionFocus(0);
    }, [menuDiv]);
    return (React__default.createElement("ul", { "data-testid": "dropdown-menu", "data-elevation": "elevated", className: styles.dropDownMenuContainer, ref: menuDiv, onKeyDown: handleKeyDown }, options.map((option, index) => {
        const optionClass = classnames(styles.option, {
            [styles.active]: index === highlightedIndex,
        });
        return (React__default.createElement("li", { key: `${index}-${option.label}`, className: optionClass, onClick: event => {
                event.stopPropagation();
                event.preventDefault();
                handleOptionClick(option);
            }, onMouseOver: e => handleOptionHover(e, index) },
            React__default.createElement(Checkbox, { label: option.label, checked: option.checked, onFocus: () => setHighlightedIndex(index) })));
    })));
    function handlePressUp(event) {
        event.preventDefault();
        const newIndex = Math.max(0, highlightedIndex - 1);
        handleOptionFocus(newIndex);
        if (menuDiv.current) {
            scrollMenuIfItemNotInView(menuDiv.current, "up");
        }
    }
    function handlePressDown(event) {
        event.preventDefault();
        const newIndex = Math.min(options.length - 1, highlightedIndex + 1);
        handleOptionFocus(newIndex);
        if (menuDiv.current) {
            scrollMenuIfItemNotInView(menuDiv.current, "down");
        }
    }
}

/**
 * @deprecated Use the "multiple" Autocomplete component instead.
 */
function MultiSelect({ defaultLabel, allSelectedLabel, options, onOptionsChange, size, }) {
    const [label, setLabel] = useState(defaultLabel);
    const [menuVisible, setMenuVisible] = useState(false);
    const [focused, setFocused] = useState(false);
    const multiSelectContainer = useRef(null);
    const multiSelectRef = useRef(null);
    const multiSelectClass = classnames(styles$1.multiSelect, {
        [styles$1.active]: menuVisible,
        [styles$1.large]: size === "large",
        [styles$1.small]: size === "small",
    });
    function handleMenuVisibility() {
        var _a;
        (_a = multiSelectRef.current) === null || _a === void 0 ? void 0 : _a.focus();
        setMenuVisible(!menuVisible);
    }
    const handleClickOutside = (e) => {
        var _a;
        if (!((_a = multiSelectContainer === null || multiSelectContainer === void 0 ? void 0 : multiSelectContainer.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
            setMenuVisible(false);
        }
    };
    function handleKeydown(event) {
        var _a;
        const { key, metaKey, ctrlKey } = event;
        if (metaKey || ctrlKey)
            return;
        switch (key) {
            case "Enter":
            case " ": {
                if (focused) {
                    setMenuVisible(!menuVisible);
                }
                break;
            }
            case "Escape": {
                (_a = multiSelectRef.current) === null || _a === void 0 ? void 0 : _a.focus();
                setMenuVisible(false);
                break;
            }
        }
    }
    useEffect(() => {
        document.addEventListener("mousedown", handleClickOutside);
        return () => document.removeEventListener("mousedown", handleClickOutside);
    });
    useEffect(() => {
        const selected = options.filter(option => option.checked);
        if (selected.length === 0) {
            setLabel(defaultLabel);
        }
        else if (selected.length == options.length) {
            setLabel(allSelectedLabel);
        }
        else {
            const selectedLabels = [];
            selected.forEach(option => selectedLabels.push(option.label));
            setLabel(selectedLabels.join(", "));
        }
    }, [options]);
    return (React__default.createElement("div", { ref: multiSelectContainer, className: styles$1.multiSelectContainer, onKeyDown: handleKeydown },
        React__default.createElement("div", { "data-testid": "multi-select", className: multiSelectClass, onClick: handleMenuVisibility, onFocus: () => setFocused(true), onBlur: () => setFocused(false), tabIndex: 0, ref: multiSelectRef, role: "button", "aria-label": `${defaultLabel}: ${label}`, "aria-multiselectable": true, "aria-haspopup": true },
            React__default.createElement(Text, null, label),
            React__default.createElement(Icon, { name: "arrowDown" })),
        menuVisible && (React__default.createElement(DropDownMenu, { options: options, setOptions: onOptionsChange }))));
}

export { MultiSelect as M };
