import { LisioComponent } from "@lisio/lisio-engine";
import { TranslationController } from "../../../controllers/translation/translation-controller";
import { translateEvent } from "../../../../misc/events";

/**
 * Abstract class extending LisioComponent to manage the dynamic translation of a text component.\
 * A text component is basically a component to display text.\
 */
abstract class LisioTextComponent extends LisioComponent {
  /**
   * Private attribute to store the text to display ine the component
   * @source
   */
  protected _textContent?: string;

  protected _textId?: string;

  /**
   * Public method to change text content
   * @param {string} textId - Id of new text
   * @param {boolean} noTranslate - Indicates if text has to be translated. Default value set to false
   * @returns Returns nothing
   * @source
   */
  public changeText(textId: string, noTranslate: boolean = false): void {
    if (noTranslate) {
      if (this._htmlElement == undefined) {
        this._textContent = textId;
      } else {
        const tmpDiv = document.createElement("div");
        tmpDiv.innerHTML = textId;
        this._htmlElement.textContent = tmpDiv.textContent;
      }
    } else {
      this._textId = textId;
      if (this._htmlElement == undefined) {
        this._textContent =
          TranslationController.current.getTranslation(textId);
      } else {
        const tmpDiv = document.createElement("div");
        tmpDiv.innerHTML = TranslationController.current.getTranslation(textId);
        this._htmlElement.innerHTML = "";
        for (const node of tmpDiv.childNodes) {
          if (node.nodeName !== "SCRIPT") {
            this._htmlElement.append(node.cloneNode(true));
          }
        }
      }
    }
  }

  /**
   * Constructor of abstract class {@link LisioTextComponent | LisioTextComponent}
   * @param {string} componentName - Component name
   * @param {string | undefined} textId - Id of text to display
   * @param {string | undefined} id - Id of component
   * @param {string[] | undefined} cssClasses - CSS classes of component
   * @param {Map<string, string> | undefined} attributes - Component attributes
   * @param {boolean | undefined} noTranslate - Indicates if text has to be translated
   * @source
   */
  constructor(
    componentName: string,
    textId?: string,
    id?: string,
    cssClasses?: string[],
    attributes?: Map<string, string>,
    noTranslate?: boolean,
  ) {
    super(componentName, id, cssClasses, attributes);
    this._textId = textId;
    if (textId) {
      if (noTranslate) {
        this._textContent = textId;
      } else {
        try {
          this._textContent =
            TranslationController.current.getTranslation(textId);
        } catch (error) {
          console.log(error);
          this._textContent = "";
        }
        window.addEventListener(translateEvent.type, () => {
          if (this._textId != undefined) {
            this.changeText(this._textId);
          }
        });
      }
    }
  }
}

export { LisioTextComponent };
