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

import {
  LisioCategoryNames,
  LisioProfileNames,
  LisioParameterNames,
  LisioBooleanParameterNames,
  LisioStringParameterNames,
  LisioNumericParameterNames,
} from "@lisio/lisio-profils";
import { CategoryComponent } from "../components/category/category-component";
import { InfoBoxRenderObject } from "../components/component-types";
import { LisioComponent } from "@lisio/lisio-engine";

/**
 * Enumerator for categories which not including Lisio functionality
 * @source
 */
enum VisualCategoryNames {
  USERS = "users",
  MANAGEMENT = "management",
  RESET = "reset",
  MORE = "more",
}

/**
 * Type describes the differents categories merged
 */
type MergedCategoriesNames = VisualCategoryNames | LisioCategoryNames;

/**
 * Type describes a component and his position in screen
 */
type ComponentAndPosition = {
  component: LisioComponent;
  position: number;
};

/**
 * Type describes all piece of informations to render a category
 */
type CategoryRenderObject = {
  buttonId: string;
  icon?: {
    fileName: string;
    iconName: string;
  };
  titleId: string;
  subtitleId?: string;
  nextScreenName: string;
  position: number;
  isActive: boolean;
  component?: CategoryComponent;
  activeSubObjects: Set<
    MergedCategoriesNames | LisioProfileNames | LisioParameterNames
  >;
  iconsClasses?: string[];
  firstIconClasses?: string[];
  cssClasses?: string[];
  categoryName?: MergedCategoriesNames;
  parentScreenName?: string;
};

/**
 * Type describes all piece of informations to render a profile
 */
type ProfileRenderObject = {
  buttonId: string;
  titleId: string;
  subTitleId?: string;
  activeTitleId?: string;
  name: LisioProfileNames;
  value: boolean;
  icon?: {
    fileName: string;
    iconName: string;
  };
  iconClasses?: string[];
  position: number;
  categoryName?: MergedCategoriesNames;
  parentScreenName?: string;
  cssClasses?: string[];
  aria?: {
    label?: {
      noTranslate?: boolean;
      id: string;
    };
    hidden?: boolean;
    checked?: boolean;
    describedby?: string;
  };
  infoBoxes?: InfoBoxRenderObject[];
  additionalCss?: string[];
};

/**
 * Type describes all piece of informations to render a boolean parameter
 */
type BooleanParameterRenderObject = {
  name: LisioBooleanParameterNames;
  buttonId: string;
  titleId: string;
  subTitleId?: string;
  activeTitleId?: string;
  value: boolean;
  icon?: {
    fileName: string;
    iconName: string;
  };
  iconClasses?: string[];
  position: number;
  categoryName?: MergedCategoriesNames;
  parentScreenName?: string;
  cssClasses?: string[];
  aria?: {
    label?: {
      noTranslate?: boolean;
      id: string;
    };
    hidden?: boolean;
    checked?: boolean;
    describedby?: string;
  };
  infoBoxes?: InfoBoxRenderObject[];
  additionalCss?: string[];
};

/**
 * Type describes all piece of informations to render a string parameter as a text input
 */
type StringParameterItemRenderObject = {
  textId: string;
  value: string;
  isChecked: boolean;
  icon?: {
    fileName: string;
    iconName: string;
  };
  iconClasses?: string[];
  cssClasses?: string[];
  noTranslate?: boolean;
  noText?: boolean;
};

/**
 * Type describes all piece of informations to render a string parameter as a choice list
 */
type StringParameterRenderObject = {
  name: LisioStringParameterNames;
  items: StringParameterItemRenderObject[];
  defaultText?: string;
  position: number;
  titleId?: string;
  cssClasses?: string[];
  cssClassesItems?: string[];
  cssClassesLabelItems?: string[];
  aria?: {
    label?: {
      noTranslate?: boolean;
      id: string;
    };
    hidden?: boolean;
    checked?: boolean;
    describedby?: string;
  };
};

/**
 * Type describes all piece of informations to render a numeric parameter
 */
type NumberParameterRenderObject = {
  name: LisioNumericParameterNames;
  buttonId: string;
  titleId: string;
  defaultValue: number;
  currentValue: number;
  minValue: number;
  maxValue: number;
  step: number;
  position: number;
  categoryName?: MergedCategoriesNames;
  parentScreenName?: string;
  cssClasses?: string[];
  icon?: {
    fileName: string;
    iconName: string;
  };
  iconClasses?: string[];
};

/**
 * Dynamic enumerator describes all screen names and a comprehensible equivalent
 */
const ScreenNames: { [key: string]: string } = {};

/**
 * Enumerator describes all language ISO with corresponding icon name
 * @source
 */
enum ISOToIcon {
  FR = "fr",
  EN = "en",
  ES = "es",
  IT = "it",
  DE = "de",
  JA = "ja",
  RU = "ru",
  ZH_CN = "zh",
  AR = "ar",
  PT = "pt",
  CA = "ca",
  KO = "ko",
  DA = "da",
  FI = "fi",
  CY = "cy",
  EL = "el",
  HE = "he",
  HI = "hi",
  NL = "nl",
  NO = "no",
  NB = "nb",
  SV = "sv",
  CS = "cs",
  TH = "th",
  TR = "tr",
  UK = "uk",
  VI = "vi",
  YI = "he",
  LB = "lb",
  PS = "ps",
  BG = "bg",
  ET = "et",
  HU = "hu",
  LV = "lv",
  LT = "lt",
  PL = "pl",
  RO = "ro",
  SK = "sk",
  SL = "sl",
  EN_GB = "en",
  EN_US = "en_us",
  PT_PT = "pt",
  PT_BR = "pt_br",
  ID = "id",
  ZH = "zh",
  OC = "oc",
  BR = "br",
  CO = "co",
  EU = "eu",
  MFE = "mfe",
}

export type {
  ComponentAndPosition,
  CategoryRenderObject,
  ProfileRenderObject,
  BooleanParameterRenderObject,
  StringParameterRenderObject,
  StringParameterItemRenderObject,
  NumberParameterRenderObject,
  MergedCategoriesNames,
};
export { VisualCategoryNames, ScreenNames, ISOToIcon };
