import { watchEffect, nextTick } from "vue";
// import {
//   fuseModelsLoaded,
//   scenes,
//   setting,
//   caseProject,
// } from "@/store";
// import {
//   initialSDK,
//   initialed as fuseInitialed,
//   sdk as fuseSDK,
//   analysisPose,
//   analysisPoseInfo,
//   setPose,
// } from "@/sdk";
import { asyncTimeout } from "./index";
// import { aMapToWgs84 } from "@/utils/coord";
import { SceneType } from "@/store/scene";

// import { offlinePrev } from "@/api/offline";

// export async function modelSDKFactory(
//   type,
//   dom: HTMLDivElement | HTMLIFrameElement
// ): Promise<ModelExpose> {
//   let center: number[] | undefined = undefined;
//   const lonlatStr = caseProject.value?.latAndLong || "22.364093,113.600356";
//     // const lonlatStr = caseProject.value?.latAndLong || "22.364093,113.600356";
//   const lonlat = lonlatStr.split(",").map(Number);
//   const gcenter = aMapToWgs84({
//     x: lonlat[1],
//     y: lonlat[0],
//   });
//   center = [gcenter.x, gcenter.y];
//   if (type === fuseModel) {
//     if (!fuseInitialed) {
//       await initialSDK({
//         laserRoot: offline ? offlinePrev : import.meta.env.VITE_LASER_HOST,
//         panoOSSRoot: offline ? offlinePrev : import.meta.env.VITE_PANO_OSS,
//         ossRoot: offline ? offlinePrev : import.meta.env.VITE_OSS,
//         laserOSSRoot: offline ? offlinePrev : import.meta.env.VITE_LASER_OSS,
//         layout: dom,
//         scenes: scenes.value,
//         lonlat: center,
//       });
//     }
//     return exposeFactory(fuseModel);
//   } else {
//     const iframe = dom as HTMLIFrameElement;
//     const win = await new Promise<Window | null>((resolve, reject) => {
//       const loadedHandler = () => {
//         resolve(iframe.contentWindow);
//         cleanup();
//       };
//       const errorHandler = (err: any) => {
//         reject(err);
//         cleanup();
//       };
//       const cleanup = () => {
//         iframe.removeEventListener("load", loadedHandler);
//         iframe.removeEventListener("error", errorHandler);
//       };
//       iframe.addEventListener("load", loadedHandler);
//       iframe.addEventListener("error", errorHandler);
//     });

//     if (!win) {
//       throw new Error("场景加载失败");
//     }
//     return await exposeFactory(type, win);
//   }
// }

const findObjectAttr = <T extends {}, K extends keyof T>(
  data: T,
  key: K
): Promise<T[K]> => {
  return new Promise<T[K]>((resolve) => {
    const query = () => {
      if (key in data) {
        resolve(data[key]);
      } else {
        setTimeout(query, 6);
      }
    };
    query();
  });
};

const fuseLoaded = new Promise<void>((resolve) => {
  const stop = watchEffect(() => {
    // if (fuseModelsLoaded.value) {
      resolve();
      nextTick(() => stop());
    // }
  });
});

export interface ModelExpose {
  getView: () => Promise<{ image: Blob; flyData: string }>;
  setView: (flyData: string) => void;
}

export async function exposeFactory(
  type,
  win?: any
): Promise<ModelExpose> {
  const sceneType = type === 'fuseModel' ? 99 : type.type;
  const platforms: {
    [key in any]: { getSDK: () => Promise<any>; expose: ModelExpose };
  } = {
    [99]: {
      getSDK: async () => {
        return await findObjectAttr(win, "__sdk");;
      },
      expose: {
        async getView() {
          const dataURL = await sdk.screenshot(260, 160);
          const res = await fetch(dataURL);
          const image = await res.blob();
          const pose = sdk.getPose();
          return {
            image,
            flyData: JSON.stringify(pose),
          };
        },
        async setView(flyData: string) {
          console.error(JSON.parse(flyData));
          // setPose(JSON.parse(flyData), sdk);
          const pose = JSON.parse(flyData);
          sdk.Camera.setPose({ dur: 300, ...pose });
        },
      },
    },
    [SceneType.SWKK]: {
      getSDK: async () => {
        const sdk = await findObjectAttr(win, "__sdk");
        if (!sdk.Scene.loaded) {
          await new Promise((reoslve) => sdk.Scene.on("loaded", reoslve));
        }
        return sdk;
      },
      expose: {
        async getView() {
          const pose = sdk.Camera.getPose();
          const images = await sdk.Camera.screenshot(
            [{ width: 260, height: 160, name: "2k" }],
            true
          );
          return {
            image: images[0].data,
            flyData: JSON.stringify(pose),
          };
        },
        async setView(flyData: string) {
          const pose = JSON.parse(flyData);
          sdk.Camera.setPose({ dur: 300, ...pose });
        },
      },
    },
    [SceneType.SWSS]: {
      getSDK: async () => {
        await findObjectAttr(win, "laserLoaded");
        return await findObjectAttr(win, "__sdk");
      },
      expose: {
        async getView() {
          const dataURL = await sdk.scene.screenshot(260, 160);
          const res = await fetch(dataURL.dataUrl);
          const image = await res.blob();
          const pose = await sdk.scene.getPose();
          const mode = sdk.customMap.mode;

          return {
            image,
            flyData: JSON.stringify({ pose, mode }),
          };
        },
        async setView(flyData: string) {
          const { pose, mode } = JSON.parse(flyData);
          sdk.customMap.mode = mode;
          sdk.scene.setPose(pose, 300);
        },
      },
    },
  };
  platforms[SceneType.SWYDSS] = platforms[SceneType.SWSS];
  platforms[SceneType.DSFXJ] = platforms[SceneType.SWYDMX] =
    platforms[SceneType.SWSSMX] =
    platforms[SceneType.SWKJ] =
      platforms[SceneType.SWKK];
  platforms[SceneType.SWMX] = {
    getSDK: async () => findObjectAttr(win, "__sdk"),
    expose: ()=>{},
  };

  if (!(sceneType in platforms)) {
    throw new Error("不支持该类型场景！");
  }

  const sdk: any = await Promise.race([
    asyncTimeout(100000).then(() => Promise.reject(new Error("加载超时"))),
    platforms[sceneType].getSDK(),
  ]);
  return platforms[sceneType].expose;
}
