import { ModifyContentAction } from '../actions/modify-content-action.abstract';
/**
 * Registry for action handler interceptors, which can register and retrieve interceptors for specific actions and targets.
 */
export class ActionHandlerInterceptorRegistry {
  /**
   * Bind a specific strategy to a special action type of the rich text node.
   *
   * @param {string} actionType - The special action type or the action class name.
   * @param {string} targetClass - The rich text node class name.
   * @param {ActionHandlerInterceptor} strategy - The action handle strategy instance.
   */
  static register(actionType, targetClass, strategy) {
    if (!this.registry.has(targetClass)) {
      this.registry.set(targetClass, new Map());
    }
    /* eslint-disable @typescript-eslint/no-non-null-assertion */
    if (!this.registry.get(targetClass).has(actionType)) {
      this.registry.get(targetClass).set(actionType, new Set());
    }
    this.registry.get(targetClass).get(actionType).add(strategy);
    /* eslint-enable @typescript-eslint/no-non-null-assertion */
  }
  /**
   * Unregister the strategy for the specific action type and target class.
   *
   * @param {string} actionType - The special action type or the action class name.
   * @param {string} targetClass - The rich text node class name.
   * @param {ActionHandlerInterceptor} strategy - The action handler interceptor instance.
   */
  static unregister(actionType, targetClass, strategy) {
    const strategyMap = this.registry.get(targetClass);
    if (strategyMap) {
      const strategySet = strategyMap.get(actionType);
      if (strategySet) {
        strategySet.delete(strategy);
      }
    }
  }
  /**
   * Get the special interceptor strategy that before handle the action logic.
   *
   * @typedef T generic type
   * @typedef target generic type
   * @param {RTEActionType} action - The special action .
   * @param {string} targetClass - The rich text node class name.
   * @returns {Nullable<ActionHandlerInterceptor<T, target>>} - The action handler interceptor instance or null if not found.
   */
  static get(action, targetClass) {
    const targetClassName = targetClass.constructor.name;
    const actionType = action instanceof ModifyContentAction ? action.type : action.constructor.name;
    const strategyMap = this.registry.get(targetClassName);
    if (strategyMap) {
      const set = strategyMap.get(actionType);
      if (set && set.size > 0) {
        return Array.from(set).find((interceptor) => interceptor.canIntercept(action, targetClass));
      }
    }
  }
}
ActionHandlerInterceptorRegistry.registry = new Map();
