import { RTEFilterStylesStrategy } from '../filter-styles-strategy.abstract';
import { BOLD_FONT_WEIGHT, ITALIC_FONT_STYLE, STRIKETHROUGH_TEXT_DECORATION, UNDERLINE_TEXT_DECORATION, } from '../../annotations/text-format-default-styles';
/**
 * Filters redundant inline text formatting styles from `customStyle` when
 * parsing an RTETextNode. These styles are already represented by semantic
 * annotations and should not be persisted as custom overrides after source
 * edit round-trips.
 */
export class TextFormatFilterStylesStrategy extends RTEFilterStylesStrategy {
  constructor() {
    super(...arguments);
    this.stylesToBeFiltered = {};
  }
  /**
   * @returns {boolean} Always `true` — this strategy runs regardless of `autoMatchFormat`.
   */
  get alwaysFilter() {
    return true;
  }
  /**
   * Filter redundant text format styles from `customStyle`.
   *
   * @param {VegaRTEAnnotations} annotations - The annotations to filter.
   * @returns {VegaRTEAnnotations} The same annotations reference with customStyle cleaned up.
   */
  filterAnnotations(annotations) {
    const textAnnotations = annotations;
    const customStyle = textAnnotations.customStyle;
    if (!customStyle) {
      return annotations;
    }
    // Only delete styles that match the default values(BOLD_FONT_WEIGHT) to avoid affecting normal-source conversion.
    if (textAnnotations.bold && customStyle.fontWeight === BOLD_FONT_WEIGHT) {
      delete customStyle.fontWeight;
    }
    if (textAnnotations.italic && customStyle.fontStyle === ITALIC_FONT_STYLE) {
      delete customStyle.fontStyle;
    }
    const normalizedTextDecoration = this.normalizeTextDecoration(customStyle.textDecoration);
    if (normalizedTextDecoration &&
      this.shouldRemoveTextDecoration(normalizedTextDecoration, textAnnotations)) {
      delete customStyle.textDecoration;
    }
    if (Object.keys(customStyle).length === 0) {
      delete textAnnotations.customStyle;
    }
    return annotations;
  }
  /**
   * Normalizes a `text-decoration` CSS value to a sorted, unique token string of
   * toolbar-only tokens (`underline`, `line-through`). Returns `undefined` if the
   * value contains any non-toolbar token (e.g. `wavy`, a color).
   *
   * @param {string | undefined} value - The raw `textDecoration` CSS value.
   * @returns {string | undefined} Normalized token string, or `undefined` if the value cannot be safely removed.
   */
  normalizeTextDecoration(value) {
    if (!value) {
      return undefined;
    }
    const tokens = value.trim().toLowerCase().split(/\s+/);
    if (tokens.some((token) => token !== UNDERLINE_TEXT_DECORATION && token !== STRIKETHROUGH_TEXT_DECORATION)) {
      return undefined;
    }
    return Array.from(new Set(tokens)).sort().join(' ');
  }
  /**
   * Determines whether the `textDecoration` custom style should be removed based on the
   * semantic annotations present. Removal happens only when the normalized value exactly
   * matches the set of `{underline, strikethrough}` annotations.
   *
   * @param {string} normalizedTextDecoration - The normalized `textDecoration` token string.
   * @param {VegaRTETextAnnotations} annotations - The text annotations to check against.
   * @returns {boolean} `true` if the `textDecoration` style is redundant and should be removed.
   */
  shouldRemoveTextDecoration(normalizedTextDecoration, annotations) {
    const expectedTokens = [];
    if (annotations.underline) {
      expectedTokens.push(UNDERLINE_TEXT_DECORATION);
    }
    if (annotations.strikethrough) {
      expectedTokens.push(STRIKETHROUGH_TEXT_DECORATION);
    }
    if (expectedTokens.length === 0) {
      return false;
    }
    return normalizedTextDecoration === expectedTokens.sort().join(' ');
  }
}
