"use client";
import { findTreeNode } from "./get-children-nodes-values/get-children-nodes-values.mjs";
import { useEffect, useState } from "react";
//#region packages/@mantine/core/src/components/Tree/use-tree-node-drag-drop.ts
function isDescendantOf(data, ancestorValue, descendantValue) {
	const ancestor = findTreeNode(ancestorValue, data);
	if (!ancestor || !ancestor.children) return false;
	function check(nodes) {
		for (const node of nodes) {
			if (node.value === descendantValue) return true;
			if (node.children && check(node.children)) return true;
		}
		return false;
	}
	return check(ancestor.children);
}
function getDragDropPosition(event, element, hasChildren, isExpanded) {
	const rect = element.getBoundingClientRect();
	const y = event.clientY - rect.top;
	const height = rect.height;
	if (hasChildren) {
		if (isExpanded) {
			if (y < height * .5) return "before";
			return "inside";
		}
		if (y < height * .25) return "before";
		if (y > height * .75) return "after";
		return "inside";
	}
	if (y < height * .5) return "before";
	return "after";
}
const EMPTY_DRAG_PROPS = {
	elementProps: {},
	dragHandleProps: void 0
};
function useTreeNodeDragDrop({ nodeValue, hasChildren, isExpanded, data, onDragDrop, dragStateRef, allowDrop, withDragHandle }) {
	const [isDragHandleActive, setIsDragHandleActive] = useState(false);
	useEffect(() => {
		if (!withDragHandle || !isDragHandleActive) return;
		const handleWindowMouseUp = () => setIsDragHandleActive(false);
		window.addEventListener("mouseup", handleWindowMouseUp);
		return () => window.removeEventListener("mouseup", handleWindowMouseUp);
	}, [withDragHandle, isDragHandleActive]);
	if (!onDragDrop) return EMPTY_DRAG_PROPS;
	const handleDragStart = (event) => {
		if (withDragHandle && !isDragHandleActive) return;
		event.stopPropagation();
		event.dataTransfer.effectAllowed = "move";
		event.dataTransfer.setData("text/plain", nodeValue);
		dragStateRef.current.draggedValue = nodeValue;
		const target = event.currentTarget;
		const treeItem = target.closest("[role=treeitem]");
		if (treeItem) treeItem.setAttribute("data-dragging", "true");
		requestAnimationFrame(() => {
			target.setAttribute("data-dragging", "true");
		});
	};
	const handleDragOver = (event) => {
		const draggedValue = dragStateRef.current.draggedValue;
		if (!draggedValue || draggedValue === nodeValue) return;
		if (isDescendantOf(data, draggedValue, nodeValue)) return;
		const target = event.currentTarget;
		const position = getDragDropPosition(event, target, hasChildren, isExpanded);
		if (allowDrop && !allowDrop({
			draggedNode: draggedValue,
			targetNode: nodeValue,
			position
		})) {
			const prevTarget = dragStateRef.current.currentDropTarget;
			if (prevTarget && prevTarget !== target) prevTarget.removeAttribute("data-drag-over");
			target.removeAttribute("data-drag-over");
			dragStateRef.current.currentDropTarget = null;
			return;
		}
		event.preventDefault();
		event.stopPropagation();
		event.dataTransfer.dropEffect = "move";
		const prevTarget = dragStateRef.current.currentDropTarget;
		if (prevTarget && prevTarget !== target) prevTarget.removeAttribute("data-drag-over");
		target.setAttribute("data-drag-over", position);
		dragStateRef.current.currentDropTarget = target;
	};
	const handleDragLeave = (event) => {
		const target = event.currentTarget;
		const related = event.relatedTarget;
		if (related && target.contains(related)) return;
		target.removeAttribute("data-drag-over");
		if (dragStateRef.current.currentDropTarget === target) dragStateRef.current.currentDropTarget = null;
	};
	const handleDrop = (event) => {
		event.preventDefault();
		event.stopPropagation();
		const target = event.currentTarget;
		const position = target.getAttribute("data-drag-over");
		target.removeAttribute("data-drag-over");
		const draggedValue = dragStateRef.current.draggedValue;
		if (draggedValue && position && draggedValue !== nodeValue) {
			const payload = {
				draggedNode: draggedValue,
				targetNode: nodeValue,
				position
			};
			if (!allowDrop || allowDrop(payload)) onDragDrop(payload);
		}
		dragStateRef.current.draggedValue = null;
		dragStateRef.current.currentDropTarget = null;
	};
	const handleDragEnd = (event) => {
		const target = event.currentTarget;
		target.removeAttribute("data-dragging");
		const treeItem = target.closest("[role=treeitem]");
		if (treeItem) treeItem.removeAttribute("data-dragging");
		const prevTarget = dragStateRef.current.currentDropTarget;
		if (prevTarget) prevTarget.removeAttribute("data-drag-over");
		dragStateRef.current.draggedValue = null;
		dragStateRef.current.currentDropTarget = null;
		if (withDragHandle) setIsDragHandleActive(false);
	};
	return {
		elementProps: {
			draggable: withDragHandle ? isDragHandleActive : true,
			onDragStart: handleDragStart,
			onDragOver: handleDragOver,
			onDragLeave: handleDragLeave,
			onDrop: handleDrop,
			onDragEnd: handleDragEnd
		},
		dragHandleProps: withDragHandle ? { onMouseDown: () => setIsDragHandleActive(true) } : void 0
	};
}
//#endregion
export { useTreeNodeDragDrop };

//# sourceMappingURL=use-tree-node-drag-drop.mjs.map