import { appConstant } from "@/app";
import {
  SceneTypeDesc,
  SceneTypeDomain,
  SceneTypePaths,
} from "@/constant/scene";
import { alert } from "@/helper/message";
import { getCaseSceneList, getSyncSceneInfo } from "@/store/case";
import { CaseTagging } from "@/store/caseTagging";
import { ModelScene, QuoteScene, Scene, SceneType } from "@/store/scene";
import { transformSWToken, user } from "@/store/user";
import { base64ToBlob, drawImage } from "@/util";
import { ref, watchEffect } from "vue";

export type MenuItem = {
  key: string;
  label: string;
  onClick: (caseId: number) => void;
};

export const getFuseCodeLink = (caseId: number, query?: boolean) => {
  const params: { token?: string; caseId: string; app: string } = {
    caseId: caseId.toString(),
    app: appConstant.deptId.toString(),
  };

  if (!query) {
    params.token = user.value.token;
  }
  const url = new URL(
    SceneTypePaths[SceneType.SWMX][0],
    SceneTypeDomain[SceneType.SWMX]
  );
  for (const [name, val] of Object.entries(params)) {
    url.searchParams.append(name, val || "");
  }
  return url.href;
};

export const getSWKKSyncLink = async (caseId: number) => {
  const scenes = await getCaseSceneList(caseId);
  const supportTypes = [
    SceneType.SWKK,
    SceneType.SWKJ,
    SceneType.SWSSMX,
    SceneType.SWYDMX,
  ];
  const kkScenes = scenes.filter((scene) =>
    supportTypes.includes(scene.type)
  ) as QuoteScene[];

  let msg: string | null = null;
  if (!scenes.length) {
    msg = "当前案件下无场景，请先添加场景。";
  } else if (!kkScenes.length) {
    msg = `带看仅支持${supportTypes
      .map((type) => SceneTypeDesc[type])
      .join("、")}类型场景，请添加此类型场景。`;
  }
  if (msg) {
    alert(msg);
    throw msg;
  }

  const url = new URL(
    SceneTypePaths[SceneType.SWKK][2],
    SceneTypeDomain[SceneType.SWKK]
  );
  const roomId = await getSyncSceneInfo(caseId);

  const params = {
    vruserId: user.value.info.userName,
    // platform: "fd",
    roomId,
    // domain: location.href,
    // fromMiniApp: "0",
    role: "leader",
    avatar: user.value.info.avatar,
    redirect: encodeURIComponent(location.href),
    name: user.value.info.userName,
    // isTour: "0",
    m: kkScenes[0].num,
  };
  for (const [name, val] of Object.entries(params)) {
    url.searchParams.append(name, val || "");
  }
  return url;
};

export const checkScenesOpen = async (caseId: number, url: URL | string) => {
  const scenes = await getCaseSceneList(caseId);
  if (!scenes.length) {
    alert("当前案件下无场景，请先添加场景。");
  } else {
    window.open(url);
  }
};

export const getQuery = (
  caseId: number,
  share: boolean = false,
  single: boolean = false
) =>
  `${getFuseCodeLink(caseId, true)}${share ? "&share=1" : ""}${
    single ? "&single=1" : ""
  }#show/summary`;

// 查看
export const gotoQuery = (caseId: number) => {
  checkScenesOpen(caseId, getQuery(caseId, true));
};

export enum FuseImageType {
  FUSE,
  KANKAN,
  LASER,
}

export const getSceneIframe = (iframe: HTMLIFrameElement) => {
  const iframeElement = iframe.contentWindow?.document.documentElement;
  if (!iframeElement) {
    return null;
  }
  const extIframe = iframeElement.querySelector(
    ".external"
  ) as HTMLIFrameElement;
  return extIframe || iframe;
};

export const getIframeSceneType = async (iframe: HTMLIFrameElement) => {
  const targetIframe = getSceneIframe(iframe);
  if (!targetIframe) {
    return null;
  }
  const targetWindow: any = targetIframe.contentWindow;
  const fuseCnavas = targetWindow.document.querySelector(
    ".scene-canvas > canvas"
  ) as HTMLElement;

  if (fuseCnavas) {
    return { type: FuseImageType.FUSE, sdk: targetWindow.sdk };
  }
  const isLaser = targetWindow.document.querySelector(".laser-layer");
  return {
    type: isLaser ? FuseImageType.LASER : FuseImageType.KANKAN,
    sdk: await targetWindow.__sdk,
  };
};

