/**
 * @mergeTarget
 * @module Src/Components/CustomInput/CustomTextInput
 */

import { LisioStringParameterNames } from "@lisio/lisio-profils";
import { CustomText } from "../../custom-text/custom-text";
import { InputManager } from "../../../../managers/input-manager";
import { TextInput } from "./input/text-input";
import { customTextInputStyles } from "./custom-text-input.css";
import { LisioComponent, LisioComponentStyles } from "@lisio/lisio-engine";
import { MergedCategoriesNames } from "../../../screens/screen-types";
import { TranslationController } from "../../../../controllers/translation/translation-controller";

/**
 * Class representing a text field component extending LisioComponent.\
 * It aims to represent a text field component.\
 * A text field component is basically a component to display a checkbox input as a text field.\
 */
class CustomTextInput extends LisioComponent {
  /**
   * Private attribute to store input
   * @source
   */
  private _input: TextInput;

  /**
   * @async
   * Public method implementing abstract method render of LisioComponent
   * @returns Returns a promise containing the representation of a text field in HTML string
   * @source
   */
  public async render(): Promise<string> {
    return `
        <div class="text-input-container ${this.renderClasses()}">
          <children></children>
        </div>
        <div class="text-input-container ${this.renderClasses()}"></div>
      `;
  }

  /**
   * Public method to set value of a text field
   * @param {string} value - New value of input
   * @returns Returns nothing
   */
  public setValue(value: string): void {
    if (this._htmlElement == undefined) {
      this._input.value = value;
    } else {
      (this._input.htmlElement as HTMLInputElement).value = value;
    }
  }

  /**
   * Constructor of class {@link CustomTextInput | CustomTextInput}
   * @param {LisioStringParameterNames.UNDERLINE_RED | LisioStringParameterNames.UNDERLINE_GREEN | LisioStringParameterNames.UNDERLINE_BLUE | "rename-user"} parameterName - Name of functionality
   * @param {string} value - Value of input
   * @param {string} screenName - Screen name including this input
   * @param {MergedCategoriesNames | undefined} categoryName - Category name containing parameter or profile related to this input
   * @param {string | undefined} parentScreenName - Parent screen name in screen tree
   * @param {string | undefined} titleId - Title id of text
   * @param {string[] | undefined} cssClasses - CSS classes of component
   * @param {object | undefined} aria - Aria attributes
   * @property {object | undefined} aria.label - Aria label datas
   * @property {boolean | undefined} aria.label.noTranslate - Indicates if label need to be translated
   * @property {string} aria.label.id - Id of the text for aria label
   * @property {boolean | undefined} aria.hidden - Aria hidden
   * @property {string | undefined} aria.controls - Arria controls
   * @property {boolean | undefined} aria.checked - Aria checked
   * @property {boolean | undefined} aria.hasPopup - Aria hasPopu
   * @source
   */
  constructor(
    parameterName:
      | LisioStringParameterNames.UNDERLINE_RED
      | LisioStringParameterNames.UNDERLINE_GREEN
      | LisioStringParameterNames.UNDERLINE_BLUE
      | "rename-user",
    value: string,
    screenName: string,
    categoryName?: MergedCategoriesNames,
    parentScreenName?: string,
    titleId?: string,
    cssClasses?: string[],
    aria?: {
      label?: {
        noTranslate?: boolean;
        id: string;
      };
      hidden?: boolean;
      controls?: string;
      checked?: boolean;
      hasPopup?: string;
      describedby?: string;
    },
  ) {
    const attributes: Map<string, string> = new Map<string, string>();
    if (aria) {
      if (aria.label) {
        attributes.set(
          "aria-label",
          aria.label.noTranslate
            ? aria.label.id
            : TranslationController.current.getTranslation(aria.label.id),
        );
      }
      if (aria.hidden != undefined) {
        attributes.set("aria-hidden", String(aria.hidden));
      }
      if (aria.controls) {
        attributes.set("aria-controls", aria.controls);
      }
      if (aria.checked != undefined) {
        attributes.set("aria-checked", String(aria.checked));
      }
      if (aria.hasPopup) {
        attributes.set("aria-haspopup", aria.hasPopup);
      }
    }
    super(CustomTextInput.name, undefined, cssClasses, attributes);

    const handler = (_: any) => {};

    this._input = new TextInput(
      value,
      parameterName,
      handler,
      `${parameterName}-input`,
      screenName,
      categoryName,
      parentScreenName,
      undefined,
      undefined,
      aria,
    );
    this._children.push(
      this._input,
      new CustomText(
        "label",
        titleId == undefined ? "default" : titleId,
        undefined,
        undefined,
        `${parameterName}-input`.replace(/_/g, "-"),
        `${parameterName}-description`.replace(/_/g, "-"),
      ),
    );
    if (parameterName != "rename-user" && value != "") {
      InputManager.current.addOrRemoveEnabledInput(parameterName, true);
    }
  }
}

new LisioComponentStyles(CustomTextInput.name, customTextInputStyles);

export { CustomTextInput };
