import { TypographyUrls } from '../../../../constants/tokens/typography';
/**
 * Registry for managing filter styles strategies keyed by DTO class name.
 *
 * Provides common `register` / `getStrategies` primitives that both output-
 * filtering strategies (DTO → HTML) and annotation-parsing strategies
 * (HTML → DTO) build upon.
 *
 * TODO: Currently, the filter styles strategies are applied for all rich text editors. We need to apply the strategies with a specific rich text editor instance when we have multiple rich text editors in the future.
 */
export class RTEFilterStylesStrategyRegistry {
  /**
   * Registers a filter styles strategy for a specific DTO class name.
   * Duplicate strategy instances are ignored.
   *
   * @param {string} dtoClassName - The DTO class name (e.g. `RTEListBlock.name`).
   * @param {RTEFilterStylesStrategy} strategy - The strategy instance to register.
   */
  static register(dtoClassName, strategy) {
    var _a;
    const set = (_a = this.registry.get(dtoClassName)) !== null && _a !== void 0 ? _a : new Set();
    set.add(strategy);
    this.registry.set(dtoClassName, set);
  }
  /**
   * Retrieves all strategies registered for a given DTO class name.
   *
   * @param {string} dtoClassName - The DTO class name to look up.
   * @returns {RTEFilterStylesStrategy[]} Registered strategies (empty array if none).
   */
  static getStrategies(dtoClassName) {
    var _a;
    return Array.from((_a = this.registry.get(dtoClassName)) !== null && _a !== void 0 ? _a : []);
  }
  /**
   * Executes the appropriate filter styles strategy for a given block or node instance.
   *
   * @param {RTEBlock | RTENode} blockOrNodeInstance - The block or node instance to filter styles for.
   * @param {RTEFilterStyles} styles - The full set of styles to filter.
   * @param {string[]} classNames - The class names to consider.
   * @returns {RTEFilterInlineStylesResult} The result of filtering, including the remaining styles and class names.
   */
  static executeTheStrategyFilterAction(blockOrNodeInstance, styles, classNames) {
    const dtoClassName = blockOrNodeInstance.constructor.name;
    const strategies = this.getStrategies(dtoClassName);
    const matchedStrategies = strategies.filter((strategy) => {
      return strategy.canFilter(blockOrNodeInstance);
    });
    return matchedStrategies.reduce((result, strategy) => {
      return strategy.filterAndDeleteStyles(result.styles, result.classNames);
    }, {
      styles,
      classNames,
    });
  }
  /**
   * Executes the appropriate filter styles strategy for refilling styles on a given element.
   *
   * @param {string} dtoClassName The class name of the DTO.
   * @param {HTMLElement} element The HTML element to refill styles on.
   */
  static executeTheStrategyRefillAction(dtoClassName, element) {
    const strategies = this.getStrategies(dtoClassName);
    const matchedStrategies = strategies.filter((strategy) => {
      return strategy.canRefill(dtoClassName, element);
    });
    matchedStrategies.forEach((strategy) => {
      strategy.refillStyles(element);
    });
  }
  /**
   * Based on the registered strategies, generates the CSS text for all strategies in the registry. The generated CSS text is grouped by DTO class names for better organization.
   *
   * @param {boolean} enableFontFaceImports - A flag indicating whether to include font-face declarations for typography styles.
   * @returns {string} The content of style file.
   */
  static generateAllStylesContent(enableFontFaceImports = false) {
    const styleBlocks = [];
    if (enableFontFaceImports) {
      styleBlocks.push('/* Font-face imports begin */\n');
      styleBlocks.push(Object.keys(TypographyUrls)
        .map((key) => {
        return `@import url('${TypographyUrls[key].url}');\n`;
      })
        .join(' '));
      styleBlocks.push('/* Font-face imports end */\n');
    }
    this.registry.forEach((strategies) => {
      strategies.forEach((strategy) => {
        const cssText = strategy.toCssText();
        if (cssText && !styleBlocks.includes(cssText)) {
          styleBlocks.push(cssText);
        }
      });
    });
    return styleBlocks.join(' ');
  }
}
RTEFilterStylesStrategyRegistry.registry = new Map();
