import LisioStyleSheetController from "../../controllers/lisio-stylesheet-controller";
import LisioCSSProperties from "../../enums/lisio-css-properties";
import { appendToHead } from "../../utils";
import LisioTextTreeWalker from "../../walkers/lisio-text-tree-walker";
import LisioAdapter from "../lisio-adapter";

/**
 * Class representing a google translation adapter extending an adapter.\
 * It aims to represents the font style functionality of Lisio.\
 * A google translation adapter is basically a functionality of Lisio which will change the google translation of texts in the main page.\
 */
class LisioGoogleTranslationAdapter extends LisioAdapter<string> {
  private _scriptGoogleTrans: HTMLScriptElement;
  private _tradButtonsGoogle: HTMLAnchorElement[] = [];

  constructor() {
    super();
    this._scriptGoogleTrans = document.createElement("script");
    this._scriptGoogleTrans.id = "googleTradScript";
    this._scriptGoogleTrans.setAttribute("type", "text/javascript");
    this._scriptGoogleTrans.src =
      "https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit";
  }

  /**
   * Public method implementing abstract method adapt of Adapter
   * @param {LisioTextTreeWalker} walker - A walker to explore the DOM
   * @param {string} value - Value of the functionality
   * @returns Returns nothing
   * @source
   */
  public adapt(_: LisioTextTreeWalker, value: string): void {
    const domainCookieName = window.location.host;
    // document.cookie = `googtrans=; domain=${domainCookieName}; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC;`;
    // document.cookie = `googtrans=; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC;`;
    this.eraseAllGoogtransCookies();
    const originLang = document.documentElement.lang == undefined ? "fr" : document.documentElement.lang;
    if (
      value != "default" && (!value.includes(document.documentElement.lang) || document.documentElement.lang === "")
    ) {
      if (!document.querySelector("script#googleTradScript")) {
        this._scriptGoogleTrans.addEventListener("load", () => {
          const stylesBody = window.getComputedStyle(document.body);
          const topBody = stylesBody.getPropertyValue("top");
          const minHeightBody = stylesBody.getPropertyValue("min-height");
          const positionBody = stylesBody.getPropertyValue("position");
          LisioStyleSheetController.current.insertRule(
            `body`,
            new Map<string, string>([
              [LisioCSSProperties.TOP, topBody],
              [LisioCSSProperties.MIN_HEIGHT, minHeightBody],
              [LisioCSSProperties.POSITION, positionBody],
            ]),
          );
          LisioStyleSheetController.current.insertRule(
            `.goog-te-banner-frame`,
            new Map<string, string>([[LisioCSSProperties.DISPLAY, "none"]]),
          );
          LisioStyleSheetController.current.insertRule(
            `iframe#\\:0\\.container`,
            new Map<string, string>([[LisioCSSProperties.DISPLAY, "none"]]),
          );
          LisioStyleSheetController.current.insertRule(
            `#goog-gt-tt`,
            new Map<string, string>([[LisioCSSProperties.DISPLAY, "none"]]),
          );
          LisioStyleSheetController.current.insertRule(
            `.VIpgJd-yAWNEb-VIpgJd-fmcmS-sn54Q`,
            new Map<string, string>([
              [LisioCSSProperties.BOX_SHADOW, "none"],
              [LisioCSSProperties.BACKGROUND_COLOR, "transparent"],
            ]),
          );
          LisioStyleSheetController.current.insertRule(
            `iframe.VIpgJd-ZVi9od-ORHb-OEVmcd`,
            new Map<string, string>([[LisioCSSProperties.DISPLAY, "none"]]),
          );
          LisioStyleSheetController.current.insertRule(
            `.VIpgJd-ZVi9od-aZ2wEe-wOHMyf`,
            new Map<string, string>([[LisioCSSProperties.DISPLAY, "none"]]),
          );
          LisioStyleSheetController.current.insertRule(
            `.VIpgJd-ZVi9od-aZ2wEe-OiiCO`,
            new Map<string, string>([[LisioCSSProperties.TRANSFORM, "none"]]),
          );
          document.cookie = `googtrans=/${originLang}/${value.replace("_","-")}; domain=${domainCookieName}; path=/`;
          const interval = setInterval(() => {
            //@ts-expect-error google trans
            if (google.translate.TranslateElement != undefined) {
              clearInterval(interval);
              //@ts-expect-error google trans
              google.translate.TranslateElement(
                {
                  pageLanguage:
                    document.documentElement.lang == undefined
                      ? "fr"
                      : document.documentElement.lang,
                  autoDisplay: false,
                },
                "google_translate_element",
              );
            }
          }, 100);
        });
        appendToHead(this._scriptGoogleTrans);
      } else {
        if (this._tradButtonsGoogle.length === 0) {
          const googleButtons = document
            .querySelector<HTMLIFrameElement>(
              "iframe:not(#\\:0\\.container).skiptranslate"
            )
            ?.contentDocument?.querySelector<HTMLElement>("#\\:1\\.menuBody")
            ?.querySelectorAll<HTMLAnchorElement>("a");
          if (googleButtons != undefined) {
            this._tradButtonsGoogle = Array.from(googleButtons);
          }
        }
        const confirm = document.querySelector("iframe#\\:0\\.container")
          ? document
              .querySelector<HTMLIFrameElement>("iframe#\\:0\\.container")
              ?.contentDocument?.querySelector<HTMLElement>("#\\:0\\.confirm")
          : undefined;
        if (confirm != undefined) {
          confirm.dispatchEvent(new Event("click"));
        }
        setTimeout(() => {
          const langLink = this._tradButtonsGoogle.find(
            (a) => Object.getOwnPropertyDescriptor(a, "value")?.value === value.replace("_","-"),
          );
          langLink?.dispatchEvent(new Event("click"));
        }, 1000);
      }
    } else if (
      value != "default" &&
      document.querySelector("iframe#\\:0\\.container") != undefined
    ) {
      const stylesBody = window.getComputedStyle(document.body);
      const topBody = stylesBody.getPropertyValue("top");
      LisioStyleSheetController.current.insertRule(
        `body`,
        new Map<string, string>([
          [LisioCSSProperties.TOP, `calc(${topBody} - 40px)`],
        ]),
      );
      LisioStyleSheetController.current.insertRule(
        `.goog-te-banner-frame`,
        new Map<string, string>([[LisioCSSProperties.DISPLAY, "none"]]),
      );
      LisioStyleSheetController.current.insertRule(
        `iframe#\\:0\\.container`,
        new Map<string, string>([[LisioCSSProperties.DISPLAY, "none"]]),
      );
      LisioStyleSheetController.current.insertRule(
        `#goog-gt-tt`,
        new Map<string, string>([[LisioCSSProperties.DISPLAY, "none"]]),
      );
      LisioStyleSheetController.current.insertRule(
        `.VIpgJd-yAWNEb-VIpgJd-fmcmS-sn54Q`,
        new Map<string, string>([
          [LisioCSSProperties.BOX_SHADOW, "none"],
          [LisioCSSProperties.BACKGROUND_COLOR, "transparent"],
        ]),
      );
      LisioStyleSheetController.current.insertRule(
        `.VIpgJd-ZVi9od-aZ2wEe-wOHMyf`,
        new Map<string, string>([[LisioCSSProperties.DISPLAY, "none"]]),
      );
      LisioStyleSheetController.current.insertRule(
        `.VIpgJd-ZVi9od-aZ2wEe-OiiCO`,
        new Map<string, string>([[LisioCSSProperties.TRANSFORM, "none"]]),
      );
      document
        .querySelector<HTMLIFrameElement>("iframe#\\:0\\.container")
        ?.contentDocument?.querySelector<HTMLElement>("#\\:0\\.restore")
        ?.dispatchEvent(new Event("click"));
    } else if (document.querySelector("iframe#\\:0\\.container") != undefined) {
      // document.cookie = `googtrans=; domain=${domainCookieName}; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC;`;
      // document.cookie = `googtrans=; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC;`;
      this.eraseAllGoogtransCookies();
      this._scriptGoogleTrans.remove();
      window.location.reload();
    }
  }

