import type { LayoutDrawDocument } from './layoutDrawTypes';

export type LayoutDrawHistoryState = {
  past: LayoutDrawDocument[];
  present: LayoutDrawDocument;
  future: LayoutDrawDocument[];
};

function cloneDocument(document: LayoutDrawDocument): LayoutDrawDocument {
  return {
    backgroundMode: document.backgroundMode,
    shapes: document.shapes.map((shape) => ({ ...shape })),
  };
}

function isDocumentEqual(left: LayoutDrawDocument, right: LayoutDrawDocument) {
  return JSON.stringify(left) === JSON.stringify(right);
}

export function createLayoutDrawHistoryState(initialDocument: LayoutDrawDocument): LayoutDrawHistoryState {
  return {
    past: [],
    present: cloneDocument(initialDocument),
    future: [],
  };
}

export function commitLayoutDrawHistory(
  history: LayoutDrawHistoryState,
  nextDocument: LayoutDrawDocument,
): LayoutDrawHistoryState {
  const nextSnapshot = cloneDocument(nextDocument);
  if (isDocumentEqual(history.present, nextSnapshot)) {
    return history;
  }

  return {
    past: [...history.past, cloneDocument(history.present)],
    present: nextSnapshot,
    future: [],
  };
}

export function undoLayoutDrawHistory(history: LayoutDrawHistoryState): LayoutDrawHistoryState {
  if (history.past.length === 0) {
    return history;
  }

  const previous = history.past[history.past.length - 1];
  return {
    past: history.past.slice(0, -1),
    present: cloneDocument(previous),
    future: [cloneDocument(history.present), ...history.future],
  };
}

export function redoLayoutDrawHistory(history: LayoutDrawHistoryState): LayoutDrawHistoryState {
  if (history.future.length === 0) {
    return history;
  }

  const [next, ...restFuture] = history.future;
  return {
    past: [...history.past, cloneDocument(history.present)],
    present: cloneDocument(next),
    future: restFuture,
  };
}
