"use client";
const require_use_uncontrolled = require("../use-uncontrolled/use-uncontrolled.cjs");
let react = require("react");
//#region packages/@mantine/hooks/src/use-roving-index/use-roving-index.ts
function findNextEnabled(current, total, isItemDisabled, loop) {
	for (let i = current + 1; i < total; i += 1) if (!isItemDisabled(i)) return i;
	if (loop) {
		for (let i = 0; i < current; i += 1) if (!isItemDisabled(i)) return i;
	}
	return current;
}
function findPreviousEnabled(current, total, isItemDisabled, loop) {
	for (let i = current - 1; i >= 0; i -= 1) if (!isItemDisabled(i)) return i;
	if (loop) {
		for (let i = total - 1; i > current; i -= 1) if (!isItemDisabled(i)) return i;
	}
	return current;
}
function findFirstEnabled(total, isItemDisabled) {
	for (let i = 0; i < total; i += 1) if (!isItemDisabled(i)) return i;
	return 0;
}
function findLastEnabled(total, isItemDisabled) {
	for (let i = total - 1; i >= 0; i -= 1) if (!isItemDisabled(i)) return i;
	return 0;
}
const defaultIsItemDisabled = () => false;
function useRovingIndex(input) {
	const { total, orientation = "horizontal", loop = true, dir = "ltr", activateOnFocus = false, columns, focusedIndex, initialIndex, onFocusChange, isItemDisabled = defaultIsItemDisabled } = input;
	const itemRefs = (0, react.useRef)(/* @__PURE__ */ new Map());
	const isGrid = typeof columns === "number" && columns > 0;
	const [activeIndex, setActiveIndex] = require_use_uncontrolled.useUncontrolled({
		value: focusedIndex,
		defaultValue: initialIndex !== void 0 ? initialIndex : findFirstEnabled(total, isItemDisabled),
		finalValue: 0,
		onChange: onFocusChange
	});
	(0, react.useEffect)(() => {
		if (total === 0) return;
		if (activeIndex >= total) setActiveIndex(findLastEnabled(total, isItemDisabled));
		else if (isItemDisabled(activeIndex)) setActiveIndex(findFirstEnabled(total, isItemDisabled));
	}, [
		total,
		activeIndex,
		isItemDisabled
	]);
	const focusItem = (0, react.useCallback)((index) => {
		setActiveIndex(index);
		const element = itemRefs.current.get(index);
		if (element) {
			element.focus();
			if (activateOnFocus) element.click();
		}
	}, [activateOnFocus, setActiveIndex]);
	const handleGridKeyDown = (0, react.useCallback)((event, currentIndex) => {
		const row = Math.floor(currentIndex / columns);
		const col = currentIndex % columns;
		const totalRows = Math.ceil(total / columns);
		let nextIndex = null;
		const isRtl = dir === "rtl";
		switch (event.key) {
			case "ArrowRight": {
				const targetCol = isRtl ? col - 1 : col + 1;
				if (targetCol >= 0 && targetCol < columns && row * columns + targetCol < total) {
					const candidate = row * columns + targetCol;
					if (!isItemDisabled(candidate)) nextIndex = candidate;
				}
				break;
			}
			case "ArrowLeft": {
				const targetCol = isRtl ? col + 1 : col - 1;
				if (targetCol >= 0 && targetCol < columns && row * columns + targetCol < total) {
					const candidate = row * columns + targetCol;
					if (!isItemDisabled(candidate)) nextIndex = candidate;
				}
				break;
			}
			case "ArrowDown":
				for (let r = row + 1; r < totalRows; r += 1) {
					const candidate = r * columns + col;
					if (candidate < total && !isItemDisabled(candidate)) {
						nextIndex = candidate;
						break;
					}
				}
				break;
			case "ArrowUp":
				for (let r = row - 1; r >= 0; r -= 1) {
					const candidate = r * columns + col;
					if (candidate < total && !isItemDisabled(candidate)) {
						nextIndex = candidate;
						break;
					}
				}
				break;
			case "Home":
				if (event.ctrlKey) nextIndex = findFirstEnabled(total, isItemDisabled);
				else {
					const rowStart = row * columns;
					for (let i = rowStart; i < rowStart + columns && i < total; i += 1) if (!isItemDisabled(i)) {
						nextIndex = i;
						break;
					}
				}
				break;
			case "End":
				if (event.ctrlKey) nextIndex = findLastEnabled(total, isItemDisabled);
				else {
					const rowStart = row * columns;
					const rowEnd = Math.min(rowStart + columns, total) - 1;
					for (let i = rowEnd; i >= rowStart; i -= 1) if (!isItemDisabled(i)) {
						nextIndex = i;
						break;
					}
				}
				break;
		}
		if (nextIndex !== null && nextIndex !== currentIndex) {
			event.preventDefault();
			event.stopPropagation();
			focusItem(nextIndex);
		}
	}, [
		total,
		columns,
		dir,
		isItemDisabled,
		focusItem
	]);
	const handleListKeyDown = (0, react.useCallback)((event, currentIndex) => {
		const isRtl = dir === "rtl";
		let nextIndex = null;
		switch (event.key) {
			case "ArrowRight":
				if (orientation === "horizontal" || orientation === "both") nextIndex = isRtl ? findPreviousEnabled(currentIndex, total, isItemDisabled, loop) : findNextEnabled(currentIndex, total, isItemDisabled, loop);
				break;
			case "ArrowLeft":
				if (orientation === "horizontal" || orientation === "both") nextIndex = isRtl ? findNextEnabled(currentIndex, total, isItemDisabled, loop) : findPreviousEnabled(currentIndex, total, isItemDisabled, loop);
				break;
			case "ArrowDown":
				if (orientation === "vertical" || orientation === "both") nextIndex = findNextEnabled(currentIndex, total, isItemDisabled, loop);
				break;
			case "ArrowUp":
				if (orientation === "vertical" || orientation === "both") nextIndex = findPreviousEnabled(currentIndex, total, isItemDisabled, loop);
				break;
			case "Home":
				nextIndex = findFirstEnabled(total, isItemDisabled);
				break;
			case "End":
				nextIndex = findLastEnabled(total, isItemDisabled);
				break;
		}
		if (nextIndex !== null && nextIndex !== currentIndex) {
			event.preventDefault();
			event.stopPropagation();
			focusItem(nextIndex);
		}
	}, [
		total,
		orientation,
		loop,
		dir,
		isItemDisabled,
		focusItem
	]);
	return {
		getItemProps: (0, react.useCallback)((options) => {
			const { index, onClick, onKeyDown } = options;
			return {
				tabIndex: index === activeIndex ? 0 : -1,
				ref: (node) => {
					if (node) itemRefs.current.set(index, node);
					else itemRefs.current.delete(index);
				},
				onKeyDown: (event) => {
					onKeyDown?.(event);
					if (event.defaultPrevented) return;
					if (isGrid) handleGridKeyDown(event, index);
					else handleListKeyDown(event, index);
				},
				onClick: (event) => {
					onClick?.(event);
					setActiveIndex(index);
				}
			};
		}, [
			activeIndex,
			isGrid,
			handleGridKeyDown,
			handleListKeyDown,
			setActiveIndex
		]),
		focusedIndex: activeIndex,
		setFocusedIndex: setActiveIndex
	};
}
//#endregion
exports.useRovingIndex = useRovingIndex;

//# sourceMappingURL=use-roving-index.cjs.map