/** @license MIT | @cube-dev/ui-kit v0.135.1 | Cube Dev Team */
import { useEvent } from "../../../_internal/hooks/use-event.js";
import { useRef, useState } from "react";

//#region src/components/content/Tree/use-load-data.ts
/**
* Tracks which rows are currently fetching their children via `loadData`
* and exposes a setter for the Tree to call after every expand change.
*
* `loadData` is fired exactly once per key per "first expand" event:
*
* - Skipped if there is no `loadData` callback.
* - Skipped for leaf nodes (`isLeaf === true`).
* - Skipped if the node already has `children` (already loaded).
* - Skipped if a previous fetch for the same key is still in flight.
*
* The promise's resolution is awaited only to clear the `loading` mod;
* the consumer is expected to commit the new children to the controlled
* `treeData` themselves (matching AntD's pattern).
*/
function useLoadData(opts) {
	const { nodesByKey, loadData, initialExpandedKeys } = opts;
	const [loadingKeys, setLoadingKeys] = useState(() => /* @__PURE__ */ new Set());
	const previousExpandedRef = useRef(new Set(initialExpandedKeys));
	const inFlightRef = useRef(/* @__PURE__ */ new Set());
	return {
		loadingKeys,
		onExpandedChanged: useEvent((expandedKeys) => {
			const next = /* @__PURE__ */ new Set();
			for (const k of expandedKeys) next.add(String(k));
			const prev = previousExpandedRef.current;
			const newlyExpanded = [];
			for (const k of next) if (!prev.has(k)) newlyExpanded.push(k);
			previousExpandedRef.current = next;
			if (!loadData || newlyExpanded.length === 0) return;
			const toLoad = [];
			for (const key of newlyExpanded) {
				const node = nodesByKey.get(key);
				if (!node) continue;
				if (node.isLeaf) continue;
				if (node.children && node.children.length > 0) continue;
				if (inFlightRef.current.has(key)) continue;
				inFlightRef.current.add(key);
				toLoad.push(key);
			}
			if (toLoad.length === 0) return;
			setLoadingKeys((current) => {
				const updated = new Set(current);
				for (const k of toLoad) updated.add(k);
				return updated;
			});
			for (const key of toLoad) {
				const loadNode = nodesByKey.get(key);
				Promise.resolve(loadData({
					key,
					children: loadNode?.children
				})).catch((err) => {
					console.error(`[Tree] loadData failed for key "${key}":`, err);
				}).finally(() => {
					inFlightRef.current.delete(key);
					setLoadingKeys((current) => {
						if (!current.has(key)) return current;
						const updated = new Set(current);
						updated.delete(key);
						return updated;
					});
				});
			}
		})
	};
}

//#endregion
export { useLoadData };
//# sourceMappingURL=use-load-data.js.map