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

/**
 * Class representing a contrast adapter extending an adapter.\
 * It aims to represents the font style functionality of Lisio.\
 * A contrast adapter is basically a functionality of Lisio which will change the contrast of texts in the main page.\
 */
class LisioContrastAdapter extends LisioAdapter<number> {
  /**
   * Public method implementing abstract method adapt of Adapter
   * @param {LisioTextTreeWalker} walker - A walker to explore the DOM
   * @param {number} value - Value of the functionality
   * @returns Returns nothing
   * @source
   */
  public adapt(_: LisioTextTreeWalker, value: number): void {
    this.adaptFunction(document.documentElement, value);
  }

  protected adaptFunction(element: HTMLElement, value: number): void {
    const numericValue: number = value >= 1 ? value / 10 : value;
    let svg = document.querySelector("#lisio-svg");
    let matrice = document.querySelector("#lisio-svg feColorMatrix");
    if (svg == undefined) {
      const filter = document.createElementNS(
        "http://www.w3.org/2000/svg",
        "filter",
      );
      svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
      matrice = document.createElementNS(
        "http://www.w3.org/2000/svg",
        "feColorMatrix",
      );
      svg.setAttribute("height", "0");
      svg.id = "lisio-svg";
      filter.id = "filter";
      document.body.appendChild(svg);
      document.querySelector<HTMLElement>("#lisio-svg")?.appendChild(filter);
      document.querySelector<HTMLElement>("#filter")?.appendChild(matrice);
    }

    LisioStyleSheetController.current.replaceImportantInStyleAttribute(
      [LisioCSSProperties.FILTER],
      element,
    );
    if (numericValue === 1) {
      LisioStyleSheetController.current.removeRule(".lisio-filters");
      element.classList.remove("lisio-filters");
    } else {
      element.classList.add("lisio-filters");
      LisioStyleSheetController.current.removeRule(".lisio-filters");
      LisioStyleSheetController.current.insertRule(
        ".lisio-filters",
        new Map([
          [
            LisioCSSProperties.FILTER,
            `url(#lisio-filter) contrast(${numericValue})`,
          ],
        ]),
      );
    }
  }
}

export default LisioContrastAdapter;
