/**
 * @mergeTarget
 * @module Src/Screens/Daltonism
 */

import {
  DatltonismOptions,
  defautValueOfNumericParameters,
  LisioCategoryNames,
  LisioNumericParameterNames,
  LisioParameterNames,
  LisioProfileNames,
  LisioStringParameterNames,
  LisioUser,
} from "@lisio/lisio-profils";
import { LisioScreen } from "../lisio-screen";
import { ElementsContainer } from "../../components/containers/elements-container/elements-container";
import { CustomImage } from "../../components/custom-image/custom-image";
import { CustomText } from "../../components/custom-text/custom-text";
import {
  BooleanParameterRenderObject,
  StringParameterRenderObject,
  NumberParameterRenderObject,
  ComponentAndPosition,
  CategoryRenderObject,
  ProfileRenderObject,
  ScreenNames,
} from "../screen-types";
import { AccessibilityScreen } from "../accessibility/accessibility-screen";
import { LisioComponent } from "@lisio/lisio-engine";
import { UserController } from "../../../controllers/user-controller";
import { CustomRange } from "../../components/inputs/range/custom-range";

/**
 * Class representing a daltonism screen component extending LisioScreen.\
 * It aims to represent a daltonism screen component.\
 * A daltonism screen component is basically a component to render all comfort categories, profiles and parameters.\
 */
class DaltonismScreen extends LisioScreen {
  /**
   * 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>();

  /**
   * Protected attribute to store parameter render objects
   * @source
   */
  protected _parameterRenderObjects: Map<
    LisioParameterNames,
    | BooleanParameterRenderObject
    | StringParameterRenderObject
    | NumberParameterRenderObject
  > = new Map<
    LisioParameterNames,
    | BooleanParameterRenderObject
    | StringParameterRenderObject
    | NumberParameterRenderObject
  >([
    [
      LisioStringParameterNames.DALTONISM,
      {
        type: "string",
        name: LisioStringParameterNames.DALTONISM,
        items: Object.values(DatltonismOptions).map((datltonismOption) => {
          return {
            textId: datltonismOption.replace(/_/, "-"),
            value: datltonismOption,
            isChecked: false,
          };
        }),
        position: 0,
        cssClasses: ["secondary", "row"],
      } as StringParameterRenderObject,
    ],
    [
      LisioNumericParameterNames.DALTONISM_R,
      {
        type: "number",
        name: LisioNumericParameterNames.DALTONISM_R,
        buttonId: "range-daltonism-r",
        titleId: "range-daltonism-r",
        defaultValue: defautValueOfNumericParameters.get(
          LisioNumericParameterNames.DALTONISM_R
        ),
        currentValue: 100,
        minValue: 10,
        maxValue: 190,
        step: 2,
        position: 0,
        cssClasses: [],
        icon: {
          fileName: "misc-icons",
          iconName: "Color",
        },
        iconClasses: ["primary"],
      } as NumberParameterRenderObject,
    ],
    [
      LisioNumericParameterNames.DALTONISM_G,
      {
        type: "number",
        name: LisioNumericParameterNames.DALTONISM_G,
        buttonId: "range-daltonism-g",
        titleId: "range-daltonism-g",
        defaultValue: defautValueOfNumericParameters.get(
          LisioNumericParameterNames.DALTONISM_G
        ),
        currentValue: 100,
        minValue: 10,
        maxValue: 190,
        step: 2,
        position: 0,
        cssClasses: [],
        icon: {
          fileName: "misc-icons",
          iconName: "Color",
        },
        iconClasses: ["primary"],
      } as NumberParameterRenderObject,
    ],
    [
      LisioNumericParameterNames.DALTONISM_B,
      {
        type: "number",
        name: LisioNumericParameterNames.DALTONISM_B,
        buttonId: "range-daltonism-b",
        titleId: "range-daltonism-b",
        defaultValue: defautValueOfNumericParameters.get(
          LisioNumericParameterNames.DALTONISM_B
        ),
        currentValue: 100,
        minValue: 10,
        maxValue: 190,
        step: 2,
        position: 0,
        cssClasses: [],
        icon: {
          fileName: "misc-icons",
          iconName: "Color",
        },
        iconClasses: ["primary"],
      } as NumberParameterRenderObject,
    ],
    [
      LisioNumericParameterNames.DALTONISM_HUE,
      {
        type: "number",
        name: LisioNumericParameterNames.DALTONISM_HUE,
        buttonId: "range-daltonism-hue",
        titleId: "range-daltonism-hue",
        defaultValue: defautValueOfNumericParameters.get(
          LisioNumericParameterNames.DALTONISM_HUE
        ),
        currentValue: 0,
        minValue: -180,
        maxValue: 180,
        step: 2,
        position: 0,
        cssClasses: [],
        icon: {
          fileName: "misc-icons",
          iconName: "Hue",
        },
        iconClasses: ["primary"],
      } as NumberParameterRenderObject,
    ],
    [
      LisioNumericParameterNames.DALTONISM_SATURATION,
      {
        type: "number",
        name: LisioNumericParameterNames.DALTONISM_SATURATION,
        buttonId: "range-daltonism-saturation",
        titleId: "range-daltonism-saturation",
        defaultValue: defautValueOfNumericParameters.get(
          LisioNumericParameterNames.DALTONISM_SATURATION
        ),
        currentValue: 100,
        minValue: 10,
        maxValue: 190,
        step: 2,
        position: 0,
        cssClasses: [],
        icon: {
          fileName: "misc-icons",
          iconName: "Saturation",
        },
        iconClasses: ["primary"],
      } as NumberParameterRenderObject,
    ],
    [
      LisioNumericParameterNames.DALTONISM_BRIGHTNESS,
      {
        type: "number",
        name: LisioNumericParameterNames.DALTONISM_BRIGHTNESS,
        buttonId: "range-daltonism-brightness",
        titleId: "range-daltonism-brightness",
        defaultValue: defautValueOfNumericParameters.get(
          LisioNumericParameterNames.DALTONISM_BRIGHTNESS
        ),
        currentValue: 100,
        minValue: 50,
        maxValue: 150,
        step: 2,
        position: 0,
        cssClasses: [],
        icon: {
          fileName: "misc-icons",
          iconName: "Brightness",
        },
        iconClasses: ["primary"],
      } as NumberParameterRenderObject,
    ],
  ]);