  protected adaptFunction(element: HTMLElement, value: string): void {
    if (value === "true") {
      //si activé
      if (
        element.firstElementChild != null &&
        element.firstElementChild.localName == "img"
      ) {
        element.firstElementChild.classList.add("lisio-highlight");
        LisioStyleSheetController.current.replaceImportantInStyleAttribute(
          [
            LisioCSSProperties.COLOR,
            LisioCSSProperties.BACKGROUND,
            LisioCSSProperties.BACKGROUND_COLOR,
            LisioCSSProperties.BOX_SHADOW,
            LisioCSSProperties.BORDER,
          ],
          element.firstElementChild as HTMLElement,
        );
      } else {
        element.classList.add("lisio-highlight");
        LisioStyleSheetController.current.replaceImportantInStyleAttribute(
          [
            LisioCSSProperties.COLOR,
            LisioCSSProperties.BACKGROUND,
            LisioCSSProperties.BACKGROUND_COLOR,
            LisioCSSProperties.BOX_SHADOW,
            LisioCSSProperties.BORDER,
          ],
          element as HTMLElement,
        );
      }
    } else {
      //sinon on supprime les classes
      if (
        element.firstElementChild != null &&
        element.firstElementChild.localName == "img"
      ) {
        element.firstElementChild.classList.remove("lisio-highlight");
      } else {
        element.classList.remove("lisio-highlight");
      }
    }
  }

  public eraseAllGoogtransCookies() {
    const cookieName = "googtrans";
    const domainParts = window.location.hostname.split(".");
    const paths = ["/", ""];

    // Générer tous les domaines possibles (ex: lisio.fr, .lisio.fr, env-preprod.lisio.fr, etc)
    const domainsToTry = [];

    // Ajouter domaine complet (ex: www.env-preprod.lisio.fr)
    domainsToTry.push(window.location.hostname);

    // Ajouter domaines parents avec un point devant
    for (let i = 1; i < domainParts.length - 1; i++) {
      domainsToTry.push("." + domainParts.slice(i).join("."));
    }

    // Ajouter le domaine racine sans point (ex: lisio.fr)
    if (domainParts.length >= 2) {
      domainsToTry.push(domainParts.slice(-2).join("."));
    }

    // Supprimer cookie pour chaque combinaison domaine + path
    domainsToTry.forEach((domain) => {
      paths.forEach((path) => {
        document.cookie = `${cookieName}=; domain=${domain}; path=${path}; expires=Thu, 01 Jan 1970 00:00:00 GMT;`;
        // Aussi essayer sans domain pour le cookie sur domaine exact
        if (path === paths[0]) {
          document.cookie = `${cookieName}=; path=${path}; expires=Thu, 01 Jan 1970 00:00:00 GMT;`;
        }
      });
    });

    // En bonus, tenter aussi de supprimer sans domain + path vide
    document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT;`;
  }
}

export default LisioGoogleTranslationAdapter;
