/**
 * LIFO stack of undoable actions. Each push registers an inverse callback;
 * pop runs the most recent inverse and removes it from the stack. Keep the
 * UI feedback honest: undo entries are best-effort and exact restoration
 * isn't always possible (e.g. when the inverse depends on server state that
 * has since changed).
 */

export interface UndoEntry {
	id: string;
	label: string;
	pushedAt: number;
	undo(): Promise<void> | void;
}

const MAX_ENTRIES = 25;

let counter = 0;
export const undoStack = $state<{ entries: UndoEntry[] }>({ entries: [] });

export function push(label: string, undo: UndoEntry['undo']): UndoEntry {
	const entry: UndoEntry = {
		id: `u-${++counter}`,
		label,
		pushedAt: Date.now(),
		undo
	};
	undoStack.entries.push(entry);
	if (undoStack.entries.length > MAX_ENTRIES) {
		undoStack.entries.shift();
	}
	return entry;
}

export async function popAndRun(): Promise<UndoEntry | null> {
	const entry = undoStack.entries.pop();
	if (!entry) return null;
	await entry.undo();
	return entry;
}

export function clear(): void {
	undoStack.entries.length = 0;
}
