/** @license MIT | @cube-dev/ui-kit v0.142.7 | Cube Dev Team */
import { mergeProps as mergeProps$1 } from "../../../utils/react/mergeProps.js";
import { mergeRefs } from "../../../utils/react/useCombinedRefs.js";
import { useEvent } from "../../../_internal/hooks/use-event.js";
import { LoadingIcon } from "../../../icons/LoadingIcon.js";
import { ItemAction } from "../../actions/ItemAction/ItemAction.js";
import { DirectionIcon } from "../../../icons/DirectionIcon.js";
import { MoreIcon } from "../../../icons/MoreIcon.js";
import { _MenuTrigger } from "../../actions/Menu/MenuTrigger.js";
import { __Menu } from "../../actions/Menu/Menu.js";
import { useContextMenu } from "../../actions/use-context-menu.js";
import { TreeNodeCheckboxWrapper, TreeNodeRow, TreeNodeToggle, TreeNodeTogglePlaceholder, TreeRowItem } from "./styled.js";
import { __Checkbox } from "../../fields/Checkbox/Checkbox.js";
import { Children, memo, useMemo, useRef, useState } from "react";
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
import { useHover, useTreeItem } from "react-aria";

//#region src/components/content/Tree/TreeNode.tsx
const stopPropagation = (e) => {
	e.stopPropagation();
};
/** Check whether a `menu` ReactNode actually contains anything. */
function isMenuEmpty(menu) {
	if (menu === null || menu === void 0 || menu === false) return true;
	return Children.toArray(menu).length === 0;
}
function TreeNodeInner(props) {
	const { node, data, state, isCheckable, isExpanded, isIndeterminate, isChecked, isLoading, onToggleChecked, size, itemProps, rowStyles, virtualStyle, virtualRef, virtualIndex, menu: treeMenu, contextMenu: treeContextMenu, onAction: treeOnAction, menuTriggerProps, menuProps } = props;
	const rowRef = useRef(null);
	const { rowProps, gridCellProps, expandButtonProps, isPressed } = useTreeItem({ node }, state, rowRef);
	const isDisabled = state.disabledKeys.has(node.key);
	const isSelected = state.selectionManager.isSelected(node.key);
	const { hoverProps, isHovered } = useHover({ isDisabled });
	const isFocused = state.selectionManager.isFocused && state.selectionManager.focusedKey === node.key;
	const isLeaf = data.isLeaf === true || data.isLeaf !== false && !node.hasChildNodes;
	const isRowCheckable = isCheckable && data.isCheckable !== false;
	const nodeState = {
		isExpanded,
		isSelected,
		isChecked,
		isIndeterminate,
		isLeaf
	};
	const effectiveMenuChildren = data.menu === null ? null : data.menu !== void 0 ? data.menu : typeof treeMenu === "function" ? treeMenu(data, nodeState) : treeMenu ?? null;
	const hasMenu = !isMenuEmpty(effectiveMenuChildren);
	const effectiveContextMenu = data.contextMenu ?? treeContextMenu ?? false;
	const menuExposed = hasMenu && (effectiveContextMenu === true || effectiveContextMenu === "context-only");
	const contextMenuOnly = effectiveContextMenu === "context-only";
	const [isMenuOpen, setIsMenuOpen] = useState(false);
	const handleMenuAction = useEvent((action) => {
		const actionStr = String(action);
		const normalizedAction = actionStr.startsWith(".$") ? actionStr.slice(2) : actionStr;
		data.onAction?.(normalizedAction);
		treeOnAction?.(normalizedAction, node.key);
		menuProps?.onAction?.(normalizedAction);
	});
	const rowContextMenu = useContextMenu(__Menu, { placement: "bottom start" }, {
		...menuProps,
		onAction: handleMenuAction,
		children: effectiveMenuChildren
	});
	const handleCheckboxChange = useEvent(() => {
		onToggleChecked(String(node.key));
	});
	const handleKeyDown = useEvent((e) => {
		if (e.key === " " && isRowCheckable && !isDisabled && !data.isCheckboxDisabled) {
			e.preventDefault();
			onToggleChecked(String(node.key));
			return false;
		}
		if (e.key === "F10" && e.shiftKey && menuExposed) {
			e.preventDefault();
			e.stopPropagation();
			if (contextMenuOnly) rowContextMenu.open();
			else setIsMenuOpen(true);
			return true;
		}
		return false;
	});
	const composedKeyDown = useEvent((e) => {
		if (handleKeyDown(e)) return;
		rowProps.onKeyDown?.(e);
	});
	const sharedMods = useMemo(() => ({
		checked: isChecked,
		indeterminate: isIndeterminate,
		expanded: isExpanded,
		loading: isLoading,
		leaf: isLeaf,
		"has-checkbox": isRowCheckable,
		"has-menu": menuExposed
	}), [
		isChecked,
		isIndeterminate,
		isExpanded,
		isLoading,
		isLeaf,
		isRowCheckable,
		menuExposed
	]);
	const rowMods = useMemo(() => ({
		...sharedMods,
		disabled: isDisabled
	}), [sharedMods, isDisabled]);
	const itemMods = useMemo(() => ({
		...sharedMods,
		focused: isFocused,
		hovered: isHovered,
		pressed: isPressed
	}), [
		sharedMods,
		isFocused,
		isHovered,
		isPressed
	]);
	const rowStyle = useMemo(() => ({
		["--tree-level"]: String(node.level ?? 0),
		...virtualStyle
	}), [node.level, virtualStyle]);
	const ariaChecked = isRowCheckable ? isIndeterminate ? "mixed" : isChecked ? "true" : "false" : void 0;
	const finalRowProps = {
		...mergeProps$1(rowProps, hoverProps),
		"aria-checked": ariaChecked,
		onKeyDown: composedKeyDown
	};
	const toggleNode = isLeaf ? /* @__PURE__ */ jsx(TreeNodeTogglePlaceholder, {
		"aria-hidden": true,
		"data-element": "Toggle"
	}) : /* @__PURE__ */ jsx(TreeNodeToggle, {
		...expandButtonProps,
		tabIndex: -1,
		"data-element": "Toggle",
		children: isLoading ? /* @__PURE__ */ jsx(LoadingIcon, {}) : /* @__PURE__ */ jsx(DirectionIcon, { to: isExpanded ? "bottom" : "right" })
	});
	const checkboxNode = isRowCheckable ? /* @__PURE__ */ jsx(TreeNodeCheckboxWrapper, {
		"data-element": "Checkbox",
		role: "presentation",
		onClick: stopPropagation,
		onKeyDown: stopPropagation,
		children: /* @__PURE__ */ jsx(__Checkbox, {
			isSelected: isChecked,
			isIndeterminate,
			isDisabled: isDisabled || data.isCheckboxDisabled,
			"aria-label": typeof data.title === "string" ? data.title : String(node.key),
			onChange: handleCheckboxChange
		})
	}) : null;
	const { prefix: userPrefix, actions: userActions, ...restUserProps } = (typeof itemProps === "function" ? itemProps(data, nodeState) : itemProps) ?? {};
	const composedPrefix = checkboxNode || userPrefix ? /* @__PURE__ */ jsxs(Fragment$1, { children: [checkboxNode, userPrefix] }) : null;
	const menuAction = menuExposed && !contextMenuOnly ? /* @__PURE__ */ jsxs(_MenuTrigger, {
		isOpen: isMenuOpen,
		onOpenChange: setIsMenuOpen,
		children: [/* @__PURE__ */ jsx(ItemAction, {
			tabIndex: -1,
			icon: /* @__PURE__ */ jsx(MoreIcon, {}),
			"aria-label": "Actions",
			...menuTriggerProps
		}), /* @__PURE__ */ jsx(__Menu, {
			...menuProps,
			onAction: handleMenuAction,
			children: effectiveMenuChildren
		})]
	}) : null;
	const composedActions = userActions || menuAction ? /* @__PURE__ */ jsxs(Fragment$1, { children: [userActions, menuAction] }) : void 0;
	const refs = useMemo(() => {
		const list = [rowRef];
		if (virtualRef) list.push(virtualRef);
		if (menuExposed) list.push(rowContextMenu.targetRef);
		return mergeRefs(...list);
	}, [
		virtualRef,
		menuExposed,
		rowContextMenu.targetRef
	]);
	return /* @__PURE__ */ jsxs(TreeNodeRow, {
		...finalRowProps,
		ref: refs,
		mods: rowMods,
		style: rowStyle,
		"data-element": "Row",
		"data-qa-key": String(node.key),
		"data-index": virtualIndex,
		children: [/* @__PURE__ */ jsx(TreeRowItem, {
			...gridCellProps,
			...restUserProps,
			size,
			isSelected,
			isDisabled,
			mods: itemMods,
			icon: toggleNode,
			prefix: composedPrefix,
			actions: composedActions,
			styles: rowStyles,
			children: data.title
		}), menuExposed && rowContextMenu.rendered]
	});
}
const TreeNode = memo(TreeNodeInner);

//#endregion
export { TreeNode };
//# sourceMappingURL=TreeNode.js.map