import { GlobalContext } from "../global-context";
import fr from "../assets/langs/fr.json";

class LisioTranslationController {
  private static _current: LisioTranslationController;

  private _currentLangISO = "fr";
  private _oldTranslations: Map<string, Translations> = new Map<
    string,
    Translations
  >();
  private _rtlLangs = ["ar", "yi", "he", "ps"];
  private _translations: Translations = fr;
  private _translationsFolder: string;

  private constructor() {
    this._oldTranslations.set("fr", this._translations);
    this._translationsFolder = `${import.meta.env.VITE_LISIO_DOMAIN}/solution/dist-${__BUILD_TARGET__ === "extension" ? "ext" : "site"}/langs/`;
  }

  public static get current() {
    if (!this._current) {
      this._current = new LisioTranslationController();
    }
    return this._current;
  }

  public get currentLangISO() {
    return this._currentLangISO;
  }

  public set currentLangISO(iso: string) {
    this._currentLangISO = iso;
  }

  public getDirection(): string {
    return this._rtlLangs.includes(this._currentLangISO) ? "rtl" : "ltr";
  }

  public getTranslation(textId: string): string {
    const translation: string | undefined = this._translations[textId];
    if (translation == undefined) {
      throw new Error(`No translation found for id : ${textId}`);
    } else {
      return translation;
    }
  }

  public async loadTranslationFile(langISO: string): Promise<void> {
    if (this._currentLangISO !== langISO) {
      const oldTranslations = this._oldTranslations.get(langISO);
      this._currentLangISO = langISO;
      if (oldTranslations == undefined) {
        const tradPopinFile = `${this._translationsFolder}${langISO}.json`;
        const response = await fetch(tradPopinFile);
        this._translations = await response.json();
        this._oldTranslations.set(langISO, this._translations);
      } else {
        this._translations = oldTranslations;
      }
    }
  }

  public translateBanner(bannerText: HTMLElement) {
    bannerText.innerHTML = this.getTranslation("disable");
  }

  public translateList(list: HTMLElement) {
    for (const [selector, textId] of [
      ["#lisio-list-title", "listTitle"],
      ["#lisio-list-link", "listLink"],
    ]) {
      const elements = list.querySelectorAll<HTMLElement>(selector);
      const langDir = this.getDirection();
      for (const element of elements) {
        element.innerHTML = this.getTranslation(textId);
        element.dir = langDir;
      }
    }
  }

  public translatePopin(
    popin: HTMLElement,
    isConfigured: boolean,
    adaptation: boolean,
  ) {
    popin.title = this.getTranslation("lisioBtnWidget");
    popin.ariaLabel = this.getTranslation("lisioBtnWidget");
    const boutonTranslator: string =
      isConfigured && !adaptation ? "lisioBtnParam" : "lisioBtnTranslator";
    const boutonEco: string =
      isConfigured && !adaptation ? "lisioBtnParam" : "lisioBtnEco";
    const boutonOpen: string =
      isConfigured && !adaptation ? "lisioBtnParam" : "lisioBtnWidget";
    for (const [selector, textId] of [
      [".openWidgetLisio", boutonOpen],
      ["#lisio-btn-translator", boutonTranslator],
      // [".openWidgetTranslatorLisio", boutonTranslator],
      ["#lisio-btn-eco", boutonEco],
      // [".openWidgetEcoLisio", boutonEco],
      [".openLinkLisio", "lisioBtnLink"],
    ]) {
      const elements = popin.querySelectorAll(selector);
      for (const element of elements) {
        for (const attribute of ["title", "aria-label"]) {
          element.setAttribute(attribute, this.getTranslation(textId));
        }
      }
    }
  }

  public translatePopup(popup: HTMLElement) {
    const isPopin2024: boolean =
      GlobalContext.current.popinName.includes("2024");

    for (const [selector, textId] of [
      ["p#popup-header-title", "popin2025_popupTitle"],
      ["p#popup-header-subtitle", "popin2025_popupSubtitle"],
      [
        "p#lisio-popup-info-translator",
        isPopin2024 ? "popinTrad" : "popin2025_popupTranslation",
      ],
      [
        "p#lisio-popup-info-widget",
        isPopin2024 ? "popinAccess" : "popin2025_popupAccess",
      ],
      [
        "p#lisio-popup-info-eco",
        isPopin2024 ? "popinEco" : "popin2025_popupEco",
      ],
      ["p#lisio-popup-info-management", "managementTitle"],
      ["button#lisio-popup-info-close span", "popin2025_popupClose"],
      ["span#footer-text-popup", "popin2025_popupLisio"],
      ["span#popup-new-tab", "popin2025_newTab"],
      ["lisio-compensation-text", "popupCompensation"],
      ["lisio-popup-info-close", "closePopUp"],
    ]) {
      const elements = popup.querySelectorAll<HTMLElement>(selector);
      const langDir = this.getDirection();
      for (const element of elements) {
        element.innerHTML = this.getTranslation(textId);
        element.dir = langDir;
      }
    }
  }

  public translateShowHide(icon: HTMLElement, textId: string) {
    icon.setAttribute("aria-label", this.getTranslation(textId));
  }

  public translateWidget(widget: HTMLIFrameElement) {
    widget.title = this.getTranslation("iframeTitle");
  }

  public translateSpeechSynthesisButtons() {
    if (
      document.documentElement.classList.contains(
        "lisio-vocal-synthesis-reading",
      )
    ) {
      for (const button of document.querySelectorAll(".start-synth")) {
        button.setAttribute(
          "aria-label",
          this.getTranslation("pauseSynthButton"),
        );
      }
    } else if (
      document.documentElement.classList.contains(
        "lisio-vocal-synthesis-active",
      )
    ) {
      document
        .querySelector(".start-synth-first")
        ?.setAttribute(
          "aria-label",
          this.getTranslation("startSynthFirstButton"),
        );
      for (const button of document.querySelectorAll(
        ".start-synth:not(.start-synth-first)",
      )) {
        button.setAttribute(
          "aria-label",
          this.getTranslation("startSynthButton"),
        );
      }
    }
  }

  public translateModal(
    closeButton: HTMLElement,
    modalContainer: HTMLElement,
    title: HTMLElement | undefined,
    headerTitleTextId: string,
    isTitleVisible: boolean,
  ) {
    closeButton.setAttribute(
      "aria-label",
      this.getTranslation("confirmation-modal-close"),
    );
    if (isTitleVisible) {
      title!.innerText = this.getTranslation(headerTitleTextId);
    } else {
      modalContainer.setAttribute(
        "aria-label",
        this.getTranslation(headerTitleTextId),
      );
    }
  }

  public translateDicoModal(notFoundText: HTMLElement | undefined) {
    if (notFoundText) {
      notFoundText.innerText = this.getTranslation("dico-no-definition-found");
    }
  }
}

type Translations = Record<string, string>;

export default LisioTranslationController;
