const MAX = 50;
let _stack    = [];
let _cursor   = -1;
let _onUpdate = null;

export function setOnUpdate(fn) {
  _onUpdate = fn;
}

export function push(files, affectedPaths = null) {
  _stack = _stack.slice(0, _cursor + 1);
  _stack.push({ files: [...files], affectedPaths: affectedPaths ? new Set(affectedPaths) : null });
  if (_stack.length > MAX) _stack.shift();
  _cursor = _stack.length - 1;
  _onUpdate?.();
}

// Returns { files, affectedPaths } where affectedPaths are from the entry being undone
export function undo() {
  if (!canUndo()) return null;
  const affectedPaths = _stack[_cursor].affectedPaths;
  --_cursor;
  _onUpdate?.();
  return { files: [..._stack[_cursor].files], affectedPaths };
}

// Returns { files, affectedPaths } from the entry being redone
export function redo() {
  if (!canRedo()) return null;
  ++_cursor;
  _onUpdate?.();
  return { files: [..._stack[_cursor].files], affectedPaths: _stack[_cursor].affectedPaths };
}

export function canUndo() { return _cursor > 0; }
export function canRedo() { return _cursor < _stack.length - 1; }

export function reset() {
  _stack  = [];
  _cursor = -1;
  _onUpdate?.();
}
