import React, { forwardRef, useCallback, useEffect, useId, useImperativeHandle, useRef, useState, } from "react";
import IconProp from "../../../Types/Icon/IconProp";
import useComponentOutsideClick from "../../Types/UseComponentOutsideClick";
import Button, { ButtonStyleType } from "../Button/Button";
const MoreMenu = forwardRef((props, componentRef) => {
    const uniqueId = useId();
    const menuId = `menu-${uniqueId}`;
    const buttonId = `menu-button-${uniqueId}`;
    const { ref, isComponentVisible, setIsComponentVisible } = useComponentOutsideClick(false);
    const [focusedIndex, setFocusedIndex] = useState(-1);
    const menuItemRefs = useRef([]);
    useImperativeHandle(componentRef, () => {
        return {
            closeDropdown() {
                setIsComponentVisible(false);
            },
            openDropdown() {
                setIsComponentVisible(true);
            },
            flipDropdown() {
                setIsComponentVisible(!isDropdownVisible);
            },
        };
    });
    const [isDropdownVisible, setDropdownVisible] = useState(false);
    useEffect(() => {
        setDropdownVisible(isComponentVisible);
        if (isComponentVisible) {
            setFocusedIndex(0);
        }
        else {
            setFocusedIndex(-1);
        }
    }, [isComponentVisible]);
    useEffect(() => {
        var _a;
        if (focusedIndex >= 0 && menuItemRefs.current[focusedIndex]) {
            (_a = menuItemRefs.current[focusedIndex]) === null || _a === void 0 ? void 0 : _a.focus();
        }
    }, [focusedIndex]);
    const handleKeyDown = useCallback((event) => {
        if (!isComponentVisible) {
            return;
        }
        const itemCount = props.children.length;
        switch (event.key) {
            case "Escape":
                event.preventDefault();
                setIsComponentVisible(false);
                break;
            case "ArrowDown":
                event.preventDefault();
                setFocusedIndex((prev) => {
                    return (prev + 1) % itemCount;
                });
                break;
            case "ArrowUp":
                event.preventDefault();
                setFocusedIndex((prev) => {
                    return (prev - 1 + itemCount) % itemCount;
                });
                break;
            case "Home":
                event.preventDefault();
                setFocusedIndex(0);
                break;
            case "End":
                event.preventDefault();
                setFocusedIndex(itemCount - 1);
                break;
        }
    }, [isComponentVisible, props.children.length, setIsComponentVisible]);
    return (React.createElement("div", { className: "relative inline-block text-left", onKeyDown: handleKeyDown },
        !props.elementToBeShownInsteadOfButton && (React.createElement(Button, { id: buttonId, icon: props.menuIcon || IconProp.More, title: props.text || "", buttonStyle: ButtonStyleType.OUTLINE, onClick: () => {
                setIsComponentVisible(!isDropdownVisible);
            }, ariaLabel: props.text || "More options", ariaExpanded: isComponentVisible, ariaHaspopup: "menu", ariaControls: isComponentVisible ? menuId : undefined })),
        props.elementToBeShownInsteadOfButton && (React.createElement("div", { onClick: () => {
                setIsComponentVisible(!isDropdownVisible);
            }, role: "button", tabIndex: 0, onKeyDown: (e) => {
                if (e.key === "Enter" || e.key === " ") {
                    setIsComponentVisible(!isDropdownVisible);
                }
            } }, props.elementToBeShownInsteadOfButton)),
        isComponentVisible && (React.createElement("div", { ref: ref, id: menuId, className: "absolute right-0 z-10 mt-2 w-56 origin-top-right rounded-lg bg-white shadow-xl ring-1 ring-gray-200 focus:outline-none py-1", role: "menu", "aria-orientation": "vertical", "aria-labelledby": buttonId }, props.children.map((child, index) => {
            return (React.createElement("div", { key: index, ref: (el) => {
                    menuItemRefs.current[index] = el;
                }, role: "menuitem", tabIndex: focusedIndex === index ? 0 : -1, onClick: () => {
                    if (isComponentVisible) {
                        setIsComponentVisible(false);
                    }
                }, onKeyDown: (e) => {
                    if (e.key === "Enter" || e.key === " ") {
                        e.preventDefault();
                        setIsComponentVisible(false);
                        // Trigger child click
                        const clickEvent = new MouseEvent("click", {
                            bubbles: true,
                        });
                        e.currentTarget.dispatchEvent(clickEvent);
                    }
                } }, child));
        })))));
});
MoreMenu.displayName = "MoreMenu";
export default MoreMenu;
//# sourceMappingURL=MoreMenu.js.map