/**
 * @mergeTarget
 * @module Src/Screens/Dyslexia
 */
import {
  LisioCategoryNames,
  LisioParameterNames,
  LisioProfileNames,
  LisioStringParameterNames,
  LisioUser,
} from "@lisio/lisio-profils";
import { LisioScreen } from "../lisio-screen";
import { ElementsContainer } from "../../components/containers/elements-container/elements-container";
import { TextsContainer } from "../../components/containers/texts-container/texts-container";
import { CustomText } from "../../components/custom-text/custom-text";
import {
  BooleanParameterRenderObject,
  StringParameterRenderObject,
  NumberParameterRenderObject,
  ComponentAndPosition,
  CategoryRenderObject,
  ProfileRenderObject,
  ScreenNames,
} from "../screen-types";
import { ListContainer } from "../../components/containers/list-container/list-container";
import { ComfortScreen } from "../comfort/comfort-screen";
import { LisioComponent } from "@lisio/lisio-engine";

/**
 * Class representing a dyslexia screen component extending LisioScreen.\
 * It aims to represent a dyslexia screen component.\
 * A dyslexia screen component is basically a component to render all dyslexia categories, profiles and parameters.\
 */
class DyslexiaScreen extends LisioScreen {
  /**
   * Private attribute to store exemple id
   */
  private _exampleId: string = "lisio-dyslexia-example-text";

  /**
   * Protected attribute to store category render objects
   * @source
   */
  protected _categoryRenderObjects: Map<
    LisioCategoryNames,
    CategoryRenderObject
  > = new Map<LisioCategoryNames, CategoryRenderObject>();

  /**
   * Protected attribute to store profile render objects
   * @source
   */
  protected _profileRenderObjects: Map<LisioProfileNames, ProfileRenderObject> =
    new Map<LisioProfileNames, ProfileRenderObject>([
      [
        LisioProfileNames.UNDERLINE,
        {
          buttonId: "dyslexia-underline",
          titleId: "dyslexia-underline-button",
          position: 0,
          name: LisioProfileNames.UNDERLINE,
          value: false,
          cssClasses: ["width-100", "btn-pill", "secondary", "space-between"],
          infoBoxes: [
            {
              textId: "infobox-underline",
              cssClassesText: ["info-text"],
            },
          ],
        } as ProfileRenderObject,
      ],
    ]);

  /**
   * Protected attribute to store parameter render objects
   * @source
   */
  protected _parameterRenderObjects: Map<
    LisioParameterNames,
    | BooleanParameterRenderObject
    | StringParameterRenderObject
    | NumberParameterRenderObject
  > = new Map<
    LisioParameterNames,
    | BooleanParameterRenderObject
    | StringParameterRenderObject
    | NumberParameterRenderObject
  >([
    [
      LisioStringParameterNames.UNDERLINE_RED,
      {
        type: "string",
        name: LisioStringParameterNames.UNDERLINE_RED,
        titleId: "highlight-red-title",
        items: [],
        position: 0,
        aria: {
          describedby: this._exampleId,
        },
      } as StringParameterRenderObject,
    ],
    [
      LisioStringParameterNames.UNDERLINE_GREEN,
      {
        type: "string",
        name: LisioStringParameterNames.UNDERLINE_GREEN,
        titleId: "highlight-green-title",
        items: [],
        position: 1,
        aria: {
          describedby: this._exampleId,
        },
      } as StringParameterRenderObject,
    ],
    [
      LisioStringParameterNames.UNDERLINE_BLUE,
      {
        type: "string",
        name: LisioStringParameterNames.UNDERLINE_BLUE,
        titleId: "highlight-blue-title",
        items: [],
        position: 2,
        aria: {
          describedby: this._exampleId,
        },
      } as StringParameterRenderObject,
    ],
  ]);

  /**
   * @async
   * Public method implementing abstract method render of LisioComponent
   * @returns Returns a promise containing the representation of a dyslexia screen in HTML string
   * @source
   */
  public async render(): Promise<string> {
    return `
      <section id="${this._id}">
        <children></children>
      </section>
      `;
  }

  /**
   * Constructor of class {@link DyslexiaScreen | DyslexiaScreen}
   * @param {LisioProfileNames[]} profileNames - Profiles to include in this screen
   * @param {LisioParameterNames[]} parameterNames - Parameters to include in this screen
   * @param {LisioUser | undefined} user - Current user
   * @source
   */
  constructor(
    profileNames: LisioProfileNames[],
    hiddenProfileNames: LisioProfileNames[],
    parameterNames: LisioParameterNames[],
    user?: LisioUser,
  ) {
    ScreenNames[DyslexiaScreen.name] = "dyslexia-screen";
    super(
      DyslexiaScreen.name,
      DyslexiaScreen.name,
      LisioCategoryNames.DYSLEXIA_COMFORT,
      ComfortScreen.name,
    );
    const profileElements: ComponentAndPosition[] = this.initProfiles(
      profileNames,
      hiddenProfileNames,
      user?.profiles,
    );
    profileElements.sort((a, b) => a.position - b.position);
    const profileElementsContainer: LisioComponent = new ListContainer(
      [...profileElements.map((profileElement) => profileElement.component)],
      undefined,
      ["column", "width-100", "secondary"],
    );

    const elementsTitleContainer: LisioComponent = new ElementsContainer(
      [
        this.createScreenSubtitle("comfort-title"),
        this.createScreenTitle("dyslexia-title"),
      ],
      undefined,
      ["column gap-0"],
    );

    const parametersElements: ComponentAndPosition[] = this.initParameters(
      parameterNames,
      [],
      user?.customParameters,
    );
    parametersElements.sort((a, b) => a.position - b.position);
    const parameterElementsContainer: LisioComponent = new ElementsContainer(
      [
        ...parametersElements.map((parameterELement) => {
          return parameterELement.component;
        }),
      ],
      undefined,
      ["column", "width-100", "secondary"],
    );
    this._children?.push(
      elementsTitleContainer,
      new ElementsContainer(
        [
          new TextsContainer(
            [
              new CustomText("p", "dyslexia-text-1"),
              new CustomText("p", "dyslexia-text-2"),
            ],
            ["padding-x"],
          ),
        ],
        this._exampleId,
        ["secondary", "infobox", "width-100"],
      ),
      parameterElementsContainer,
      profileElementsContainer,
    );
  }
}

export { DyslexiaScreen };
