import { isNonNullable } from '../../../../types/type-guard';
import { CommonAnnotation, CommonAnnotationTypeEnum } from './common-annotation.abstract';
/**
 * Annotation to add custom attributes of element
 */
export class CustomAttributeAnnotation extends CommonAnnotation {
  constructor(customAttribute) {
    super();
    this.type = CommonAnnotationTypeEnum.CUSTOM_ATTRIBUTE;
    this.BOOLEAN_ATTRS = new Set([
      'controls',
      'disabled',
      'checked',
      'readonly',
      'multiple',
      'required',
      'autoplay',
      'muted',
    ]);
    this.customAttribute = customAttribute;
  }
  /**
   * Generate the map item for the annotation
   *
   * @param {Record<string, string>} customizeAttribute - custom attribute annotation
   * @returns {[CommonAnnotationTypeEnum.CUSTOM_ATTRIBUTE, CustomAttributeAnnotation]} Map item for the annotation
   */
  static from(customizeAttribute) {
    return [CommonAnnotationTypeEnum.CUSTOM_ATTRIBUTE, new CustomAttributeAnnotation(customizeAttribute)];
  }
  /**
   * Generate the JSON representation of the annotation
   *
   * @returns {Record<string, unknown>} JSON representation of the annotation
   */
  toJSON() {
    return {
      customAttribute: this.customAttribute,
    };
  }
  /**
   * Create a new custom attribute annotation
   *
   * @returns {CustomAttributeAnnotation} - Custom attribute annotation
   */
  clone() {
    return new CustomAttributeAnnotation(this.customAttribute);
  }
  /**
   * Generate the custom attribute of current element, excluding 'style' and 'class'
   *
   * @param {string[]} filterAttr - should filter these existed attrs
   * @returns {string[]} - Custom attributes
   */
  toString(filterAttr = []) {
    const filterAttrKeys = filterAttr.map((attr) => attr.split('=')[0]);
    return Object.keys(this.customAttribute)
      .map((key) => {
      return !filterAttrKeys.includes(key) ? `${key}="${this.customAttribute[key]}"` : null;
    })
      .filter(isNonNullable);
  }
  /**
   * Generate the custom attribute for the annotation
   *
   * @param {RTERenderCustomAttributes} options - should filter these certain attrs
   * @returns {Record<string, string>} custom attribute
   */
  render(options = {}) {
    var _a;
    const customAttribute = Object.assign({}, this.customAttribute);
    (_a = options.filterAttributes) === null || _a === void 0 ? void 0 : _a.forEach((attr) => delete customAttribute[attr]);
    Object.keys(customAttribute).forEach((key) => {
      if (this.BOOLEAN_ATTRS.has(key) && customAttribute[key] === '') {
        customAttribute[key] = 'true';
      }
    });
    return customAttribute;
  }
}
