import { jsx } from 'react/jsx-runtime';
import { useState, useRef, useId, useCallback } from 'react';
import { cn } from '../../../utils/cn.js';
import { DropdownContext } from './DropdownContext.js';
import { DropdownTrigger } from './DropdownTrigger.js';
import { DropdownMenu } from './DropdownMenu.js';
import { DropdownItem } from './DropdownItem.js';
import { DropdownSection } from './DropdownSection.js';
import { DropdownSeparator } from './DropdownSeparator.js';
import { dropdownTheme } from './Dropdown.theme.js';

/**
 * Dropdown component for displaying action menus
 *
 * @component
 * @example
 * ```tsx
 * <Dropdown>
 *   <Dropdown.Trigger>
 *     <Button>Actions</Button>
 *   </Dropdown.Trigger>
 *   <Dropdown.Menu>
 *     <Dropdown.Item key="edit">Edit</Dropdown.Item>
 *     <Dropdown.Item key="delete" isDanger>Delete</Dropdown.Item>
 *   </Dropdown.Menu>
 * </Dropdown>
 * ```
 */
const DropdownRoot = ({ children, className, isOpen: controlledIsOpen, defaultIsOpen = false, onOpenChange, placement = "bottom-start", offset = 4, closeOnSelect = true, disabledKeys = [], selectedKeys: controlledSelectedKeys, defaultSelectedKeys = [], selectionMode = "none", onAction, onSelectionChange, theme: themeOverrides, darkMode = false, ...props }) => {
    // State for uncontrolled open
    const [uncontrolledIsOpen, setUncontrolledIsOpen] = useState(defaultIsOpen);
    // State for uncontrolled selection
    const [uncontrolledSelectedKeys, setUncontrolledSelectedKeys] = useState(new Set(defaultSelectedKeys));
    // Determine if controlled or uncontrolled
    const isControlledOpen = controlledIsOpen !== undefined;
    const isOpen = isControlledOpen ? controlledIsOpen : uncontrolledIsOpen;
    const isControlledSelection = controlledSelectedKeys !== undefined;
    const selectedKeys = isControlledSelection
        ? new Set(controlledSelectedKeys)
        : uncontrolledSelectedKeys;
    // Refs for positioning
    const triggerRef = useRef(null);
    const menuRef = useRef(null);
    // Generate a stable menu ID for aria-controls
    const generatedMenuId = useId();
    const menuId = `dropdown-menu-${generatedMenuId}`;
    // Handle open state changes
    const handleOpenChange = useCallback((value) => {
        if (!isControlledOpen) {
            setUncontrolledIsOpen(value);
        }
        onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(value);
    }, [isControlledOpen, onOpenChange]);
    // Handle selection changes
    const handleSelectionChange = useCallback((keys) => {
        if (!isControlledSelection) {
            setUncontrolledSelectedKeys(keys);
        }
        onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange(Array.from(keys));
    }, [isControlledSelection, onSelectionChange]);
    // Merge theme with overrides
    const theme = {
        ...dropdownTheme,
        ...(themeOverrides || {}),
    };
    // Convert disabled keys array to Set
    const disabledKeysSet = new Set(disabledKeys);
    // Context value
    const contextValue = {
        isOpen,
        onOpenChange: handleOpenChange,
        triggerRef,
        menuRef,
        menuId,
        placement,
        offset,
        closeOnSelect,
        disabledKeys: disabledKeysSet,
        selectedKeys,
        selectionMode,
        onAction,
        onSelectionChange: handleSelectionChange,
        theme,
    };
    return (jsx(DropdownContext.Provider, { value: contextValue, children: jsx("div", { className: cn("dropdown", darkMode && "dark", className), "data-state": isOpen ? "open" : "closed", ...props, children: children }) }));
};
DropdownRoot.displayName = "Dropdown";
// Export as a unified component with sub-components
const Dropdown = Object.assign(DropdownRoot, {
    Trigger: DropdownTrigger,
    Menu: DropdownMenu,
    Item: DropdownItem,
    Section: DropdownSection,
    Separator: DropdownSeparator,
});

export { Dropdown };
