import { LisioBooleanParameterNames } from "@lisio/lisio-profils";

import styles from "../assets/css/shadowroot/lisio-reading-mask.css?raw";
import LisioShadowRootController from "../controllers/lisio-shadow-root-controller";
import LisioMessageManager from "../managers/lisio-message-manager";
import LisioTextTreeWalker from "../walkers/lisio-text-tree-walker";
import LisioAdapter from "./lisio-adapter";

/**
 * Class representing a reading mask adapter extending an adapter.\
 * It aims to represents the font style functionality of Lisio.\
 * A reading mask adapter is basically a functionality of Lisio which will change the reading mask of texts in the main page.\
 */
class LisioReadingMask extends LisioAdapter<boolean> {
  private _mask: HTMLElement;
  private _mouseMoveHandlerBind = this.mouseMoveHandler.bind(this);
  private _keyDownHandlerBind = this.keyDownHandler.bind(this);

  constructor() {
    super();
    this._mask = document.createElement("div");
    this._mask.classList.add("lisio-mask", "lisio-hidden");
    const p = document.createElement("p");
    p.innerHTML =
      "Pour quitter : cliquez sur la page, puis appuyer sur &Eacutechap";
    p.id = "lisio-echap";
    this._mask.appendChild(p);
  }

  /**
   * 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: boolean): void {
    // for(const tag of walker.tags.values()){
    //   this.adaptFunction(tag, value);
    // }
    this.adaptFunction(document.body, value);
  }

  protected adaptFunction(_element: HTMLElement, value: boolean): void {
    if (value) {
      LisioShadowRootController.current.appendElement(this._mask, styles);
      //si le mask est activé on ajoute les listener
      this._mask.classList.remove("lisio-hidden");
      window.addEventListener("mousemove", this._mouseMoveHandlerBind);
      window.addEventListener("keydown", this._keyDownHandlerBind);
    } else {
      this._mask.classList.add("lisio-hidden");
      window.removeEventListener("mousemove", this._mouseMoveHandlerBind);
      window.removeEventListener("keydown", this._keyDownHandlerBind);
      LisioShadowRootController.current.removeElement(this._mask, styles);
    }
  }

  private keyDownHandler(event: KeyboardEvent) {
    if (
      event.key.toLowerCase() === "escape" ||
      event.key.toLowerCase() === "esc"
    ) {
      LisioMessageManager.current.sendDisableParameter(
        LisioBooleanParameterNames.READING_MASK,
      );
    }
  }

  private mouseMoveHandler(event: MouseEvent) {
    this._mask.style.top = `${event.clientY - this._mask.offsetHeight / 2}px`;
  }
}

export default LisioReadingMask;
