import LisioStyleSheetController from "../controllers/lisio-stylesheet-controller";
import LisioDicoModal from "../controllers/modals/lisio-dico-modal";
import LisioCSSProperties from "../enums/lisio-css-properties";
import LisioMessageManager from "../managers/lisio-message-manager";
import LisioTextTreeWalker from "../walkers/lisio-text-tree-walker";
import LisioAdapter from "./lisio-adapter";

/**
 * Class representing a dictionary adapter extending an adapter.\
 * It aims to represents the font style functionality of Lisio.\
 * A dictionary adapter is basically a functionality of Lisio which will change the dictionary of texts in the main page.\
 */
class LisioDictionaryAdapter extends LisioAdapter<boolean> {
  private _dictionaryTimeout = -1;
  private _isEnabled = false;
  private _query?: string;
  private _dicoModal: LisioDicoModal;
  private _boundedDef: ()=>void;

  public get dicoModal() {
    return this._dicoModal;
  }

  constructor() {
    super();
    this._dicoModal = new LisioDicoModal();
    this._boundedDef = this.findDef.bind(this);
  }

  public get query() {
    return this._query;
  }

  /**
   * 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(walker: LisioTextTreeWalker, value: boolean): void {
    if (value && !this._isEnabled) {
      this._isEnabled = true;
      document.addEventListener("selectionchange", this._boundedDef);
      document.documentElement.style.userSelect = "auto";
      document.documentElement.style.webkitUserSelect = "auto";
      LisioStyleSheetController.current.insertRule(
        ".lisio-cursor-help",
        new Map([[LisioCSSProperties.CURSOR, "help"]]),
      );
    } else {
      this._isEnabled = false;
      //document.getSelection().removeAllRanges();
      document.removeEventListener("selectionchange", this._boundedDef);
      document.documentElement.style.userSelect = "";
      document.documentElement.style.webkitUserSelect = "";
      LisioStyleSheetController.current.removeRule(".lisio-cursor-help");
    }
    for (const tag of walker.tags.values()) {
      this.adaptFunction(tag, value);
    }
  }

  protected adaptFunction(element: HTMLElement, value: boolean): void {
    if (element.textContent?.trim() != "" && element instanceof HTMLElement) {
      //on enlève les noeuds vides
      if (
        element.localName != "i" &&
        element.localName != "script" &&
        element.localName != "style" &&
        !element.className.includes("icon")
      ) {
        //on vérifie si le texte est pas déjà stocké
        if (value) {
          element.classList.add("lisio-cursor-help");
        } else {
          element.classList.remove("lisio-cursor-help");
        }
      }
    }
  }

  private findDef() {
    if (this._dictionaryTimeout != null) {
      clearTimeout(this._dictionaryTimeout);
    }
    this._dictionaryTimeout = setTimeout(() => {
      const str = document.getSelection()?.toString().trim().toLowerCase();
      const normalizedStr =
        str?.normalize == undefined ? str : str.normalize("NFD");
      this._query = normalizedStr
        ?.replace(/\s+/g, " ")
        .split(" ")
        .slice(0, 3)
        .join(" ");
      if (
        this._query != undefined &&
        this._query.length > 1 &&
        /[a-zA-Z]+/g.test(this._query)
      ) {
        // LisioMessageManager.current.sendEncodeProfilesMessage();
        const selection = document.getSelection();
        if (
          selection?.anchorNode?.parentElement != undefined &&
          selection.anchorNode.nodeType === Node.TEXT_NODE
        ) {
          this._dicoModal.triggerer = selection.anchorNode.parentElement;
        } else if (
          selection?.anchorNode?.parentElement != undefined &&
          selection.anchorNode.nodeType === Node.ELEMENT_NODE
        ) {
          this._dicoModal.triggerer = selection.anchorNode as HTMLElement;
        }
        LisioMessageManager.current.sendDicoAPI(this._query);
      }
    }, 1000);
  }
}

export default LisioDictionaryAdapter;
