import { KeyboardManagerSlimmer } from './keyboard-manager-slimmer';
import { debounce } from '../../utils/timer';
/**
 * An abstract class that manages the history of component values.
 */
export class ComponentValueHistoryControllerSlimmer extends KeyboardManagerSlimmer {
  constructor() {
    super(() => this.getKeyboardShortcutOptions.call(this));
    this.redoStack = [];
    this.undoStack = [];
    this.registerHistoryDelay = 300;
    this.registerHistoryDebounced = debounce((state) => {
      this.internalRegisterHistory(state);
    }, this.registerHistoryDelay, this);
  }
  /**
   * Registers history based on the editor state.
   *
   * @typedef T generic type parameter
   * @param {T} editorState - The state to record in history.
   * @param {boolean} [isForce] - If true, the history will be registered immediately without debounce.
   */
  registerHistory(editorState, isForce = false) {
    if (isForce) {
      this.internalRegisterHistory(editorState);
    }
    else {
      this.registerHistoryDebounced(editorState);
    }
  }
  /**
   * Internal function to register history immediately.
   *
   * @typedef T generic type parameter
   * @param {T} state - The state to record in history.
   */
  internalRegisterHistory(state) {
    this.redoStack = []; // clear redo stack when new action happens.
    this.undoStack.push(state);
  }
  /**
   * Returns the keyboard shortcut options for undo/redo functionality.
   *
   * @returns {KeyboardEventListener[]} - An array of keyboard shortcut options.
   */
  getKeyboardShortcutOptions() {
    const baseOption = {
      keyCode: 'KeyZ',
      activeElementInScope: this.getEffectiveTargets(),
      activeElementOutScope: this.getIneffectiveTargets.bind(this),
      eventName: 'keydown',
      modifierPressed: true,
    };
    return [
      Object.assign(Object.assign({}, baseOption), { shiftKey: false, 
        /**
         * Callback function for the undo action.
         *
         * @param {KeyboardEvent} e - The keyboard event triggered by the user.
         */
        callback: (e) => {
          e.preventDefault();
          if (this.undoStack.length > 0) {
            void this.undo();
          }
        } }),
      Object.assign(Object.assign({}, baseOption), { shiftKey: true, 
        /**
         * Callback function for the redo action.
         *
         * @param {KeyboardEvent} e - The keyboard event triggered by the user.
         */
        callback: (e) => {
          e.preventDefault();
          if (this.redoStack.length > 0) {
            void this.redo();
          }
        } }),
    ];
  }
}