// 处理融合iframe页面
export const fuseIframeHandler = (iframe: HTMLIFrameElement) => {
  const currentType = ref<FuseImageType>();
  const interval = setInterval(async () => {
    const typeMap = await getIframeSceneType(iframe);
    currentType.value = typeMap?.type;
  }, 100);

  const stopWatch = watchEffect((onCleanup) => {
    // if (currentType.value === FuseImageType.LASER) {
    //   const $iframe = getSceneIframe(iframe)!;
    //   const target = $iframe.contentWindow!.document.head;
    //   const $style = document.createElement("style");
    //   $style.type = "text/css";
    //   var textNode = document.createTextNode(`
    //     .mode-tab > .model-mode-tab.strengthen {
    //       display: none
    //     }
    //   `);
    //   $style.appendChild(textNode);
    //   target.appendChild($style);
    // }
  });

  return () => {
    clearInterval(interval);
    stopWatch();
  };
};

// 获取fuse场景截图
export type FuseImageRet = { type: FuseImageType; blob: Blob | null };
export const getFuseImage = async (
  iframe: HTMLIFrameElement,
  width: number = 500,
  height: number = width
) => {
  const typeMap = await getIframeSceneType(iframe);
  let blob: Blob | null = null;

  switch (typeMap?.type) {
    case FuseImageType.FUSE:
      const dataURL = await typeMap.sdk.screenshot(width, height);
      const res = await fetch(dataURL);
      blob = await res.blob();
      break;
    case FuseImageType.KANKAN:
      const result = await typeMap.sdk.Camera.screenshot(
        [{ width: width, height: width, name: "2k" }],
        false
      );
      blob = base64ToBlob(result[0].data);
      break;
    case FuseImageType.LASER:
      blob = await new Promise<Blob | null>((resolve) => {
        typeMap.sdk.scene
          .screenshot(width, height)
          .done((data: { dataUrl: string }) =>
            resolve(base64ToBlob(data.dataUrl))
          );
      });
      break;
  }
  return { type: typeMap?.type, blob };
};

// 处理fuse融合一起的图，将热点加入图片内
export const fuseImageJoinHot = async (
  iframe: HTMLIFrameElement,
  rawBlob: Blob,
  showTags: CaseTagging[],
  width = 500
) => {
  // fuse场景需要特别处理
  const img = new Image();
  img.src = URL.createObjectURL(rawBlob);
  await new Promise((resolve) => (img.onload = resolve));

  const $canvas = document.createElement("canvas");
  $canvas.width = img.width;
  $canvas.height = img.height;

  const ctx = $canvas.getContext("2d")!;
  ctx.drawImage(img, 0, 0, img.width, img.height);

  const contentDoc = iframe.contentWindow!.document;
  const hotItems = Array.from(
    contentDoc.querySelectorAll(".hot-item")
  ) as HTMLDivElement[];
  hotItems.forEach((hot) => {
    const hotTitle = (hot.querySelector(".tip") as HTMLDivElement).innerText;
    const index = showTags.findIndex(
      (tag) => tag.tagTitle.trim() === hotTitle.trim()
    );
    if (index !== -1) {
      const bound = hot.getBoundingClientRect();
      const size = (img.width / width) * 32;

      const left = bound.left + size / 2;
      const top = bound.top + size / 2;
      ctx.save();
      ctx.translate(left, top);
      ctx.beginPath();
      ctx.arc(0, 0, size / 2, 0, 2 * Math.PI);
      ctx.strokeStyle = "#000";
      ctx.fillStyle = "#fff";
      ctx.stroke();
      ctx.fill();
      ctx.beginPath();
      ctx.fillStyle = "#000";
      ctx.textAlign = "center";
      ctx.textBaseline = "middle";
      ctx.font = `normal ${size / 2}px serif`;
      ctx.fillText((index + 1).toString(), 0, 0);
      ctx.restore();
    }
  });

  const $ccanvas = document.createElement("canvas");
  $ccanvas.width = width;
  $ccanvas.height = width;
  const cctx = $ccanvas.getContext("2d")!;
  drawImage(
    cctx,
    $ccanvas.width,
    $ccanvas.height,
    $canvas,
    img.width,
    img.height,
    0,
    0
  );

  const blob = await new Promise<Blob | null>((resolve) =>
    $ccanvas.toBlob(resolve, "png")
  );

  return blob;
};

export enum OpenType {
  query,
  edit,
}
export const openSceneUrl = async (scene: Scene, type: OpenType) => {
  const pathname = SceneTypePaths[scene.type][type];
  const url = new URL(
    pathname || "",
    SceneTypeDomain[scene.type] || window.location.href
  );
  url.searchParams.append("lang", "zh");
  if (scene.type === SceneType.SWMX) {
    url.searchParams.append(
      "modelId",
      (scene as ModelScene).modelId.toString()
    );
    url.hash = "#sign-model";
    url.searchParams.append("share", "1");
    url.searchParams.append("app", appConstant.deptId.toString());
  } else {
    if (scene.type === SceneType.QJKK) {
      url.searchParams.append("id", (scene as QuoteScene).id);
    } else {
      url.searchParams.append("m", (scene as QuoteScene).num);
    }

    if (type === OpenType.edit) {
      url.searchParams.append(
        "token",
        await transformSWToken(scene as QuoteScene)
      );
    }
  }
  window.open(url);
};
