/**
 * @mergeTarget
 * @module Src/Screens/Home
 */
import {
  LisioBooleanParameterNames,
  LisioCategoryNames,
  LisioParameterNames,
  LisioProfileNames,
} from "@lisio/lisio-profils";
import { LisioScreen } from "../lisio-screen";
import { Group } from "../../../versions/widget-version";
import { UserController } from "../../../controllers/user-controller";
import {
  BooleanParameterRenderObject,
  StringParameterRenderObject,
  NumberParameterRenderObject,
  ComponentAndPosition,
  CategoryRenderObject,
  ProfileRenderObject,
  VisualCategoryNames,
  MergedCategoriesNames,
  ScreenNames,
} from "../screen-types";
import { ListContainer } from "../../components/containers/list-container/list-container";
import { homeScreenStyles } from "./home-screen.css";
import { AccessibilityScreen } from "../accessibility/accessibility-screen";
import { ComfortScreen } from "../comfort/comfort-screen";
import { TranslationScreen } from "../translation/translation-screen";
import { SynthScreen } from "../synth/synth-screen";
import { EcoScreen } from "../eco/eco-screen";
import { RuralScreen } from "../rural/rural-screen";
import { SettingsScreen } from "../settings/settings-screen";
import { UsersScreen } from "../users/users-screen";
import { ResetScreen } from "../reset/reset-screen";
import { LisioComponent, LisioComponentStyles } from "@lisio/lisio-engine";
import { MoreScreen } from "../more/more-screen";

/**
 * Class representing a home screen component extending LisioScreen.\
 * It aims to represent a home screen component.\
 * A home screen component is basically a component to render all home categories, profiles and parameters.\
 */
