"use client";
const require_use_uncontrolled = require("../use-uncontrolled/use-uncontrolled.cjs");
let react = require("react");
//#region packages/@mantine/hooks/src/use-splitter/use-splitter.ts
function clamp(value, min, max) {
	return Math.min(Math.max(value, min), max);
}
function getMin(panel) {
	return panel.min ?? 0;
}
function getMax(panel) {
	return panel.max ?? 100;
}
function getCollapseThreshold(panel) {
	return panel.collapseThreshold ?? getMin(panel);
}
function createInitialInternalState() {
	return {
		isDragging: false,
		handleIndex: -1,
		startPointer: 0,
		containerSize: 0,
		startSizes: [],
		preCollapseSizes: []
	};
}
function checkCollapse(sizes, panels, handleIndex, delta) {
	const beforeIdx = handleIndex;
	const afterIdx = handleIndex + 1;
	const beforePanel = panels[beforeIdx];
	const afterPanel = panels[afterIdx];
	const rawBefore = sizes[beforeIdx] + delta;
	const rawAfter = sizes[afterIdx] - delta;
	if (beforePanel.collapsible && rawBefore < getCollapseThreshold(beforePanel) && rawBefore < sizes[beforeIdx]) {
		const result = [...sizes];
		result[afterIdx] += result[beforeIdx];
		result[beforeIdx] = 0;
		return result;
	}
	if (afterPanel.collapsible && rawAfter < getCollapseThreshold(afterPanel) && rawAfter < sizes[afterIdx]) {
		const result = [...sizes];
		result[beforeIdx] += result[afterIdx];
		result[afterIdx] = 0;
		return result;
	}
	return null;
}
function applyAdjacentOnly(sizes, panels, handleIndex, delta) {
	const result = [...sizes];
	const beforeIdx = handleIndex;
	const afterIdx = handleIndex + 1;
	const total = result[beforeIdx] + result[afterIdx];
	const effectiveBeforeMax = Math.min(getMax(panels[beforeIdx]), total - getMin(panels[afterIdx]));
	const effectiveBeforeMin = Math.max(getMin(panels[beforeIdx]), total - getMax(panels[afterIdx]));
	const newBefore = clamp(result[beforeIdx] + delta, effectiveBeforeMin, effectiveBeforeMax);
	result[beforeIdx] = newBefore;
	result[afterIdx] = total - newBefore;
	return result;
}
function redistributeNearest(sizes, panels, handleIndex, delta) {
	const result = [...sizes];
	if (delta > 0) {
		const growIdx = handleIndex;
		const maxGrow = getMax(panels[growIdx]) - result[growIdx];
		const wantedGrow = Math.min(delta, maxGrow);
		let taken = 0;
		for (let i = handleIndex + 1; i < result.length && taken < wantedGrow; i += 1) {
			const canGive = result[i] - getMin(panels[i]);
			const take = Math.min(canGive, wantedGrow - taken);
			result[i] -= take;
			taken += take;
		}
		result[growIdx] += taken;
	} else if (delta < 0) {
		const growIdx = handleIndex + 1;
		const maxGrow = getMax(panels[growIdx]) - result[growIdx];
		const wantedGrow = Math.min(Math.abs(delta), maxGrow);
		let taken = 0;
		for (let i = handleIndex; i >= 0 && taken < wantedGrow; i -= 1) {
			const canGive = result[i] - getMin(panels[i]);
			const take = Math.min(canGive, wantedGrow - taken);
			result[i] -= take;
			taken += take;
		}
		result[growIdx] += taken;
	}
	return result;
}
function redistributeEqual(sizes, panels, handleIndex, delta) {
	const result = [...sizes];
	if (delta > 0) {
		const growIdx = handleIndex;
		const maxGrow = getMax(panels[growIdx]) - result[growIdx];
		const wantedGrow = Math.min(delta, maxGrow);
		const donors = [];
		for (let i = handleIndex + 1; i < result.length; i += 1) if (result[i] > getMin(panels[i])) donors.push(i);
		let remaining = wantedGrow;
		while (remaining > .001 && donors.length > 0) {
			const perDonor = remaining / donors.length;
			const exhausted = [];
			for (let d = 0; d < donors.length; d += 1) {
				const idx = donors[d];
				const canGive = result[idx] - getMin(panels[idx]);
				const take = Math.min(canGive, perDonor);
				result[idx] -= take;
				remaining -= take;
				if (canGive <= perDonor + .001) exhausted.push(d);
			}
			for (let i = exhausted.length - 1; i >= 0; i -= 1) donors.splice(exhausted[i], 1);
			if (exhausted.length === 0) break;
		}
		result[growIdx] += wantedGrow - remaining;
	} else if (delta < 0) {
		const growIdx = handleIndex + 1;
		const maxGrow = getMax(panels[growIdx]) - result[growIdx];
		const wantedGrow = Math.min(Math.abs(delta), maxGrow);
		const donors = [];
		for (let i = handleIndex; i >= 0; i -= 1) if (result[i] > getMin(panels[i])) donors.push(i);
		let remaining = wantedGrow;
		while (remaining > .001 && donors.length > 0) {
			const perDonor = remaining / donors.length;
			const exhausted = [];
			for (let d = 0; d < donors.length; d += 1) {
				const idx = donors[d];
				const canGive = result[idx] - getMin(panels[idx]);
				const take = Math.min(canGive, perDonor);
				result[idx] -= take;
				remaining -= take;
				if (canGive <= perDonor + .001) exhausted.push(d);
			}
			for (let i = exhausted.length - 1; i >= 0; i -= 1) donors.splice(exhausted[i], 1);
			if (exhausted.length === 0) break;
		}
		result[growIdx] += wantedGrow - remaining;
	}
	return result;
}
function applyConstraints(sizes, panels, handleIndex, delta, redistribute) {
	if (typeof redistribute === "function") return redistribute({
		sizes: [...sizes],
		panels,
		handleIndex,
		delta
	});
	if (redistribute === "nearest" || redistribute === "equal") {
		const result = (redistribute === "nearest" ? redistributeNearest : redistributeEqual)(sizes, panels, handleIndex, delta);
		const beforeIdx = handleIndex;
		const afterIdx = handleIndex + 1;
		const beforePanel = panels[beforeIdx];
		const afterPanel = panels[afterIdx];
		if (beforePanel.collapsible && result[beforeIdx] < getCollapseThreshold(beforePanel) && result[beforeIdx] < sizes[beforeIdx]) {
			const freed = result[beforeIdx];
			result[afterIdx] += freed;
			result[beforeIdx] = 0;
		} else if (afterPanel.collapsible && result[afterIdx] < getCollapseThreshold(afterPanel) && result[afterIdx] < sizes[afterIdx]) {
			const freed = result[afterIdx];
			result[beforeIdx] += freed;
			result[afterIdx] = 0;
		}
		return result;
	}
	const collapsed = checkCollapse(sizes, panels, handleIndex, delta);
	if (collapsed) return collapsed;
	return applyAdjacentOnly(sizes, panels, handleIndex, delta);
}
function useSplitter(options) {
	const { panels, orientation = "horizontal", sizes: controlledSizes, onSizeChange, onCollapseChange, redistribute, step = 1, shiftStep = 10, dir = "ltr", enabled = true } = options;
	const defaultSizes = panels.map((p) => p.defaultSize);
	const [currentSizes, setCurrentSizes] = require_use_uncontrolled.useUncontrolled({
		value: controlledSizes,
		defaultValue: defaultSizes,
		finalValue: defaultSizes,
		onChange: onSizeChange
	});
	const [activeHandle, setActiveHandle] = (0, react.useState)(-1);
	const optionsRef = (0, react.useRef)(options);
	optionsRef.current = options;
	const internalStateRef = (0, react.useRef)(createInitialInternalState());
	const containerRef = (0, react.useRef)(null);
	const documentControllerRef = (0, react.useRef)(null);
	const frameRef = (0, react.useRef)(0);
	const currentSizesRef = (0, react.useRef)(currentSizes);
	currentSizesRef.current = currentSizes;
	const preCollapseSizesRef = (0, react.useRef)(defaultSizes);
	const collapsed = currentSizes.map((size) => size === 0);
	const updateSizes = (0, react.useCallback)((newSizes) => {
		currentSizesRef.current = newSizes;
		setCurrentSizes(newSizes);
	}, [setCurrentSizes]);
	const collapsePanel = (0, react.useCallback)((panelIndex) => {
		if (!panels[panelIndex]?.collapsible) return;
		const sizes = currentSizesRef.current;
		if (sizes[panelIndex] === 0) return;
		preCollapseSizesRef.current = [...sizes];
		const newSizes = [...sizes];
		const freedSize = newSizes[panelIndex];
		newSizes[panelIndex] = 0;
		const neighbor = panelIndex === 0 ? 1 : panelIndex - 1;
		newSizes[neighbor] += freedSize;
		updateSizes(newSizes);
		onCollapseChange?.(panelIndex, true);
	}, [
		panels,
		updateSizes,
		onCollapseChange
	]);
	const expandPanel = (0, react.useCallback)((panelIndex) => {
		if (!panels[panelIndex]?.collapsible) return;
		const sizes = currentSizesRef.current;
		if (sizes[panelIndex] !== 0) return;
		const restoreSize = preCollapseSizesRef.current[panelIndex] || panels[panelIndex].defaultSize;
		const newSizes = [...sizes];
		const neighbor = panelIndex === 0 ? 1 : panelIndex - 1;
		const available = Math.max(0, newSizes[neighbor] - getMin(panels[neighbor]));
		const actualRestore = Math.min(restoreSize, available);
		if (actualRestore <= 0) return;
		newSizes[panelIndex] = actualRestore;
		newSizes[neighbor] -= actualRestore;
		updateSizes(newSizes);
		onCollapseChange?.(panelIndex, false);
	}, [
		panels,
		updateSizes,
		onCollapseChange
	]);
	const toggleCollapsePanel = (0, react.useCallback)((panelIndex) => {
		if (currentSizesRef.current[panelIndex] === 0) expandPanel(panelIndex);
		else collapsePanel(panelIndex);
	}, [collapsePanel, expandPanel]);
	const containerRefCallback = (0, react.useCallback)((node) => {
		containerRef.current = node;
	}, []);
	const handleRefCallbacks = (0, react.useRef)(/* @__PURE__ */ new Map());
	const handleElementControllers = (0, react.useRef)(/* @__PURE__ */ new Map());
	const getHandleRefCallback = (0, react.useCallback)((handleIndex) => {
		if (handleRefCallbacks.current.has(handleIndex)) return handleRefCallbacks.current.get(handleIndex);
		const callback = (node) => {
			const existingController = handleElementControllers.current.get(handleIndex);
			if (existingController) {
				existingController.abort();
				handleElementControllers.current.delete(handleIndex);
			}
			if (!node) return;
			const elementController = new AbortController();
			handleElementControllers.current.set(handleIndex, elementController);
			const onPointerDown = (event) => {
				if (optionsRef.current.enabled === false) return;
				if (event.button !== 0) return;
				const container = containerRef.current;
				if (!container) return;
				const rect = container.getBoundingClientRect();
				const isHorizontal = (optionsRef.current.orientation ?? "horizontal") === "horizontal";
				const containerSize = isHorizontal ? rect.width : rect.height;
				const pointerPos = isHorizontal ? event.clientX : event.clientY;
				const s = internalStateRef.current;
				s.isDragging = true;
				s.handleIndex = handleIndex;
				s.startPointer = pointerPos;
				s.containerSize = containerSize;
				s.startSizes = [...currentSizesRef.current];
				s.preCollapseSizes = [...preCollapseSizesRef.current];
				setActiveHandle(handleIndex);
				document.body.style.userSelect = "none";
				document.body.style.webkitUserSelect = "none";
				document.body.style.cursor = isHorizontal ? "col-resize" : "row-resize";
				optionsRef.current.onResizeStart?.(handleIndex);
				documentControllerRef.current?.abort();
				documentControllerRef.current = new AbortController();
				const sig = documentControllerRef.current.signal;
				document.addEventListener("pointermove", onPointerMove, { signal: sig });
				document.addEventListener("pointerup", onPointerUp, { signal: sig });
				document.addEventListener("pointercancel", onPointerUp, { signal: sig });
			};
			const flushResize = (pointerEvent) => {
				const s = internalStateRef.current;
				if (!s.containerSize) return;
				const isHorizontal = (optionsRef.current.orientation ?? "horizontal") === "horizontal";
				const isRtl = isHorizontal && optionsRef.current.dir === "rtl";
				const pixelDelta = (isHorizontal ? pointerEvent.clientX : pointerEvent.clientY) - s.startPointer;
				const percentDelta = (isRtl ? -pixelDelta : pixelDelta) / s.containerSize * 100;
				const opts = optionsRef.current;
				const newSizes = applyConstraints(s.startSizes, opts.panels, s.handleIndex, percentDelta, opts.redistribute);
				const prevSizes = currentSizesRef.current;
				const beforeWasCollapsed = prevSizes[s.handleIndex] === 0;
				const afterWasCollapsed = prevSizes[s.handleIndex + 1] === 0;
				const beforeNowCollapsed = newSizes[s.handleIndex] === 0;
				const afterNowCollapsed = newSizes[s.handleIndex + 1] === 0;
				if (!beforeWasCollapsed && beforeNowCollapsed) {
					preCollapseSizesRef.current = [...s.startSizes];
					opts.onCollapseChange?.(s.handleIndex, true);
				} else if (beforeWasCollapsed && !beforeNowCollapsed) opts.onCollapseChange?.(s.handleIndex, false);
				if (!afterWasCollapsed && afterNowCollapsed) {
					preCollapseSizesRef.current = [...s.startSizes];
					opts.onCollapseChange?.(s.handleIndex + 1, true);
				} else if (afterWasCollapsed && !afterNowCollapsed) opts.onCollapseChange?.(s.handleIndex + 1, false);
				currentSizesRef.current = newSizes;
				setCurrentSizes(newSizes);
			};
			const onPointerMove = (event) => {
				if (!internalStateRef.current.isDragging) return;
				cancelAnimationFrame(frameRef.current);
				frameRef.current = requestAnimationFrame(() => {
					flushResize(event);
				});
			};
			const onPointerUp = (event) => {
				const s = internalStateRef.current;
				if (!s.isDragging) return;
				cancelAnimationFrame(frameRef.current);
				flushResize(event);
				s.isDragging = false;
				const finishedHandle = s.handleIndex;
				s.handleIndex = -1;
				setActiveHandle(-1);
				document.body.style.userSelect = "";
				document.body.style.webkitUserSelect = "";
				document.body.style.cursor = "";
				documentControllerRef.current?.abort();
				documentControllerRef.current = null;
				optionsRef.current.onResizeEnd?.(finishedHandle, [...currentSizesRef.current]);
			};
			node.addEventListener("pointerdown", onPointerDown, { signal: elementController.signal });
		};
		handleRefCallbacks.current.set(handleIndex, callback);
		return callback;
	}, [setCurrentSizes]);
	const getHandleProps = (0, react.useCallback)((input) => {
		const { index } = input;
		const orient = orientation;
		const beforeSize = currentSizes[index] ?? 0;
		const beforePanel = panels[index];
		const afterPanel = panels[index + 1];
		return {
			ref: getHandleRefCallback(index),
			role: "separator",
			"aria-orientation": orient,
			"aria-valuenow": Math.round(beforeSize),
			"aria-valuemin": Math.round(getMin(beforePanel)),
			"aria-valuemax": Math.round(getMax(beforePanel)),
			tabIndex: 0,
			onKeyDown: (event) => {
				if (!enabled) return;
				const isHorizontal = orient === "horizontal";
				const isRtl = dir === "rtl";
				let delta = 0;
				const currentStep = event.shiftKey ? shiftStep : step;
				switch (event.key) {
					case "ArrowLeft":
						if (!isHorizontal) return;
						delta = isRtl ? currentStep : -currentStep;
						break;
					case "ArrowRight":
						if (!isHorizontal) return;
						delta = isRtl ? -currentStep : currentStep;
						break;
					case "ArrowUp":
						if (isHorizontal) return;
						delta = -currentStep;
						break;
					case "ArrowDown":
						if (isHorizontal) return;
						delta = currentStep;
						break;
					case "Home":
						delta = -(currentSizes[index] - getMin(beforePanel));
						break;
					case "End":
						delta = getMax(beforePanel) - currentSizes[index];
						break;
					case "Enter": {
						const beforeCollapsible = beforePanel?.collapsible;
						const afterCollapsible = afterPanel?.collapsible;
						if (beforeCollapsible && currentSizes[index] <= currentSizes[index + 1]) {
							toggleCollapsePanel(index);
							event.preventDefault();
							return;
						}
						if (afterCollapsible) {
							toggleCollapsePanel(index + 1);
							event.preventDefault();
							return;
						}
						if (beforeCollapsible) {
							toggleCollapsePanel(index);
							event.preventDefault();
							return;
						}
						return;
					}
					default: return;
				}
				event.preventDefault();
				if (delta !== 0) {
					const newSizes = applyConstraints(currentSizes, panels, index, delta, redistribute);
					const beforeWas = currentSizes[index] === 0;
					const afterWas = currentSizes[index + 1] === 0;
					const beforeNow = newSizes[index] === 0;
					const afterNow = newSizes[index + 1] === 0;
					if (!beforeWas && beforeNow) {
						preCollapseSizesRef.current = [...currentSizes];
						onCollapseChange?.(index, true);
					} else if (beforeWas && !beforeNow) onCollapseChange?.(index, false);
					if (!afterWas && afterNow) {
						preCollapseSizesRef.current = [...currentSizes];
						onCollapseChange?.(index + 1, true);
					} else if (afterWas && !afterNow) onCollapseChange?.(index + 1, false);
					updateSizes(newSizes);
				}
			},
			"data-active": activeHandle === index || void 0,
			"data-orientation": orient
		};
	}, [
		orientation,
		currentSizes,
		panels,
		enabled,
		dir,
		step,
		shiftStep,
		activeHandle,
		redistribute,
		getHandleRefCallback,
		toggleCollapsePanel,
		updateSizes,
		onCollapseChange
	]);
	(0, react.useEffect)(() => () => {
		documentControllerRef.current?.abort();
		documentControllerRef.current = null;
		handleElementControllers.current.forEach((controller) => controller.abort());
		handleElementControllers.current.clear();
		cancelAnimationFrame(frameRef.current);
		if (internalStateRef.current.isDragging) {
			internalStateRef.current.isDragging = false;
			document.body.style.userSelect = "";
			document.body.style.webkitUserSelect = "";
			document.body.style.cursor = "";
		}
	}, []);
	return {
		ref: containerRefCallback,
		sizes: currentSizes,
		collapsed,
		activeHandle,
		getHandleProps,
		setSizes: updateSizes,
		collapse: collapsePanel,
		expand: expandPanel,
		toggleCollapse: toggleCollapsePanel
	};
}
//#endregion
exports.useSplitter = useSplitter;

//# sourceMappingURL=use-splitter.cjs.map