/**
 * @mergeTarget
 * @module Src/Components/CustomText
 */

import { LisioComponentStyles } from "@lisio/lisio-engine";
import { LisioTextComponent } from "../LisioTextComponent/LisioTextComponent";
import { customTextStyles } from "./custom-text.css";
import { TextTagNames } from "../component-types";

/**
 * Class representing a text component extending LisioTextComponent.\
 * It aims to represent a text component.\
 * A text component is basically a component to display text.\
 */
class CustomText extends LisioTextComponent {
  /**
   * Private attribute to store tag name of component
   * @source
   */
  private _tagName: TextTagNames;

  /**
   * Private attribute to sotre for attribute
   * @source
   */
  private _labelFor: string = "";

  /**
   * @async
   * Public method implementing abstract method render of LisioComponent
   * @returns Returns a promise containing the representation of a text in HTML string
   * @source
   */
  public async render(): Promise<string> {
    return `
      <${this._tagName} class="lisio-custom-text ${this.renderClasses()}" ${
        this._tagName === "label" ? `for="${this._labelFor}"` : ""
      }
      ${
        this._id != undefined ? `id="${this._id}"` : ""
      } ${this.renderAttributes()}>
        ${this._textContent}
      </${this._tagName}>
    `;
  }

  /**
   * Public method to toggle focus on text
   * @param {boolean} isFocus - Indicates if text has to be focused
   * @returns Returns nothing
   * @source
   */
  public toggleFocus(isFocus: boolean): void {
    this._htmlElement?.setAttribute("tabindex", "-1");
    if (isFocus) {
      this._htmlElement?.focus();
      this._htmlElement?.classList.add("show-title-focus-visible");
    } else {
      this._htmlElement?.classList.remove("show-title-focus-visible");
      this._htmlElement?.focus();
    }
  }

  /**
   * Constructor of class {@link CustomText | CustomText}
   * @param {TextTagNames} tagName - Tag name of text component. See {@link Src/Components.TextTagNames | TextTagNames}
   * @param {string} textId - Id of text to display
   * @param {boolean | undefined} noTranslate - Indicates if text has to be translated
   * @param {string[] | undefined} cssClasses - CSS classes of component
   * @param {string | undefined} labelFor - For attribute of text
   * @param {string | undefined} id - Id of component
   * @param {Map<string, string> | undefined} attributes - Attributes for component
   * @source
   */
  constructor(
    tagName: TextTagNames,
    textId: string,
    noTranslate?: boolean,
    cssClasses?: string[],
    labelFor?: string,
    id?: string,
    aria?: {
      hidden?: boolean;
      describedby?: string;
    },
    attributes?: Map<string, string>,
  ) {
    if (attributes == undefined) {
      attributes = new Map<string, string>();
    }
    if (aria) {
      if (aria.hidden != undefined) {
        attributes.set("aria-hidden", String(aria.hidden));
      }
      if (aria.describedby != undefined) {
        attributes.set("aria-describedby", aria.describedby);
      }
    }
    super(CustomText.name, textId, id, cssClasses, attributes, noTranslate);
    this._tagName = tagName;
    if (labelFor != undefined) {
      this._labelFor = labelFor;
    }
  }
}

new LisioComponentStyles(CustomText.name, customTextStyles);

export { CustomText };
