import {PluginKey} from "prosemirror-state";

/**
 * @import {Schema} from "prosemirror-model";
 * @import {Plugin} from "prosemirror-state";
 */

/**
 * @abstract
 */
export default class ProseMirrorPlugin {
  /**
   * An abstract class for building a ProseMirror Plugin.
   * @see {Plugin}
   * @param {Schema} schema  The schema to build the plugin against.
   */
  constructor(schema) {
    /**
     * The ProseMirror schema to build the plugin against.
     * @type {Schema}
     */
    this.schema = schema;
    Object.defineProperty(this, "schema", {configurable: false, enumerable: false, writable: false});
  }

  /* -------------------------------------------- */

  /**
   * Build the plugin.
   * @param {Schema} schema     The ProseMirror schema to build the plugin against.
   * @param {object} [options]  Additional options to pass to the plugin.
   * @returns {Plugin}
   * @abstract
   */
  static build(schema, options={}) {
    throw new Error("Subclasses of ProseMirrorPlugin must implement a static build method.");
  }

  /* -------------------------------------------- */

  /**
   * A unique key for this plugin that can be used to identify a plugin instance in any given editor.
   * @returns {PluginKey}
   */
  static get key() {
    if ( Object.hasOwn(this, "key") ) return this.key;
    const key = new PluginKey(this.name);
    Object.defineProperty(this, "key", { value: key, writable: false });
    return key;
  }
}