class HomeScreen extends LisioScreen {
  /**
   * Protected attribute to store category render objects
   * @source
   */
  protected _categoryRenderObjects: Map<
    MergedCategoriesNames,
    CategoryRenderObject
  > = new Map<MergedCategoriesNames, CategoryRenderObject>([
    [
      LisioCategoryNames.ACCESSIBILITY,
      {
        buttonId: "accessibility",
        icon: {
          fileName: "misc-icons",
          iconName: "Human",
        },
        titleId: "accessibility-title",
        subtitleId: "accessibility-subtitle",
        nextScreenName: AccessibilityScreen.name,
        position: 0,
        isActive: false,
        activeSubObjects: new Set(),
        firstIconClasses: ["primary"],
        iconsClasses: ["grey"],
        cssClasses: ["secondary", "button-category"],
      },
    ],
    [
      LisioCategoryNames.COMFORT,
      {
        buttonId: "comfort",
        icon: {
          fileName: "misc-icons",
          iconName: "Computer",
        },
        titleId: "comfort-title",
        subtitleId: "comfort-subtitle",
        nextScreenName: ComfortScreen.name,
        position: 1,
        isActive: false,
        activeSubObjects: new Set(),
        firstIconClasses: ["primary"],
        iconsClasses: ["grey"],
        cssClasses: ["secondary", "button-category"],
      },
    ],
    [
      LisioCategoryNames.GOOGLE_TRANSLATION,
      {
        buttonId: "translation",
        icon: {
          fileName: "trans-icons",
          iconName: "fr",
        },
        titleId: "translation-title",
        // subtitleId: "translation-subtitle",
        nextScreenName: TranslationScreen.name,
        position: 3,
        isActive: false,
        activeSubObjects: new Set(),
        iconsClasses: ["grey"],
        firstIconClasses: ["trans-icon primary"],
        cssClasses: ["secondary", "button-category"],
      },
    ],
    [
      LisioCategoryNames.DEEPL_TRANSLATION,
      {
        buttonId: "translation",
        icon: {
          fileName: "trans-icons",
          iconName: "fr",
        },
        titleId: "translation-title",
        // subtitleId: "translation-subtitle",
        nextScreenName: TranslationScreen.name,
        position: 3,
        isActive: false,
        activeSubObjects: new Set(),
        iconsClasses: ["grey"],
        firstIconClasses: ["trans-icon primary"],
        cssClasses: ["secondary", "button-category"],
      },
    ],
    [
      LisioCategoryNames.SPEECH_SYNTHESIS,
      {
        buttonId: "synth",
        icon: {
          fileName: "misc-icons",
          iconName: "Speak",
        },
        titleId: "synth-title",
        nextScreenName: SynthScreen.name,
        position: 4,
        isActive: false,
        activeSubObjects: new Set(),
        firstIconClasses: ["primary"],
        iconsClasses: ["grey"],
        cssClasses: ["secondary", "button-category"],
      },
    ],
    [
      LisioCategoryNames.ECOLOGICAL,
      {
        buttonId: "eco",
        icon: {
          fileName: "misc-icons",
          iconName: "Leaf",
        },
        titleId: "eco-title",
        subtitleId: "ecological-subtitle",
        nextScreenName: EcoScreen.name,
        position: 5,
        isActive: false,
        activeSubObjects: new Set(),
        firstIconClasses: ["primary"],
        iconsClasses: ["grey"],
        cssClasses: ["secondary", "button-category"],
      },
    ],
    [
      LisioCategoryNames.LIGHT_ECOLOGICAL,
      {
        buttonId: "eco",
        icon: {
          fileName: "misc-icons",
          iconName: "Dark",
        },
        titleId: "light-eco-title",
        subtitleId: "light-ecological-subtitle",
        nextScreenName: EcoScreen.name,
        position: 5,
        isActive: false,
        activeSubObjects: new Set(),
        firstIconClasses: ["primary"],
        iconsClasses: ["grey"],
        cssClasses: ["secondary", "button-category"],
      },
    ],
    [
      LisioCategoryNames.RURAL,
      {
        buttonId: "network",
        icon: {
          fileName: "misc-icons",
          iconName: "Network",
        },
        titleId: "rural-title",
        nextScreenName: RuralScreen.name,
        position: 5,
        isActive: false,
        activeSubObjects: new Set(),
        firstIconClasses: ["primary"],
        iconsClasses: ["grey"],
        cssClasses: ["secondary", "button-category"],
      },
    ],
    [
      LisioCategoryNames.SETTINGS,
      {
        buttonId: "settings",
        icon: {
          fileName: "misc-icons",
          iconName: "Settings",
        },
        titleId: "settings-title",
        nextScreenName: SettingsScreen.name,
        position: 7,
        isActive: false,
        activeSubObjects: new Set(),
        firstIconClasses: ["primary"],
        iconsClasses: ["grey"],
        cssClasses: ["secondary", "button-category"],
      },
    ],
    [
      VisualCategoryNames.USERS,
      {
        buttonId: "users",
        icon: {
          fileName: "misc-icons",
          iconName: "User",
        },
        titleId: "users-title",
        nextScreenName: UsersScreen.name,
        position: 8,
        isActive: false,
        activeSubObjects: new Set(),
        firstIconClasses: ["primary"],
        iconsClasses: ["grey"],
        cssClasses: ["secondary", "button-category"],
      },
    ],
    [
      VisualCategoryNames.RESET,
      {
        buttonId: "reset",
        icon: {
          fileName: "misc-icons",
          iconName: "Reset",
        },
        titleId: "reset-title",
        nextScreenName: ResetScreen.name,
        position: 10,
        isActive: false,
        activeSubObjects: new Set(),
        iconsClasses: ["red"],
        cssClasses: ["secondary", "button-category"],
      },
    ],
    [
      VisualCategoryNames.MORE,
      {
        buttonId: `${this.id}-more`,
        icon: {
          fileName: "footer-icons",
          iconName: "More",
        },
        titleId: "more-button",
        nextScreenName: MoreScreen.name,
        position: 10,
        isActive: false,
        activeSubObjects: new Set(),
        firstIconClasses: [""],
        iconsClasses: ["grey"],
        cssClasses: ["secondary", "footer-button", "button-category"],
      },
    ],
  ]);

  /**
   * Protected attribute to store profile render objects
   * @source
   */
  protected _profileRenderObjects: Map<LisioProfileNames, ProfileRenderObject> =
    new Map<LisioProfileNames, ProfileRenderObject>([
      [
        LisioProfileNames.LOW_NETWORK,
        {
          buttonId: "network",
          icon: {
            fileName: "misc-icons",
            iconName: "Network",
          },
          titleId: "rural-title",
          name: LisioProfileNames.LOW_NETWORK,
          position: 2,
          value: false,
          cssClasses: ["width-100", "btn-pill", "secondary"],
          infoBoxes: [
            {
              textId: "infobox-low-network",
              cssClassesText: ["info-text"],
            },
          ],
        },
      ],
      [
        LisioProfileNames.ECOLO,
        {
          buttonId: "eco",
          icon: {
            fileName: "misc-icons",
            iconName: "Leaf",
          },
          titleId: "eco-title",
          subTitleId: "ecological-subtitle",
          name: LisioProfileNames.LOW_NETWORK,
          position: 2,
          value: false,
          cssClasses: ["width-100", "btn-pill", "secondary"],
          infoBoxes: [
            {
              textId: "infobox-ecolo",
              cssClassesText: ["info-text"],
            },
          ],
        },
      ],
    ]);

