var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { MapToComponentField, MapToComponentMethod, VegaSlimmer } from 'vega-slimmer/core';
import { isArrayEqual } from '../../../../utils/array';
/**
 * Inject the editor context to the extensions.
 */
export class RTEExtensionController extends VegaSlimmer {
  constructor() {
    super(...arguments);
    /**
     * Flush the editor value to the host. Auto focus the last node if autoFocusLastNode is true.
     *
     * @param {VegaRTEContent} value - The content value to flush.
     * @param {boolean} autoFocusLastNode - Whether to auto-focus the last node after flushing.
     */
    this.flushValue = (value, autoFocusLastNode = false) => {
      if (this.host && value) {
        void this.valueController.flushChanges(value, true);
        if (autoFocusLastNode) {
          const lastNode = this.host.value.getLastNode();
          if (lastNode) {
            this.selectionController.enqueueSelectionRangeFutureState(lastNode, lastNode.getRangeEndOffset());
          }
        }
      }
    };
    /**
     * Check if the editor is in source edit mode.
     *
     * @returns {boolean} - Whether the editor is in source edit mode.
     */
    this.isSourceEditMode = () => {
      return this.sourceView;
    };
    /**
     * Get the currently selected nodes in the editor.
     *
     * @returns {RTENode[]} - An array of currently selected RTENode objects.
     */
    this.getSelectedNodes = () => {
      return this.selectionController.getSelectedNodes();
    };
  }
  /**
   * Initializes the extension context for all registered extensions.
   * This method is called when the component is connected and whenever the extensions property changes.
   */
  initialExtensionContext() {
    if (this.extensions && this.host) {
      const extensionContext = this.generateExtensionContext();
      for (const extension of this.extensions) {
        extension.initialExtension(extensionContext);
      }
    }
  }
  /**
   * Destroys all registered extensions.
   */
  destroyExtension() {
    if (this.extensions) {
      for (const extension of this.extensions) {
        extension.destroyExtension();
      }
    }
  }
  /**
   * Update extension context when extensions property changes.
   *
   * @param {VegaRTEExtension[]} newValue - New extensions array.
   * @param {VegaRTEExtension[]} oldValue - Old extensions array.
   */
  handleExtensionsChange(newValue, oldValue) {
    if (oldValue) {
      for (const extension of oldValue) {
        extension.destroyExtension();
      }
    }
    if (!isArrayEqual(newValue, oldValue, false, (a, b) => a === b ? 0 : 1)) {
      this.initialExtensionContext();
    }
  }
  /**
   * Generates the extension context for the host component.
   *
   * @returns {RTEExtensionContext} - The generated extension context.
   */
  generateExtensionContext() {
    return {
      host: this.host,
      flushValue: this.flushValue,
      isSourceEditMode: this.isSourceEditMode,
      getSelectedNodes: this.getSelectedNodes,
      setSelectedNodes: this.selectionController.setSelectedNodes.bind(this.selectionController),
      getSelection: this.selectionController.getSelection.bind(this.selectionController),
    };
  }
}
__decorate([
  MapToComponentField()
], RTEExtensionController.prototype, "extensions", void 0);
__decorate([
  MapToComponentField()
], RTEExtensionController.prototype, "host", void 0);
__decorate([
  MapToComponentField()
], RTEExtensionController.prototype, "sourceView", void 0);
__decorate([
  MapToComponentField()
], RTEExtensionController.prototype, "valueController", void 0);
__decorate([
  MapToComponentField()
], RTEExtensionController.prototype, "selectionController", void 0);
__decorate([
  MapToComponentMethod('componentDidLoad')
], RTEExtensionController.prototype, "initialExtensionContext", null);
__decorate([
  MapToComponentMethod('disconnectedCallback')
], RTEExtensionController.prototype, "destroyExtension", null);
__decorate([
  MapToComponentMethod('watchExtensions')
], RTEExtensionController.prototype, "handleExtensionsChange", null);
