import popupStyles from "../assets/css/shadowroot/popup/lisio-popup.css?raw";
import LisioTranslationController from "../controllers/lisio-translation-controller";
import { LisioIconNames } from "../enums/lisio-icon-names";

interface LisioIconListItem {
  className: string;
  color: string;
  iconDims: { height?: number; width?: number };
  iconName: LisioIconNames;
  isHidden: boolean;
  lisioPanelInfoItemId: string;
  textId: string;
}

abstract class LisioPopup {
  protected _hidePopup = false;
  protected _iconListItems: LisioIconListItem[] = [];
  protected _onClose: () => void;
  protected _popup: HTMLElement;
  protected _popupContainer: HTMLDivElement;
  protected abstract _sideOffset: number;

  constructor(onCloseCallback: () => void) {
    const rawHidePopup = localStorage.getItem("lisio-hidePopUp");
    if (rawHidePopup != undefined) {
      const { expiration } = JSON.parse(rawHidePopup);
      this._hidePopup = new Date() < new Date(expiration);
      if (!this._hidePopup) {
        localStorage.removeItem("lisio-hidePopUp");
      }
    }
    this._onClose = onCloseCallback;
    this._popup = document.createElement("div");
    this._popupContainer = document.createElement("div");
    this._popupContainer.id = "lisio-popup-container";
    this._popupContainer.append(this._popup);
    window.addEventListener("lisio-widget-open", () => {
      this.closePopUp();
    });
    window.addEventListener("lisio-lang-change", (event) => {
      if (event instanceof CustomEvent) {
        LisioTranslationController.current.translatePopup(this._popup);
      }
    });
  }

  public get hidePopup(): boolean {
    return this._hidePopup;
  }

  public get popupContainer(): HTMLDivElement {
    return this._popupContainer;
  }

  public closePopUp() {
    const expirationDate = new Date();
    expirationDate.setDate(
      expirationDate.getDate() + Number(import.meta.env.VITE_EXPIRATION_POPUP),
    );
    const hidePopUp = {
      expiration: expirationDate.toISOString(),
    };
    localStorage.setItem("lisio-hidePopUp", JSON.stringify(hidePopUp));
    this._hidePopup = true;
    this._popupContainer.remove();
    this._onClose();
  }

  public async startPopup(
    posY: string,
    posX: string,
    colorPrimary: string,
    _colorEco: string,
    isCompensation: boolean,
  ) {
    this._popupContainer.style.top = `calc(${posY} + 20px)`;
    const rightOrLeft: "right" | "left" = posX == "R" ? "right" : "left";
    this._popupContainer.classList.add(rightOrLeft);
    this._popupContainer.style[rightOrLeft] = `${this._sideOffset}px`;
    const borderSide: string = posX == "R" ? "left" : "right";
    const justifyContentStartOrEnd: string = posX == "R" ? "start" : "end";
    const colorPrimaryRGBA: string =
      colorPrimary
        .match(/[0-9,a,b,c,d,e,f]{2}/gi)
        ?.map((c) => Math.round(parseInt(c, 16) * 0.7 + 255 * 0.3))
        .join(", ") || "";

    await this.getHTML(
      justifyContentStartOrEnd,
      borderSide,
      colorPrimaryRGBA,
      colorPrimary,
      isCompensation,
    );

    const buttonClosePopup = this._popup.querySelector(
      "#lisio-popup-info-close",
    );

    if (buttonClosePopup != null) {
      buttonClosePopup.addEventListener("click", () => this.closePopUp());
    }

    window.addEventListener("resize", () => this.topCorrection());
  }

  public topCorrection(): void {
    const { top, bottom, height } =
      this._popupContainer.getBoundingClientRect();
    if (top < 0) {
      this._popupContainer.style.top = `${height / 2}px`;
    } else if (bottom > window.innerHeight) {
      this._popupContainer.style.top = "";
      this._popupContainer.style.bottom = `-${height / 2}px`;
    }
  }

  protected abstract getHTML(
    justifyContentStartOrEnd: string,
    borderSide: string,
    colorPrimaryRGBA: string,
    colorPrimary: string,
    isCompensation: boolean,
  ): Promise<void>;

  protected abstract listItemBuilder(
    iconName: LisioIconNames,
    iconDim: { height?: number; width?: number },
    color: string,
    lisioPanelInfoItemId: string,
    textId: string,
    className: string,
    isHidden: boolean,
  ): Promise<string>;
}

export { LisioPopup, popupStyles };

export type { LisioIconListItem };
