import React, { useEffect, useMemo, useRef, useState } from "react";
import "../../assets/css/button.css";
import { useOutsideClickDetector } from "../../hooks/useOutsideClickDetector";
const emptyOption = {
    optionLabel: "Please select..",
    clickHandler: () => { },
};
const DefaultDropdownButton = ({ allowEmpty = true, caretLocation = "left", classNames = "", buttonOptions = [], defaultSelection = null, enabled = true, buttonLabel = "Select value", }) => {
    const wrapperRef = useRef(null);
    const uniqueId = useMemo(() => Math.random(), []);
    const [optionsVisible, toggleOptionsPanel] = useState(false);
    const [focusIndex, setFocusIndex] = useState(-1);
    useOutsideClickDetector(wrapperRef, () => toggleOptionsPanel(false));
    const [selectedValue, setSelectedValue] = useState(defaultSelection);
    useEffect(() => {
        if (defaultSelection) {
            setSelectedValue(defaultSelection);
        }
        else {
            if (allowEmpty) {
                if (!buttonOptions.includes(emptyOption))
                    buttonOptions.unshift(emptyOption);
                setSelectedValue(emptyOption);
            }
            else {
                setSelectedValue(buttonOptions[0]);
            }
        }
    }, [defaultSelection]);
    const selectOptionByIndex = (index) => {
        setSelectedValue(buttonOptions[index]);
        if ("clickHandler" in buttonOptions[index]) {
            buttonOptions[index].clickHandler();
        }
        toggleOptionsPanel(false);
    };
    const changeOptionByDirection = (direction) => {
        if (!selectedValue) {
            if (direction === "down") {
                selectOptionByIndex(0);
            }
            return;
        }
        const optionLabels = buttonOptions.map((opt) => opt.optionLabel);
        const currentOptionIndex = optionLabels.indexOf(selectedValue.optionLabel);
        if (direction === "up") {
            const newIndex = currentOptionIndex - 1;
            selectOptionByIndex(Math.max(0, newIndex));
        }
        else {
            const newIndex = currentOptionIndex + 1;
            selectOptionByIndex(Math.min(newIndex, buttonOptions.length - 1));
        }
    };
    const options = buttonOptions.map((option, index) => (React.createElement("div", { key: index, tabIndex: 0, className: "finsemble-dropdown__btn-option", onClick: () => {
            selectOptionByIndex(index);
        }, role: "option", "aria-selected": focusIndex === index }, option.optionLabel)));
    return (React.createElement("div", { tabIndex: enabled ? 0 : -1, ref: wrapperRef, role: "combobox", "aria-haspopup": optionsVisible, "aria-expanded": optionsVisible, "aria-owns": `default-dropdown_${uniqueId}`, "aria-label": "combobox", className: `finsemble-dropdown__btn ${classNames} ${optionsVisible ? "active" : ""}`, onClick: enabled ? () => toggleOptionsPanel(!optionsVisible) : () => { }, onKeyDown: (e) => {
            if (!enabled) {
                return;
            }
            if (optionsVisible) {
                // Keyboard navigation for the expanded combobox options
                if (e.key === "Enter" || e.key === " ") {
                    // Activate the selected option (equiv: click the hovered option)
                    selectOptionByIndex(focusIndex);
                }
                else if (e.key === "ArrowDown") {
                    // Select next option down (equiv: hover over the next option down)
                    setFocusIndex(focusIndex + 1 >= buttonOptions.length ? buttonOptions.length - 1 : focusIndex + 1);
                    e.preventDefault();
                }
                else if (e.key === "ArrowUp") {
                    // Select next option up (equiv: hover over the next option up)
                    setFocusIndex(focusIndex - 1 <= 0 ? 0 : focusIndex - 1);
                    e.preventDefault();
                }
                else if (e.key === "Escape") {
                    // Without activating anything, close the options. (equiv: clicking away)
                    toggleOptionsPanel(false);
                    setFocusIndex(0);
                    e.preventDefault();
                }
            }
            else {
                // Keyboard navigation for a collapsed combobox
                if (e.key === "Enter" || e.key === " ") {
                    // Expand the combobox
                    toggleOptionsPanel(!optionsVisible);
                    setFocusIndex(0);
                    e.preventDefault();
                }
                else if (e.key === "ArrowDown") {
                    if (e.altKey) {
                        toggleOptionsPanel(!optionsVisible);
                    }
                    else {
                        // Cycle between options (down)
                        changeOptionByDirection("down");
                    }
                    e.preventDefault();
                }
                else if (e.key === "ArrowUp") {
                    // Cycle between options (up)
                    e.preventDefault();
                    changeOptionByDirection("up");
                }
            }
        } },
        caretLocation === "left" ? (React.createElement(React.Fragment, null,
            React.createElement("i", { "aria-hidden": "true", className: `ff-caret-${optionsVisible ? "up" : "down"}` }),
            React.createElement("span", { className: "finsemble-dropdown__btn-label", "aria-label": buttonLabel }, selectedValue ? selectedValue.optionLabel : emptyOption.optionLabel))) : (React.createElement(React.Fragment, null,
            React.createElement("span", { className: "finsemble-dropdown__btn-label", "aria-label": buttonLabel }, selectedValue ? selectedValue.optionLabel : emptyOption.optionLabel),
            React.createElement("i", { "aria-hidden": "true", className: `ff-caret-${optionsVisible ? "up" : "down"}` }))),
        optionsVisible ? (React.createElement("div", { id: `default-dropdown_${uniqueId}`, className: `finsemble-dropdown__btn-options ${classNames}` }, options)) : null));
};
export default DefaultDropdownButton;
//# sourceMappingURL=DefaultDropdownButton.js.map