import { h } from '@stencil/core';
import { ImageAnnotation } from '../../annotations/image-annotation';
import { NodeAnnotation, NodeAnnotationTypeEnum } from '../../annotations/node-annotation.abstract';
import { ImageAnnotationAction } from '../../actions/image-annotation-action';
import stateEntityRenderingRegistry from '../../../slimmers/controllers/state-entity-rendering-registry';
import { DomNodeSubjectObserverFactory } from '../../../../../helpers/change-manager/subject/dom-node-subject/dom-node-subject-observer-factory';
import { VegaChange } from '../../../../../helpers/event-manager/event-id/vega-event-id';
import { RTENodeRenderer } from './node-renderer.abstract';
import { isNonNullable } from '../../../../../types/type-guard';
import { CommonAnnotationTypeEnum } from '../../annotations/common-annotation.abstract';
import { RTEDecoratorNode } from '../../nodes/decorator-node';
class RTEImageNodeRenderer extends RTENodeRenderer {
  constructor() {
    super(...arguments);
    this.handleChange = ({ detail }, node) => {
      switch (detail.action) {
        case 'edit': {
          const size = detail.payload.size;
          const alt = detail.payload.alt;
          node.apply(new ImageAnnotationAction(size, alt));
          break;
        }
        /*
         * The below method is e2e-test covered in
         * @see{module:vega-rich-text-editor-image-click-delete-button}
         */
        /* istanbul ignore next */
        case 'delete': {
          const event = new InputEvent('beforeinput', {
            inputType: 'deleteContentBackward',
            bubbles: true,
          });
          setTimeout(() => {
            stateEntityRenderingRegistry.getDOMByEntity(node).dispatchEvent(event);
          }, 50);
          break;
        }
      }
    };
  }
  render(node, renderContext) {
    const imageAnnotation = node.getAnnotationByType(NodeAnnotationTypeEnum.IMAGE) ||
      new ImageAnnotation('md', '');
    return renderContext.editable ? (h("vega-rich-text-image-editor", { key: node.id, class: this.getClassesForImageEditor(node), size: imageAnnotation.size, alt: imageAnnotation.alt, ref: (ref) => {
        DomNodeSubjectObserverFactory.addUniqueObserverToNode(ref, VegaChange, (e) => this.handleChange(e, node));
      } }, this.renderImage(imageAnnotation, node, renderContext))) : (this.renderImage(imageAnnotation, node, renderContext));
  }
  /**
   * The function will render an image.
   * In edit mode, it will be placed in the "vega-rich-text-image-editor" component as a slot.
   * In view mode, the img image will be displayed directly.
   *
   * @param {ImageAnnotation} imageAnnotation - the image annotation of the image node
   * @param {RTEImageNode} node  - the current image node
   * @returns {HTMLElement} return a image element
   */
  renderImage(imageAnnotation, node, renderContext) {
    var _a;
    return (h("img", Object.assign({}, (_a = node.getCustomAttributesAnnotation()) === null || _a === void 0 ? void 0 : _a.render({ filterAttributes: ['width', 'height'] }), { class: this.getClassesForImageNode(node, renderContext.editable), style: renderContext.editable
        ? Object.assign(Object.assign({}, node.getStyles()), { width: '100%' }) : Object.assign(Object.assign({}, node.getStyles()), imageAnnotation.renderStyle({ standalone: true })), alt: imageAnnotation.alt, "data-size": imageAnnotation.size, src: node.url, ref: (ref) => super.registerRef(ref, node), 
      // eslint-disable-next-line react/jsx-no-bind
      onError: (e) => {
        const img = e.target;
        img.style.width = '16px';
        img.style.height = '16px';
      } })));
  }
  /**
   * Get the custom class string of the current RTEImageNode.
   *
   * @returns {Nullable<string>} A string of classes.
   */
  getCommonClasses(node) {
    const customClassAnnotation = node.getAnnotationByType(CommonAnnotationTypeEnum.CUSTOM_CLASS);
    if (customClassAnnotation) {
      return customClassAnnotation.customClass
        .filter(isNonNullable)
        .reduce((pre, cur) => [pre, cur].join(' ').trim(), '');
    }
    return null;
  }
  /**
   * Get classes from annotations
   *
   * @param {RTERenderContext} [options={ standalone: false }] - Options to control style mode
   * @returns {string} - Annotation style
   */
  getClasses(node, options = { standalone: false }) {
    return Array.from(node.annotationMap.values())
      .filter((annotation) => annotation instanceof NodeAnnotation)
      .map((annotation) => annotation.renderClass(options))
      .filter(isNonNullable)
      .reduce((pre, cur) => [pre, cur].join(' ').trim(), '');
  }
  /**
   * Get the class string for the image node.
   *
   * @param {RTEImageNode} node - The image node
   * @param {boolean} editable - Whether the editor is in editable mode
   * @returns {string} - The class string for the image node
   */
  getClassesForImageNode(node, editable) {
    var _a;
    return editable
      ? `${RTEDecoratorNode.DECORATOR_NODE_CLASS} ${(_a = this.getCommonClasses(node)) !== null && _a !== void 0 ? _a : ''}`
      : node.getClasses();
  }
  /**
   * Get the class string for the image editor.
   *
   * @param {RTEImageNode} node - The image node
   * @returns {string} - The class string for the image editor
   */
  getClassesForImageEditor(node) {
    return `${RTEDecoratorNode.DECORATOR_CONTAINER_CLASS} ${this.getClasses(node)}`;
  }
}
export default new RTEImageNodeRenderer();