  /**
   * Protected attribute to store parameter render objects
   * @source
   */
  protected _parameterRenderObjects: Map<
    LisioParameterNames,
    | BooleanParameterRenderObject
    | StringParameterRenderObject
    | NumberParameterRenderObject
  > = new Map<
    LisioParameterNames,
    | BooleanParameterRenderObject
    | StringParameterRenderObject
    | NumberParameterRenderObject
  >([
    [
      LisioBooleanParameterNames.IS_ACTIVE,
      {
        buttonId: "adaptation",
        titleId: "adaptation-disabled",
        activeTitleId: "adaptation-enabled",
        name: LisioBooleanParameterNames.IS_ACTIVE,
        position: 9,
        cssClasses: ["width-100", "btn-pill", "secondary"],
        infoBoxes: [
          {
            textId: "infobox-adaptation",
            cssClassesText: ["info-text"],
          },
        ],
      } as BooleanParameterRenderObject,
    ],
  ]);

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

  /**
   * Constructor of class {@link HomeScreen | HomeScreen}
   * @param {Group[]} groups - Groups to display in this screen
   * @source
   */
  constructor(isCompensation: boolean, isFlag: boolean, groups: Group[]) {
    ScreenNames[HomeScreen.name] = "home-screen";
    super(HomeScreen.name, HomeScreen.name);
    if (isFlag) {
      this._categoryRenderObjects.get(
        LisioCategoryNames.GOOGLE_TRANSLATION,
      )!.icon!.iconName = "fr";
      this._categoryRenderObjects.get(
        LisioCategoryNames.DEEPL_TRANSLATION,
      )!.icon!.iconName = "fr";
      this._categoryRenderObjects.get(
        LisioCategoryNames.GOOGLE_TRANSLATION,
      )!.icon!.fileName = "trans-icons";
      this._categoryRenderObjects.get(
        LisioCategoryNames.DEEPL_TRANSLATION,
      )!.icon!.fileName = "trans-icons";
      this._categoryRenderObjects
        .get(LisioCategoryNames.GOOGLE_TRANSLATION)!
        .firstIconClasses?.push("border-flags");
      this._categoryRenderObjects
        .get(LisioCategoryNames.DEEPL_TRANSLATION)!
        .firstIconClasses?.push("border-flags");
    } else {
      this._categoryRenderObjects.get(
        LisioCategoryNames.GOOGLE_TRANSLATION,
      )!.icon!.iconName = "trad";
      this._categoryRenderObjects.get(
        LisioCategoryNames.DEEPL_TRANSLATION,
      )!.icon!.iconName = "trad-deepl";
      this._categoryRenderObjects.get(
        LisioCategoryNames.GOOGLE_TRANSLATION,
      )!.icon!.fileName = "misc-icons";
      this._categoryRenderObjects.get(
        LisioCategoryNames.DEEPL_TRANSLATION,
      )!.icon!.fileName = "misc-icons";
    }
    const homeContainerChildren: LisioComponent[] = [];
    for (const group of groups) {
      const categoriesElements: ComponentAndPosition[] = this.initCategories(
        group.categories,
      );
      const profilesElements: ComponentAndPosition[] = this.initProfiles(
        group.profiles,
        [],
        UserController.current?.currentUser?.profiles,
      );
      const parametersElements: ComponentAndPosition[] = this.initParameters(
        group.parameters,
        [],
        UserController.current?.currentUser?.customParameters,
      );
      const groupElements: ComponentAndPosition[] = categoriesElements
        .concat(profilesElements)
        .concat(parametersElements);
      groupElements.sort((a, b) => a.position - b.position);

      const groupContainer: LisioComponent = new ListContainer(
        groupElements.map((group) => group.component),
        undefined,
        ["lines-h", "column", "full", "secondary"],
      );
      homeContainerChildren.push(groupContainer);
    }

    homeContainerChildren.push(...this.createFooter(isCompensation));
    const homeContainer = new ListContainer(
      homeContainerChildren,
      "home-container",
      ["column", "screen-ul", "home", "width-100"],
    );
    if (__BUILD_TARGET__ === "site") {
      this._children?.push(this.createScreenSubtitle("home-title"));
    }
    this._children?.push(
      this.createScreenTitle("home-title", "h1"),
      homeContainer,
    );
  }
}

new LisioComponentStyles(ScreenNames[HomeScreen.name], homeScreenStyles);

export { HomeScreen };
