import { useCallback, useMemo, useRef, useState } from "react";
//#region src/components/pisellFloorMapLayout/hooks/useDraftConfigHistory.ts
/**
* 平面图草稿历史栈：past/present/future + commit/replace/undo/redo
*
* 设计：
* - `commit(value, opts?)`：写入新值并入栈（覆盖 future）。同一 `groupId` 在
*   `mergeWindowMs` 内的多次提交会合并为同一条历史，避免高频微调污染栈。
*   实际项目里 `EditableItemLayer` 只在 mouseup 时回调一次，因此默认场景下不会
*   触发合并；保留 group 能力是为后续如「输入框边输入边写草稿」等连续操作准备。
* - `replace(value)`：直接重置 present 并清空历史；用于上游 props 同步落地，避免
*   把"上游回写"也变成可撤销项。
* - `undo` / `redo`：在 past/future 栈内迁移 present。
*/
/** 历史最大长度，超出从最旧端裁剪 */
const HISTORY_LIMIT = 100;
function useDraftConfigHistory() {
	const [state, setState] = useState({
		past: [],
		present: null,
		future: []
	});
	const lastGroupRef = useRef(null);
	const commit = useCallback((next, options) => {
		var _options$mergeWindowM;
		const now = Date.now();
		const last = lastGroupRef.current;
		const inGroup = !!((options === null || options === void 0 ? void 0 : options.groupId) && last && last.id === options.groupId && now - last.at <= ((_options$mergeWindowM = options.mergeWindowMs) !== null && _options$mergeWindowM !== void 0 ? _options$mergeWindowM : 600));
		lastGroupRef.current = {
			id: options === null || options === void 0 ? void 0 : options.groupId,
			at: now
		};
		setState((cur) => {
			const value = typeof next === "function" ? next(cur.present) : next;
			if (Object.is(value, cur.present)) return cur;
			let nextPast = cur.past;
			if (cur.present != null && !inGroup) nextPast = nextPast.length >= HISTORY_LIMIT ? [...nextPast.slice(1), cur.present] : [...nextPast, cur.present];
			return {
				past: nextPast,
				present: value,
				future: []
			};
		});
	}, []);
	const replace = useCallback((next) => {
		lastGroupRef.current = null;
		setState({
			past: [],
			present: next,
			future: []
		});
	}, []);
	const undo = useCallback(() => {
		lastGroupRef.current = null;
		setState((cur) => {
			if (cur.past.length === 0) return cur;
			const prev = cur.past[cur.past.length - 1];
			const nextFuture = cur.present != null ? [cur.present, ...cur.future] : cur.future;
			return {
				past: cur.past.slice(0, -1),
				present: prev,
				future: nextFuture
			};
		});
	}, []);
	const redo = useCallback(() => {
		lastGroupRef.current = null;
		setState((cur) => {
			if (cur.future.length === 0) return cur;
			const next = cur.future[0];
			return {
				past: cur.present != null ? [...cur.past, cur.present] : cur.past,
				present: next,
				future: cur.future.slice(1)
			};
		});
	}, []);
	return useMemo(() => ({
		present: state.present,
		commit,
		replace,
		undo,
		redo,
		canUndo: state.past.length > 0,
		canRedo: state.future.length > 0
	}), [
		state,
		commit,
		replace,
		undo,
		redo
	]);
}
//#endregion
export { useDraftConfigHistory };
