"use client";
const require_get_children_nodes_values = require("./get-children-nodes-values/get-children-nodes-values.cjs");
const require_get_all_checked_nodes = require("./get-all-checked-nodes/get-all-checked-nodes.cjs");
const require_is_node_checked = require("./is-node-checked/is-node-checked.cjs");
const require_is_node_indeterminate = require("./is-node-indeterminate/is-node-indeterminate.cjs");
let react = require("react");
let _mantine_hooks = require("@mantine/hooks");
//#region packages/@mantine/core/src/components/Tree/use-tree.ts
function getInitialTreeExpandedState(initialState, data, value, acc = {}) {
	data.forEach((node) => {
		acc[node.value] = node.value in initialState ? initialState[node.value] : node.value === value;
		if (Array.isArray(node.children)) getInitialTreeExpandedState(initialState, node.children, value, acc);
	});
	return acc;
}
function getTreeExpandedState(data, expandedNodesValues) {
	const state = getInitialTreeExpandedState({}, data, []);
	if (expandedNodesValues === "*") {
		const result = {};
		const keys = Object.keys(state);
		for (let i = 0; i < keys.length; i++) result[keys[i]] = true;
		return result;
	}
	expandedNodesValues.forEach((node) => {
		state[node] = true;
	});
	return state;
}
function getInitialCheckedState(initialState, data, checkStrictly) {
	if (checkStrictly) return initialState;
	const acc = [];
	initialState.forEach((node) => acc.push(...require_get_children_nodes_values.getChildrenNodesValues(node, data)));
	return Array.from(new Set(acc));
}
function getAllNodeValues(data) {
	const acc = [];
	for (const node of data) {
		acc.push(node.value);
		if (Array.isArray(node.children) && node.children.length > 0) acc.push(...getAllNodeValues(node.children));
	}
	return acc;
}
function useTree({ initialSelectedState = [], expandedState, initialCheckedState = [], checkedState, initialExpandedState = {}, selectedState, multiple = false, onNodeCollapse, onNodeExpand, onCheckedStateChange, onSelectedStateChange, onExpandedStateChange, onLoadChildren, checkStrictly = false } = {}) {
	const [data, setData] = (0, react.useState)([]);
	const [_expandedState, setExpandedState] = (0, _mantine_hooks.useUncontrolled)({
		value: expandedState,
		defaultValue: initialExpandedState,
		finalValue: {},
		onChange: onExpandedStateChange
	});
	const [_selectedState, setSelectedState] = (0, _mantine_hooks.useUncontrolled)({
		value: selectedState,
		defaultValue: initialSelectedState,
		finalValue: [],
		onChange: onSelectedStateChange
	});
	const [_checkedState, setCheckedState] = (0, _mantine_hooks.useUncontrolled)({
		value: checkedState,
		defaultValue: initialCheckedState,
		finalValue: [],
		onChange: onCheckedStateChange
	});
	const [anchorNode, setAnchorNode] = (0, react.useState)(null);
	const loadingNodesRef = (0, react.useRef)(/* @__PURE__ */ new Set());
	const loadedNodesRef = (0, react.useRef)(/* @__PURE__ */ new Set());
	const [loadingNodes, setLoadingNodes] = (0, react.useState)([]);
	const [loadErrors, setLoadErrors] = (0, react.useState)({});
	const initialize = (0, react.useCallback)((_data) => {
		setExpandedState(getInitialTreeExpandedState(_expandedState, _data, _selectedState));
		setCheckedState(getInitialCheckedState(_checkedState, _data, checkStrictly));
		setData(_data);
	}, [
		_selectedState,
		_checkedState,
		_expandedState,
		checkStrictly
	]);
	const loadNodeImpl = (0, react.useCallback)(async (value) => {
		if (!onLoadChildren) return;
		if (loadingNodesRef.current.has(value) || loadedNodesRef.current.has(value)) return;
		loadingNodesRef.current.add(value);
		setLoadingNodes(Array.from(loadingNodesRef.current));
		setLoadErrors((prev) => {
			if (!(value in prev)) return prev;
			const next = { ...prev };
			delete next[value];
			return next;
		});
		try {
			await onLoadChildren(value);
			loadedNodesRef.current.add(value);
		} catch (error) {
			const err = error instanceof Error ? error : new Error(String(error));
			setLoadErrors((prev) => ({
				...prev,
				[value]: err
			}));
		} finally {
			loadingNodesRef.current.delete(value);
			setLoadingNodes(Array.from(loadingNodesRef.current));
		}
	}, [onLoadChildren]);
	const tryLoadAsync = (0, react.useCallback)((value) => {
		if (!onLoadChildren) return;
		const node = require_get_children_nodes_values.findTreeNode(value, data);
		if (node && node.hasChildren && !Array.isArray(node.children)) loadNodeImpl(value);
	}, [
		onLoadChildren,
		data,
		loadNodeImpl
	]);
	const toggleExpanded = (0, react.useCallback)((value) => {
		const nextState = {
			..._expandedState,
			[value]: !_expandedState[value]
		};
		nextState[value] ? onNodeExpand?.(value) : onNodeCollapse?.(value);
		if (nextState[value]) tryLoadAsync(value);
		setExpandedState(nextState);
	}, [
		onNodeCollapse,
		onNodeExpand,
		_expandedState,
		tryLoadAsync
	]);
	const collapse = (0, react.useCallback)((value) => {
		if (_expandedState[value] !== false) onNodeCollapse?.(value);
		setExpandedState({
			..._expandedState,
			[value]: false
		});
	}, [onNodeCollapse, _expandedState]);
	const expand = (0, react.useCallback)((value) => {
		if (_expandedState[value] !== true) onNodeExpand?.(value);
		tryLoadAsync(value);
		setExpandedState({
			..._expandedState,
			[value]: true
		});
	}, [
		onNodeExpand,
		_expandedState,
		tryLoadAsync
	]);
	const expandAllNodes = (0, react.useCallback)(() => {
		const nextState = { ..._expandedState };
		Object.keys(nextState).forEach((key) => {
			nextState[key] = true;
			tryLoadAsync(key);
		});
		setExpandedState(nextState);
	}, [_expandedState, tryLoadAsync]);
	const collapseAllNodes = (0, react.useCallback)(() => {
		const nextState = { ..._expandedState };
		Object.keys(nextState).forEach((key) => {
			nextState[key] = false;
		});
		setExpandedState(nextState);
	}, [_expandedState]);
	const toggleSelected = (0, react.useCallback)((value) => {
		if (!multiple) {
			if (_selectedState.includes(value)) {
				setAnchorNode(null);
				return [];
			}
			setAnchorNode(value);
			return [value];
		}
		if (_selectedState.includes(value)) {
			setAnchorNode(null);
			return _selectedState.filter((item) => item !== value);
		}
		setAnchorNode(value);
		setSelectedState([..._selectedState, value]);
	}, [_selectedState]);
	const select = (0, react.useCallback)((value) => {
		setAnchorNode(value);
		setSelectedState(multiple ? _selectedState.includes(value) ? _selectedState : [..._selectedState, value] : [value]);
	}, [_selectedState]);
	const deselect = (0, react.useCallback)((value) => {
		anchorNode === value && setAnchorNode(null);
		setSelectedState(_selectedState.filter((item) => item !== value));
	}, [_selectedState]);
	const clearSelected = (0, react.useCallback)(() => {
		setSelectedState([]);
		setAnchorNode(null);
	}, []);
	const checkNode = (0, react.useCallback)((value) => {
		if (checkStrictly) {
			if (!_checkedState.includes(value)) setCheckedState([..._checkedState, value]);
		} else {
			const checkedNodes = require_get_children_nodes_values.getChildrenNodesValues(value, data);
			setCheckedState(Array.from(new Set([..._checkedState, ...checkedNodes])));
		}
	}, [
		data,
		_checkedState,
		checkStrictly
	]);
	const uncheckNode = (0, react.useCallback)((value) => {
		if (checkStrictly) setCheckedState(_checkedState.filter((item) => item !== value));
		else {
			const checkedNodes = require_get_children_nodes_values.getChildrenNodesValues(value, data);
			setCheckedState(_checkedState.filter((item) => !checkedNodes.includes(item)));
		}
	}, [
		data,
		_checkedState,
		checkStrictly
	]);
	const checkAllNodes = (0, react.useCallback)(() => {
		if (checkStrictly) setCheckedState(getAllNodeValues(data));
		else setCheckedState(require_get_children_nodes_values.getAllChildrenNodes(data));
	}, [data, checkStrictly]);
	const uncheckAllNodes = (0, react.useCallback)(() => {
		setCheckedState([]);
	}, []);
	const getCheckedNodes = (0, react.useCallback)(() => {
		if (checkStrictly) return _checkedState.map((value) => {
			const node = require_get_children_nodes_values.findTreeNode(value, data);
			return {
				checked: true,
				indeterminate: false,
				value,
				hasChildren: node ? Array.isArray(node.children) && node.children.length > 0 || !!node.hasChildren : false
			};
		});
		return require_get_all_checked_nodes.getAllCheckedNodes(data, _checkedState).result;
	}, [
		checkStrictly,
		_checkedState,
		data
	]);
	const isNodeChecked = (0, react.useCallback)((value) => {
		if (checkStrictly) return _checkedState.includes(value);
		return require_is_node_checked.memoizedIsNodeChecked(value, data, _checkedState);
	}, [
		checkStrictly,
		_checkedState,
		data
	]);
	const isNodeIndeterminate = (0, react.useCallback)((value) => {
		if (checkStrictly) return false;
		return require_is_node_indeterminate.memoizedIsNodeIndeterminate(value, data, _checkedState);
	}, [
		checkStrictly,
		_checkedState,
		data
	]);
	const isNodeLoading = (0, react.useCallback)((value) => loadingNodes.includes(value), [loadingNodes]);
	const getNodeLoadError = (0, react.useCallback)((value) => loadErrors[value] || null, [loadErrors]);
	const invalidateNode = (0, react.useCallback)((value) => {
		loadedNodesRef.current.delete(value);
		setLoadErrors((prev) => {
			if (!(value in prev)) return prev;
			const next = { ...prev };
			delete next[value];
			return next;
		});
	}, []);
	return (0, react.useMemo)(() => ({
		checkStrictly,
		multiple,
		expandedState: _expandedState,
		selectedState: _selectedState,
		checkedState: _checkedState,
		anchorNode,
		initialize,
		toggleExpanded,
		collapse,
		expand,
		expandAllNodes,
		collapseAllNodes,
		setExpandedState,
		checkNode,
		uncheckNode,
		checkAllNodes,
		uncheckAllNodes,
		setCheckedState,
		toggleSelected,
		select,
		deselect,
		clearSelected,
		setSelectedState,
		getCheckedNodes,
		isNodeChecked,
		isNodeIndeterminate,
		isNodeLoading,
		getNodeLoadError,
		loadNode: loadNodeImpl,
		invalidateNode
	}), [
		checkStrictly,
		multiple,
		_expandedState,
		_selectedState,
		_checkedState,
		anchorNode,
		initialize,
		toggleExpanded,
		collapse,
		expand,
		expandAllNodes,
		collapseAllNodes,
		setExpandedState,
		checkNode,
		uncheckNode,
		checkAllNodes,
		uncheckAllNodes,
		setCheckedState,
		toggleSelected,
		select,
		deselect,
		clearSelected,
		setSelectedState,
		getCheckedNodes,
		isNodeChecked,
		isNodeIndeterminate,
		isNodeLoading,
		getNodeLoadError,
		loadNodeImpl,
		invalidateNode
	]);
}
//#endregion
exports.getTreeExpandedState = getTreeExpandedState;
exports.useTree = useTree;

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