  /**
   * @async
   * Public method implementing abstract method render of LisioComponent
   * @returns Returns a promise containing the representation of a daltonism screen in HTML string
   * @source
   */
  public async render(): Promise<string> {
    return `
    <section id="${this._id}">
      <children></children>
      <form id="daltonism-form-test" action="" method="post" style="margin-top:1.5rem;display:flex;flex-direction:column;align-items:center;padding-inline:1rem;">
        <label for="daltonism-form-test-input">
          <span>Cette personnalisation vous a-t-elle été utile ? <strong>Une fois vos réglages terminés</strong> dites-nous :</span><br><span>facilité d’utilisation, type de daltonisme (si connu) et satisfaction du résultat.</span>
        </label>

        <textarea id="daltonism-form-test-input" name="daltonism-form-test-input" style='width:100%;max-width:100%;min-height:120px;margin-top:20px;font-family:"Calibri", sans-serif;border-radius:10px;'></textarea>

        <p aria-hidden="true" style="display:none;background-color:#eaffe7;padding:10px;border-radius:10px;border:2px solid #cdefc8;">
          Votre retour a bien été envoyé ! Lisio vous remercie pour votre contribution 😊
        </p>

        <input
          type="submit"
          value="Envoyer"
          style="padding:0.5rem;margin-top:20px;border-radius:1000rem;cursor:pointer;border:none;background-color:var(--lisio-color-primary);color:white;margin-bottom:10px;"
        />
      </form>
    </section>
    `;
  }

  public postRender(): void {
    const form = this._htmlElement!.querySelector("#daltonism-form-test") as HTMLFormElement;
    form!.addEventListener("submit", async (e)=>{
      e.preventDefault();
      const formData = new FormData();
      formData.append("daltonism-form-test-input", (form?.querySelector("#daltonism-form-test-input") as HTMLInputElement).value);
      if(UserController.current.currentUser?.customParameters){
        Array.from(UserController.current.currentUser.customParameters)
          .filter(element => ["daltonism_r","daltonism_g","daltonism_b","daltonism_hue","daltonism_saturation","daltonism_brightness"].includes(element[0]))
          .map(element => {return {name: element[0], value: element[1].value}})
          .forEach(element => {
            formData.append(element.name, element.value as string);
          });
      }
      await fetch("https://env-preprod-mobiledition.lisio.fr/daltonisme/daltonisme2.php", {
        method: "POST",
        body: formData,
      });
      form.reset();
      form.querySelector("p")?.style.setProperty("display", "block");
      form.querySelector("p")?.setAttribute("aira-hidden", "false");
    })
  }

  /**
   * Constructor of class {@link DaltonismScreen | DaltonismScreen}
   * @param {LisioUser | undefined} user - Current user
   * @source
   */
  constructor(user?: LisioUser) {
    ScreenNames[DaltonismScreen.name] = "daltonism-screen";
    super(
      DaltonismScreen.name,
      DaltonismScreen.name,
      LisioCategoryNames.DALTONISM,
      AccessibilityScreen.name,
    );

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

    const parametersElements: ComponentAndPosition[] = this.initParameters(
      Array.from(this._parameterRenderObjects.keys()),
      [],
      user?.customParameters,
    );
    parametersElements.sort((a, b) => a.position - b.position);
    const ishihara: LisioComponent = new CustomImage(
      "./assets/imgs/ishihara.png",
      {
        id: "alt-ishihara-test",
      },
      ["img-ishihara"]
    );
    const ishiharaSubText: LisioComponent = new CustomText(
      "p",
      "ishihara-subtext",
      false,
      ["small"],
    );
    // const firstTextSection: LisioComponent = new ElementsContainer(
    //   [
    //     new CustomText(
    //       "p",
    //       "infobox-daltonism",
    //       false,
    //       ["info-text"],
    //       undefined,
    //       "infobox-daltonism",
    //     ),
    //   ],
    //   undefined,
    //   ["column", "width-100", "secondary", "infobox"],
    // );
    // const radioParametersElement = parametersElements.filter((parameterElement)=>parameterElement.component.componentName === "CustomChoice");
    const rangeParametersElement = parametersElements.filter((parameterElement)=>parameterElement.component.componentName === CustomRange.name);


    const elementsContainer2: LisioComponent = new ElementsContainer(
      [
        ...rangeParametersElement.map(
          (parameterELement) => parameterELement.component,
        ),
      ],
      undefined,
      ["full", "secondary", "custom-ranges-container"],
    );
    const elementsContainer3: LisioComponent = new ElementsContainer(
      [
        ishihara,
        ishiharaSubText
      ],
      undefined,
      ["column", "full", "secondary", "ishihara-section"],
    );
    this._children?.push(
      elementsTitleContainer,
      // firstTextSection,
      // elementsContainer,
      elementsContainer2,
      elementsContainer3,
    );
  }
}

export { DaltonismScreen };
