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 stop animation adapter extending an adapter.\
 * It aims to represents the font style functionality of Lisio.\
 * A stop animation adapter is basically a functionality of Lisio which will change the stop animation of texts in the main page.\
 */
class LisioStopAnimationAdapter extends LisioAdapter<boolean> {
  /**
   * Public method implementing abstract method adapt of Adapter
   * @param {LisioTextTreeWalker} walker - A walker to explore the DOM
   * @param {boolean} value - Value of the functionality
   * @returns Returns nothing
   * @source
   */
  public adapt(walker: LisioTextTreeWalker, value: boolean): void {
    for (const tag of walker.tags.values()) {
      this.adaptFunction(tag, value);
    }

    if (value) {
      LisioStyleSheetController.current.insertRule(
        ".lisio-stop-animation",
        new Map<LisioCSSProperties, string>([
          [LisioCSSProperties.TRANSITION_DURATION, "0s"],
          [LisioCSSProperties.ANIMATION_DURATION, "0s"],
        ]),
      );
    } else {
      LisioStyleSheetController.current.removeRule(".lisio-stop-animation");
    }
  }

  protected adaptFunction(element: HTMLElement, value: boolean): void {
    const { transitionDuration, animationDuration } =
      window.getComputedStyle(element);
    const defaultB = element.dataset.lisioTransition;
    const defaultA = element.dataset.lisioAnimation;
    if (
      element.localName != "script" &&
      (transitionDuration != "0s" ||
        animationDuration != "0s" ||
        defaultB != null ||
        defaultA != null)
    ) {
      if (defaultA != undefined) {
        element.dataset.lisioAnimation = defaultA;
        element.dataset.lisioAnimationDuration = defaultA;
      }
      if (defaultB != undefined) {
        element.dataset.lisioTransition = defaultB;
        element.dataset.lisioTransitionDuration = defaultB;
      }
    }
    if (!value) {
      element.classList.remove(`lisio-stop-animation`);
    } else {
      LisioStyleSheetController.current.replaceImportantInStyleAttribute(
        [
          LisioCSSProperties.ANIMATION_DURATION,
          LisioCSSProperties.ANIMATION,
          LisioCSSProperties.TRANSITION_DURATION,
          LisioCSSProperties.TRANSITION,
        ],
        element,
      );
      element.classList.add(`lisio-stop-animation`);
    }
  }
}

export default LisioStopAnimationAdapter;
