import LisioIconController from "../controllers/lisio-icons-controller";
import { LisioShowHideController } from "../controllers/lisio-show-hide-controller";
import LisioTranslationController from "../controllers/lisio-translation-controller";
import { LisioWidgetController } from "../controllers/lisio-widget-controller";
import { LisioIconNames } from "../enums/lisio-icon-names";
import LisioPopinNames from "../enums/lisio-popin-names";
import { LisioPopup } from "./lisio-popin-factory";
import LisioLightMessageManager from "../managers/lisio-light-message-manager";

interface LisioButtonMenu {
  className: string;
  color: string;
  iconDims: { width?: number; height?: number };
  iconName: LisioIconNames;
  lisioButtonId: string;
  menu: string;
  svgClassname?: string;
  titleId: string;
}

abstract class LisioPopin {
  private _name: LisioPopinNames;

  protected _buttonsMenus: LisioButtonMenu[] = [];
  protected _colorEco: string;
  protected _colorPrimary: string;
  protected _eventShortcutTo = 0;
  protected _isConfigured = false;
  protected _isPopinShow = true;
  protected _popinContainer: HTMLElement;
  protected _popup?: LisioPopup;
  protected _popupStyles: string;
  protected _scriptToExecute: (() => void) | undefined;
  protected _shortcutTo = "";
  protected _showHideController?: LisioShowHideController;
  protected _widget?: LisioWidgetController;

  constructor(
    popupStyles: string,
    colorPrimary: string,
    colorEco: string,
    name: LisioPopinNames,
    showHideControllerOptions: {
      backgroundColor: string;
      color: string;
      direction: "column" | "column-reverse";
    },
  ) {
    this._popupStyles = popupStyles;
    this._colorPrimary = colorPrimary;
    this._colorEco = colorEco;
    this._popinContainer = document.createElement("div");
    this._popinContainer.id = "lisio-popin";
    window.addEventListener("lisio-open-widget", (e) => {
      this.customEventHandler("accessibility-screen", e as CustomEvent);
    });
    window.addEventListener("lisio-open-widget-translator", (e) => {
      this.customEventHandler("translation-screen", e as CustomEvent);
    });
    window.addEventListener("lisio-open-widget-eco", (e) => {
      this.customEventHandler("eco-screen", e as CustomEvent);
    });
    window.addEventListener("lisio-lang-change", () => {
      LisioTranslationController.current.translatePopin(
        this._popinContainer,
        true,
        true,
      );
    });
    this._name = name;
    this._showHideController = new LisioShowHideController(
      this,
      showHideControllerOptions.backgroundColor,
      showHideControllerOptions.color,
      showHideControllerOptions.direction,
    );
  }

  public get eventShortcutTo(): number {
    return this._eventShortcutTo;
  }

  public get name() {
    return this._name;
  }

  public get popinContainer(): HTMLElement {
    return this._popinContainer;
  }

  public get popup() {
    return this._popup;
  }

  public get shortcutoTo(): string {
    return this._shortcutTo;
  }

  public get showHideController() {
    return this._showHideController;
  }

  public set widget(value: LisioWidgetController) {
    this._widget = value;
  }

  public attachListenerPopinButtons(parentElement: HTMLElement) {
    if (this._buttonsMenus.length > 0) {
      for (const lisioButtonMenu of this._buttonsMenus) {
        if (lisioButtonMenu.iconName !== LisioIconNames.HELP) {
          const buttons = parentElement.querySelectorAll(
            `.${lisioButtonMenu.className}`,
          );
          for (const button of buttons) {
            button.addEventListener("click", (e) =>
              this.shortcutTo(lisioButtonMenu.menu, (e as PointerEvent).detail),
            );
            button.addEventListener("keydown", (e) =>
              {
                if((e as KeyboardEvent).code === "Enter" || (e as KeyboardEvent).code === "Space" || (e as KeyboardEvent).code === "NumpadEnter"){
                  this.shortcutTo(lisioButtonMenu.menu, (e as PointerEvent).detail);
                }
              }
            );
          }
        }
      }
    } else {
      parentElement
        .querySelector(".openWidgetLisio")
        ?.addEventListener("click", (e) => {
          this.shortcutTo("accessibility-screen", (e as PointerEvent).detail);
        });
      parentElement
        .querySelector(".openWidgetLisio")
        ?.addEventListener("keydown", (e) => {
          if((e as KeyboardEvent).code === "Enter" || (e as KeyboardEvent).code === "Space" || (e as KeyboardEvent).code === "NumpadEnter"){
            this.shortcutTo("accessibility-screen", (e as PointerEvent).detail);
          }
        });
    }
  }

  public getPopupStyles(): string {
    return this._popupStyles;
  }

  public abstract initialize(mobileIconName: string): Promise<void>;

  public async refreshLabel(adaptation: boolean, isConfigured: boolean) {
    LisioTranslationController.current.translatePopin(
      this._popinContainer,
      isConfigured,
      adaptation,
    );
  }

  public shortcutTo(screenId: string, detail = 0) {
    if (this._widget?.isReady) {
      this._shortcutTo = screenId;
      this._eventShortcutTo = detail;
      this._widget?.openWidget();
      LisioLightMessageManager.current.sendShortcutMessageToIframe(screenId, detail);
    }
  }

  public showHidePopin() {
    if (this._popinContainer.classList.contains("lisio-hidden")) {
      this._isPopinShow = true;
      this._popinContainer.classList.remove("lisio-hidden");
    } else {
      this._isPopinShow = false;
      this._popinContainer.classList.add("lisio-hidden");
    }
  }

  public startPopin() {
    this._popinContainer.addEventListener("click", function (event) {
      event.stopPropagation();
    });
  }

  protected async getAnchorHTML(
    iconName: LisioIconNames,
    dims: { width?: number; height?: number },
    titleId: string,
    lisioAnchorId: string,
    color: string,
    anchorClassname: string,
    href: string,
  ): Promise<string> {
    //${icons(35, this._colorPrimary).main}
    return `
    <li style="list-style: none !important;">
        <a id="lisio-btn-${lisioAnchorId}" class="${anchorClassname} notranslate" href="${href}" title="${LisioTranslationController.current.getTranslation(
          titleId,
        )}">
            ${await LisioIconController.current.getIconHTML(iconName, dims, "", { color })}
        </a>
    </li>`;
  }

  protected async getButtonHTML(
    iconName: LisioIconNames,
    dims: { width?: number; height?: number },
    titleId: string,
    lisioButtonId: string,
    color: string,
    buttonClassname: string,
    svgClassname?: string,
  ): Promise<string> {
    //${icons(35, this._colorPrimary).main}
    return `
    <li style="list-style: none !important;">
        <button id="lisio-btn-${lisioButtonId}" class="${buttonClassname} notranslate" title="${LisioTranslationController.current.getTranslation(
          titleId,
        )}" aria-label="${LisioTranslationController.current.getTranslation(
          titleId,
        )}" >
            ${await LisioIconController.current.getIconHTML(iconName, dims, "popin", { color, className: svgClassname })}
        </button>
    </li>`;
  }

  private customEventHandler(screenId: string, { detail }: CustomEvent): void {
    let numberDetail = detail;
    if (detail) {
      if (
        typeof detail === "object" &&
        Object.prototype.hasOwnProperty.call(detail, "event_detail")
      ) {
        numberDetail = detail.event_detail;
      }
    }
    this.shortcutTo(screenId, numberDetail);
  }
}

export {LisioPopin};
