/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e634e55 | Cube Dev Team */
import { mergeProps as mergeProps$1 } from "../../../utils/react/mergeProps.js";
import { useEvent } from "../../../_internal/hooks/use-event.js";
import { ItemActionProvider } from "../../actions/ItemActionContext.js";
import { ItemAction } from "../../actions/ItemAction/ItemAction.js";
import { CloseIcon } from "../../../icons/CloseIcon.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 { TabContainer, TabElement } from "./styled.js";
import { EditableTitle } from "./EditableTitle.js";
import { TabDropIndicator } from "./TabDropIndicator.js";
import { useTabsContext } from "./TabsContext.js";
import { RADIO_SIZE_MAP } from "./types.js";
import { Children, cloneElement, isValidElement, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
import { useDraggableItem, useFocus, useFocusVisible, useHover, useTab } from "react-aria";

//#region src/components/navigation/Tabs/TabButton.tsx
const ACTIONS_EVENT_HANDLERS = {
	onClick: (e) => e.stopPropagation(),
	onPointerDown: (e) => e.stopPropagation(),
	onPointerUp: (e) => e.stopPropagation(),
	onMouseDown: (e) => e.stopPropagation(),
	onMouseUp: (e) => e.stopPropagation(),
	onKeyDown: (e) => {
		if (e.key === "Enter" || e.key === " ") e.stopPropagation();
	}
};
/**
* Extracts the raw key from a React element, stripping the ".$" prefix
* that React adds via Children.map/toArray.
*/
function getRawKey(element) {
	if (element.key == null) return null;
	const keyStr = String(element.key);
	return keyStr.startsWith(".$") ? keyStr.slice(2) : keyStr;
}
/**
* Process menu items for predefined action keys (rename, delete).
* Auto-adds labels and disables items when requirements aren't met.
*/
function processMenuItems(children, effectiveIsEditable, isDeletable) {
	return Children.toArray(children).map((child) => {
		if (!isValidElement(child)) return child;
		const childKey = getRawKey(child);
		const childProps = child.props;
		if (childKey === "rename") return cloneElement(child, {
			children: childProps.children ?? "Rename",
			isDisabled: childProps.isDisabled ?? !effectiveIsEditable
		});
		if (childKey === "delete") return cloneElement(child, {
			children: childProps.children ?? "Delete",
			theme: childProps.theme ?? "danger",
			isDisabled: childProps.isDisabled ?? !isDeletable
		});
		if (childProps.children && typeof childProps.children !== "string") return cloneElement(child, { children: processMenuItems(childProps.children, effectiveIsEditable, isDeletable) });
		return child;
	});
}
/**
* Check if menu children is empty (null, undefined, or empty fragment)
*/
function isMenuEmpty(menu) {
	if (menu === null || menu === void 0) return true;
	return Children.toArray(menu).length === 0;
}
/**
* Individual tab button component.
*
* Uses TabsContext to access shared props, dramatically reducing prop drilling.
* Handles:
* - Tab selection and keyboard navigation
* - Inline title editing
* - Menu and context menu
* - Drag-and-drop reordering
* - Focus and hover states
*/
function TabButton({ item, tabData, isLastTab }) {
	const { state, type, size, autoHideActions: parentAutoHideActions, isEditable: parentIsEditable, menu: parentMenu, menuTriggerProps: parentMenuTriggerProps, menuProps: parentMenuProps, contextMenu: parentContextMenu, onAction: parentOnAction, onDelete, dragState, dropState, editingKey, editValue, setEditValue, startEditing, submitEditing, cancelEditing } = useTabsContext();
	const ref = useRef(null);
	const containerRef = useRef(null);
	const actionsRef = useRef(null);
	const { tabProps } = useTab({ key: item.key }, state, ref);
	const [actionsWidth, setActionsWidth] = useState(0);
	const isDraggable = !!dragState && !!dropState;
	const mockDragState = useMemo(() => ({
		collection: state.collection,
		selectionManager: state.selectionManager,
		isDragging: () => false,
		getKeysForDrag: () => /* @__PURE__ */ new Set(),
		isDisabled: false,
		startDrag: () => {},
		endDrag: () => {}
	}), [state.collection, state.selectionManager]);
	const dragResult = useDraggableItem({ key: item.key }, dragState ?? mockDragState);
	const effectiveDragProps = isDraggable ? dragResult.dragProps : {};
	const isDragging = isDraggable && dragResult.isDragging;
	const [isMenuOpen, setIsMenuOpen] = useState(false);
	const { hoverProps, isHovered } = useHover({});
	const [isFocused, setIsFocused] = useState(false);
	const { focusProps } = useFocus({ onFocusChange: setIsFocused });
	const { isFocusVisible } = useFocusVisible();
	const [suppressFocusVisible, setSuppressFocusVisible] = useState(false);
	const effectiveFocusVisible = isFocusVisible && !suppressFocusVisible;
	const isActive = state.selectedKey === item.key;
	const isDisabled = state.disabledKeys.has(item.key);
	const isDeletable = !!onDelete;
	const isEditing = editingKey === item.key;
	const effectiveIsEditable = tabData.isEditable ?? parentIsEditable ?? false;
	const effectiveMenu = tabData.menu === null ? null : tabData.menu ?? parentMenu;
	const effectiveMenuTriggerProps = {
		...parentMenuTriggerProps,
		...tabData.menuTriggerProps
	};
	const effectiveMenuProps = {
		...parentMenuProps,
		...tabData.menuProps
	};
	const effectiveContextMenu = tabData.contextMenu ?? parentContextMenu ?? false;
	const effectiveType = tabData.type ?? type ?? "default";
	const showDeleteButton = isDeletable && isMenuEmpty(effectiveMenu);
	const processedMenu = effectiveMenu && !isMenuEmpty(effectiveMenu) ? processMenuItems(effectiveMenu, effectiveIsEditable, isDeletable) : null;
	const itemKeyStr = String(item.key);
	const handleDelete = useEvent(() => {
		onDelete?.(itemKeyStr);
	});
	const handleStartEditing = useEvent(() => {
		if (!effectiveIsEditable || isDisabled) return;
		startEditing(itemKeyStr, typeof tabData.title === "string" ? tabData.title : itemKeyStr);
	});
	const handleSubmitEditing = useEvent(() => {
		submitEditing(itemKeyStr, editValue, tabData.onTitleChange);
		setSuppressFocusVisible(true);
		requestAnimationFrame(() => {
			ref.current?.focus();
		});
	});
	const handleCancelEditing = useEvent(() => {
		cancelEditing();
		setSuppressFocusVisible(true);
		requestAnimationFrame(() => {
			ref.current?.focus();
		});
	});
	const handleEditValueChange = useEvent((value) => {
		setEditValue(value);
	});
	const handleMenuAction = useEvent((action) => {
		const actionStr = String(action);
		const normalizedAction = actionStr.startsWith(".$") ? actionStr.slice(2) : actionStr;
		if (normalizedAction === "rename" && effectiveIsEditable) handleStartEditing();
		if (normalizedAction === "delete" && isDeletable) onDelete?.(itemKeyStr);
		tabData.onAction?.(normalizedAction);
		parentOnAction?.(normalizedAction, itemKeyStr);
	});
	const handleKeyDown = useEvent((e) => {
		if (suppressFocusVisible) setSuppressFocusVisible(false);
		if (e.key === "F2" && effectiveIsEditable && !isDisabled) {
			e.preventDefault();
			e.stopPropagation();
			handleStartEditing();
		}
		if (e.key === "F10" && e.shiftKey && processedMenu) {
			e.preventDefault();
			e.stopPropagation();
			setIsMenuOpen(true);
		}
		if ((e.key === "Delete" || e.key === "Backspace") && isDeletable && !isEditing) {
			e.preventDefault();
			onDelete?.(itemKeyStr);
		}
	});
	const mods = useMemo(() => ({
		type: effectiveType,
		active: isActive,
		deletable: isDeletable,
		disabled: isDisabled,
		editing: isEditing,
		hovered: isHovered,
		focused: isFocused,
		"focus-visible": effectiveFocusVisible,
		draggable: isDraggable,
		dragging: isDragging
	}), [
		effectiveType,
		isActive,
		isDeletable,
		isDisabled,
		isEditing,
		isHovered,
		isFocused,
		effectiveFocusVisible,
		isDraggable,
		isDragging
	]);
	useEffect(() => {
		if (ref.current && isActive) ref.current.scrollIntoView?.({
			block: "nearest",
			inline: "nearest"
		});
	}, [isActive]);
	const menuElement = processedMenu ? /* @__PURE__ */ jsx(__Menu, {
		...effectiveMenuProps,
		onAction: handleMenuAction,
		children: processedMenu
	}) : null;
	const contextMenu = useContextMenu(__Menu, { placement: "bottom start" }, {
		...effectiveMenuProps,
		onAction: handleMenuAction,
		children: processedMenu
	});
	const menuAction = menuElement ? /* @__PURE__ */ jsxs(_MenuTrigger, {
		isOpen: isMenuOpen,
		onOpenChange: setIsMenuOpen,
		children: [/* @__PURE__ */ jsx(ItemAction, {
			tabIndex: -1,
			icon: /* @__PURE__ */ jsx(MoreIcon, {}),
			...effectiveMenuTriggerProps
		}), menuElement]
	}) : null;
	const deleteAction = showDeleteButton ? /* @__PURE__ */ jsx(ItemAction, {
		tabIndex: -1,
		icon: /* @__PURE__ */ jsx(CloseIcon, {}),
		tooltip: "Close",
		onPress: handleDelete
	}) : null;
	const actions = tabData.actions || menuAction || deleteAction ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
		tabData.actions,
		menuAction,
		deleteAction
	] }) : void 0;
	useLayoutEffect(() => {
		if (actions && actionsRef.current) setActionsWidth(Math.round(actionsRef.current.offsetWidth));
	}, [actions]);
	const effectiveSize = tabData.size ?? size ?? "medium";
	const itemSize = effectiveType === "radio" ? RADIO_SIZE_MAP[effectiveSize === "large" ? "large" : "medium"] : effectiveSize;
	const itemType = effectiveType === "default" ? isActive ? "clear" : "neutral" : "neutral";
	const itemShape = effectiveType === "file" ? "sharp" : void 0;
	const effectiveAutoHideActions = tabData.autoHideActions ?? parentAutoHideActions;
	const titleContent = effectiveIsEditable ? /* @__PURE__ */ jsx(EditableTitle, {
		title: tabData.title,
		isEditing,
		editValue: isEditing ? editValue : "",
		onEditValueChange: handleEditValueChange,
		onStartEditing: handleStartEditing,
		onSubmit: handleSubmitEditing,
		onCancel: handleCancelEditing
	}) : tabData.title;
	const { title: _title, content: _content, key: _key, isDisabled: _isDisabled, prerender: _prerender, keepMounted: _keepMounted, size: _size, type: _type, actions: _actions, autoHideActions: _autoHideActions, isEditable: _isEditable, onTitleChange: _onTitleChange, menu: _menu, menuTriggerProps: _menuTriggerProps, menuProps: _menuProps, contextMenu: _contextMenu, onAction: _onAction, qa, qaVal, styles, ...itemStyleProps } = tabData;
	const effectiveContainerRef = effectiveContextMenu && processedMenu ? contextMenu.targetRef : containerRef;
	const ariaProps = processedMenu ? { "aria-haspopup": "menu" } : {};
	const containerMods = {
		...mods,
		"auto-hide-actions": effectiveAutoHideActions
	};
	return /* @__PURE__ */ jsxs(TabContainer, {
		ref: effectiveContainerRef,
		"data-size": itemSize,
		mods: containerMods,
		tokens: { "$actions-width": `${actionsWidth}px` },
		...effectiveDragProps,
		children: [
			isDraggable && dropState && /* @__PURE__ */ jsx(TabDropIndicator, {
				target: {
					type: "item",
					key: item.key,
					dropPosition: "before"
				},
				dropState,
				position: "before"
			}),
			/* @__PURE__ */ jsx(TabElement, {
				preserveActionsSpace: true,
				autoHideActions: effectiveAutoHideActions,
				as: "button",
				...mergeProps$1(tabProps, hoverProps, focusProps, { onKeyDown: handleKeyDown }),
				...ariaProps,
				...itemStyleProps,
				ref,
				qa: qa ?? `Tab-${String(item.key)}`,
				qaVal,
				styles,
				mods,
				isSelected: isActive,
				isDisabled,
				size: itemSize,
				type: itemType,
				shape: itemShape,
				actions: actions ? true : void 0,
				children: titleContent
			}),
			actions && /* @__PURE__ */ jsx("div", {
				ref: actionsRef,
				"data-element": "Actions",
				...ACTIONS_EVENT_HANDLERS,
				children: /* @__PURE__ */ jsx(ItemActionProvider, {
					type: itemType,
					theme: "default",
					isDisabled,
					children: actions
				})
			}),
			effectiveContextMenu && processedMenu && contextMenu.rendered,
			isDraggable && dropState && isLastTab && /* @__PURE__ */ jsx(TabDropIndicator, {
				target: {
					type: "item",
					key: item.key,
					dropPosition: "after"
				},
				dropState,
				position: "after"
			})
		]
	});
}

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