import { GlobalConfig } from "../../config/GlobalConfig";
import { EventEmiter } from "../../event/EventEmiter";
import { PopsElementHandler } from "../../handler/PopsElementHandler";
import { PopsHandler } from "../../handler/PopsHandler";
import { PopsInstHandler } from "../../handler/PopsInstHandler";
import { PopsCSS } from "../../PopsCSS";
import { PopsInstData } from "../../PopsInst";
import type { PopsType } from "../../types/main";
import { popsDOMUtils } from "../../utils/PopsDOMUtils";
import { popsUtils } from "../../utils/PopsUtils";
import { PopsIframeDefaultConfig } from "./defaultConfig";
import type { PopsIframeClickEventConfig, PopsIframeConfig } from "./types";

export const PopsIframe = {
  init(__config__: PopsIframeConfig) {
    const guid = popsUtils.getRandomGUID();
    // 设置当前类型
    const popsType: PopsType = "iframe";

    let config = PopsIframeDefaultConfig();
    config = popsUtils.assign(config, GlobalConfig.getGlobalConfig());
    config = popsUtils.assign(config, __config__);
    if (config.url == null) {
      throw new TypeError("config.url must not be null.");
    }
    config = PopsHandler.handleOnly(popsType, config);

    const emitter =
      config.emitter ??
      new EventEmiter<{
        "pops:iframe-min": (eventConfig: PopsIframeClickEventConfig, event: MouseEvent | PointerEvent) => void;
        "pops:iframe-mise": (eventConfig: PopsIframeClickEventConfig, event: MouseEvent | PointerEvent) => void;
        "pops:iframe-max": (eventConfig: PopsIframeClickEventConfig, event: MouseEvent | PointerEvent) => void;
      }>(popsType);
    const { $shadowContainer, $shadowRoot } = PopsHandler.handlerShadow(config);
    PopsHandler.handleInit($shadowRoot, [
      {
        name: "index",
        css: PopsCSS.index,
      },
      {
        name: "ninePalaceGridPosition",
        css: PopsCSS.ninePalaceGridPosition,
      },
      {
        name: "scrollbar",
        css: PopsCSS.scrollbar,
      },
      {
        name: "anim",
        css: PopsCSS.anim,
      },
      {
        name: "common",
        css: PopsCSS.common,
      },
      {
        name: "skeleton",
        css: PopsCSS.skeletonCSS,
      },
      {
        name: "iframeCSS",
        css: PopsCSS.iframeCSS,
      },
    ]);

    const maskExtraStyle =
      config.animation != null && <string>config.animation != "" && config.animation ? "position:absolute;" : "";

    // 先把z-index提取出来
    const zIndex = PopsHandler.getTargerOrFunctionValue(config.zIndex);
    const maskHTML = PopsElementHandler.createMask(guid, zIndex, maskExtraStyle);

    const headerBtnHTML = PopsElementHandler.createHeader(popsType, config);
    const iframeLoadingHTML = /*html*/ '<div class="pops-loading"></div>';
    const titleText = config.title!.text!.trim() !== "" ? config.title.text : config.url;
    const { headerStyle, headerPStyle } = PopsElementHandler.createHeaderStyle(popsType, config);
    const animHTML = PopsElementHandler.createAnim(
      guid,
      popsType,
      config,
      /*html*/ `
            <div class="pops-title pops-${popsType}-title" style="text-align: ${
              config.title.position
            };${headerStyle}">${
              config.title.html
                ? titleText
                : `<p pops class="pops-${popsType}-title-text" style="${headerPStyle}">${titleText}</p>`
            }${headerBtnHTML}</div>
			<div class="pops-content pops-${popsType}-content">
                <div class="pops-${popsType}-content-global-loading"></div>
                <iframe src="${config.url}" pops ${
                  config.sandbox ? "sandbox='allow-forms allow-same-origin allow-scripts'" : ""
                }>
                </iframe>
			</div>${config.loading.enable ? iframeLoadingHTML : ""}`,
      "",
      zIndex
    );
    /**
     * 弹窗的主元素，包括动画层
     */

    const $anim = PopsElementHandler.parseElement<HTMLDivElement>(animHTML);
    const {
      $pops,
      $headerBtnClose,
      $headerControls,
      $title,
      $iframe,
      $loading,
      $contentLoading,
      $headerBtnMin,
      $headerBtnMax,
      $headerBtnMise,
    } = PopsHandler.handleQueryElement($anim, popsType);
    let $iframeContainer = popsDOMUtils.selector<HTMLDivElement>(".pops-iframe-container");
    if (!$iframeContainer) {
      $iframeContainer = popsDOMUtils.createElement("div", {
        className: "pops-iframe-container",
      });
      $iframeContainer.style.cssText =
        "display: flex;position: fixed;bottom: 0px;flex-flow: wrap-reverse;-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;";
      popsDOMUtils.appendBody($iframeContainer);
    }
    /**
     * 遮罩层元素
     */
    let $mask: HTMLDivElement | undefined = void 0;
    /**
     * 已创建的元素列表
     */
    const $elList: HTMLElement[] = [$anim];

    if (config.mask.enable) {
      const handleMask = PopsHandler.handleMask({
        type: popsType,
        guid: guid,

        config: config,
        animElement: $anim,
        maskHTML: maskHTML,
      });
      $mask = handleMask.maskElement;
      $elList.push($mask);
    }

    const evtConfig = PopsHandler.handleEventConfig(
      config,
      guid,
      $shadowContainer,
      $shadowRoot,
      popsType,
      $anim,
      $pops,
      emitter,
      $mask
    ) as PopsIframeClickEventConfig<typeof emitter>;
    // 赋值额外的$iframe参数
    evtConfig.$iframe = $iframe;

    const result = PopsHandler.handleResultConfig(evtConfig);

    popsDOMUtils.on($anim, popsDOMUtils.getAnimationEndNameList(), function () {
      // 动画加载完毕
      $anim.style.width = "0%";
      $anim.style.height = "0%";
    });

    popsDOMUtils.on($iframe, "load", () => {
      // iframe加载中...
      popsDOMUtils.remove($loading);
      $contentLoading!.style.animation = "iframeLoadingChange_85 0.3s forwards";
      popsDOMUtils.on($contentLoading, popsDOMUtils.getAnimationEndNameList(), () => {
        // 动画加载完毕就移除
        popsDOMUtils.remove($contentLoading);
      });

      if (config.title!.text!.trim() === "" && $iframe!.contentDocument) {
        // 同域名下的才可以获取网页标题
        $title!.querySelector<HTMLElement>("p")!.innerText = $iframe!.contentDocument.title;
      }

      config.loadEndCallBack(evtConfig);
    });
    // 创建到页面中

    popsDOMUtils.append($shadowRoot, $elList);
    emitter.emit("pops:before-append-to-page", $shadowRoot, $shadowContainer);
    $iframeContainer.appendChild($shadowContainer);
    if ($mask != null) {
      $anim.after($mask);
    }
    // 拖拽
    if (config.drag) {
      PopsInstHandler.drag($pops!, {
        dragElement: $title!,
        limit: config.dragLimit,
        extraDistance: config.dragExtraDistance,
        moveCallBack: config.dragMoveCallBack,
        endCallBack: config.dragEndCallBack,
      });
    }
    const TYPE_MODULE = "type-module";
    // 最小化按钮点击事件
    let origin_left = "";
    let origin_top = "";
    let origin_is_max = false;
    popsDOMUtils.on<PointerEvent | MouseEvent>(
      $headerBtnMin,
      "click",
      (event) => {
        event.preventDefault();
        event.stopPropagation();
        origin_left = $pops.style.left;
        origin_top = $pops.style.top;
        popsDOMUtils.addClassName(
          $pops,
          "pops-iframe-unset-top",
          "pops-iframe-unset-left",
          "pops-iframe-unset-transform"
        );
        $pops.style.transitionDuration = "";

        $pops.setAttribute(TYPE_MODULE, "min");
        $headerControls.setAttribute("type", "min");
        // 隐藏放大图标
        $headerBtnMax.style.setProperty("display", "none");
        // 显示复位图标
        $headerBtnMise.style.setProperty("display", "");
        if (typeof config?.btn?.min?.callback === "function") {
          config.btn.min.callback(evtConfig, event);
        }
        emitter.emit("pops:iframe-min", evtConfig, event);
      },
      {
        capture: true,
      }
    );
    // 最大化按钮点击事件
    popsDOMUtils.on<MouseEvent | PointerEvent>(
      $headerBtnMax,
      "click",
      (event) => {
        event.preventDefault();
        event.stopPropagation();
        if ($pops.getAttribute(TYPE_MODULE) !== "min") {
          origin_left = $pops.style.left;
          origin_top = $pops.style.top;
        }
        origin_is_max = true;
        $pops.style.transitionDuration = "";
        $pops.style.transform = "";
        $pops.removeAttribute(TYPE_MODULE);
        popsDOMUtils.addClassName(
          $pops,
          "pops-iframe-unset-transition",
          "pops-iframe-unset-left",
          "pops-iframe-unset-top",
          "pops-iframe-unset-transform"
        );
        popsDOMUtils.removeClassName($pops, "pops-iframe-unset-transition");
        $pops.setAttribute(TYPE_MODULE, "max");
        $headerControls.setAttribute("type", "max");
        // 隐藏放大图标
        $headerBtnMax.style.setProperty("display", "none");
        // 显示复位图标
        $headerBtnMise.style.setProperty("display", "");
        if (typeof config?.btn?.max?.callback === "function") {
          config.btn.max.callback(evtConfig, event);
        }
        emitter.emit("pops:iframe-max", evtConfig, event);
      },
      {
        capture: true,
      }
    );
    // 先隐藏窗口化按钮
    $headerBtnMise?.style?.setProperty("display", "none");
    // 复位按钮点击事件
    popsDOMUtils.on<MouseEvent | PointerEvent>(
      $headerBtnMise,
      "click",
      (event) => {
        event.preventDefault();
        event.stopPropagation();
        if (origin_is_max && $pops.getAttribute(TYPE_MODULE) === "min") {
          popsDOMUtils.addClassName(
            $pops,
            "pops-iframe-unset-transition",
            "pops-iframe-unset-left",
            "pops-iframe-unset-top",
            "pops-iframe-unset-transform"
          );
          popsDOMUtils.removeClassName($pops, "pops-iframe-unset-transition");
          $pops.setAttribute(TYPE_MODULE, "max");
          $headerControls.setAttribute("type", "max");
        } else {
          origin_is_max = false;
          $pops.style.left = origin_left;
          $pops.style.top = origin_top;
          $pops.style.transitionDuration = "";
          $pops.style.transform = "";
          $headerControls.removeAttribute("type");
          $pops.removeAttribute(TYPE_MODULE);
          popsDOMUtils.removeClassName(
            $pops,
            "pops-iframe-unset-top",
            "pops-iframe-unset-left",
            "pops-iframe-unset-transform"
          );

          // 显示放大图标
          $headerBtnMax.style.setProperty("display", "");
          // 隐藏复位图标
          $headerBtnMise.style.setProperty("display", "none");
        }
        if (typeof config?.btn?.mise?.callback === "function") {
          config.btn.mise.callback(evtConfig, event);
        }
        emitter.emit("pops:iframe-mise", evtConfig, event);
      },
      {
        capture: true,
      }
    );
    // 关闭按钮点击事件
    popsDOMUtils.on<MouseEvent | PointerEvent>(
      $headerBtnClose,
      "click",
      async (event) => {
        event.preventDefault();
        event.stopPropagation();
        await PopsInstHandler.removeInstance([PopsInstData.iframe], guid, false);
        if (typeof config?.btn?.close?.callback === "function") {
          config.btn.close.callback(evtConfig, event);
        }
      },
      {
        capture: true,
      }
    );

    PopsHandler.handlePush(popsType, {
      guid: guid,
      $anim: $anim,
      $pops: $pops!,
      $mask: $mask!,
      $shadowContainer: $shadowContainer,
      $shadowRoot: $shadowRoot,
      config: config,
      emitter,
    });
    return result;
  },
};
