<template>
  <iframe class="external" :src="url" ref="iframeRef" v-if="url"></iframe>
  <div class="laser-layer" v-show="!url">
    <div class="scene-canvas" ref="fuseRef">
      <div id="direction"></div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, watchEffect, computed, watch, nextTick } from 'vue'
import { SceneType } from '@/store'
import { params } from '@/env'
import { fuseModel, modelProps } from './index'
import { modelSDKFactory } from './platform'

const typeChange = () => {
  const oldType = modelProps.type
  let stopWatch = null as unknown as () => void

  const typePromise = new Promise((_, reject) => {
    stopWatch = watchEffect(() => {
      if (modelProps.type !== oldType) {
        reject(new Error('当前模型未加载完已切换到下个'))
        stopWatch!()
      }
    })
  })
  return { typePromise, typeCleanup: stopWatch }
}

export const Model = defineComponent({
  name: 'model',
  setup() {
    const scene = computed(() => modelProps.type !== fuseModel && modelProps.type)
    const url = ref("")
    const setUrl = (newURL: string) => {
      if (newURL !== url.value) {
        setTimeout(() => {
          const hook = (iframeRef.value?.contentWindow as any)?.beforeDestroy
          console.error("当前iframe的beforeDestroy", hook)
          if (hook) {
            hook()
            console.log("赋值1")
            setTimeout(() => url.value = newURL, 300)
          } else {
            console.log("赋值2")
            url.value = newURL
          }
        })
      }
    }

    watchEffect(() => {
      if (!scene.value) {
        return setUrl("");
      }
      const type = scene.value.type
      const urls = {
        [SceneType.SWKK]: `/swkk/spg.html?m=${scene.value.num}`,
        [SceneType.SWKJ]: `/swkk/spg.html?m=${scene.value.num}`,
        [SceneType.SWSS]: `/swss/index.html?m=${scene.value.num}`,
        [SceneType.SWSSMX]: `/swkk/spg.html?m=${scene.value.num}`,
        [SceneType.SWMX]: `index.html?caseId=${params.caseId}&modelId=${scene.value.num}&share=1#sign-model`
      }
      setUrl(urls[type])
    })



    const fuseRef = ref<HTMLDivElement>()
    const iframeRef = ref<HTMLIFrameElement>()

    watch(
      () => [modelProps.type, url.value],
      async ([type, url], oldType, onCleanup) => {
        if (type !== fuseModel && !url) {
          return;
        }
        const callback = modelProps.callback

        await nextTick()
        const { typePromise, typeCleanup } = typeChange()
        const modelPromise = modelSDKFactory(type as any, type === fuseModel ? fuseRef.value! : iframeRef.value!)
        let result: any = null, error = null
        try {
          result = await Promise.race([typePromise, modelPromise])
          console.error(result)
        } catch (err: any) {
          error = err
        }
        typeCleanup()
        callback && callback(result, error)
      }, 
      { immediate: true, flush: 'post' }
    )

    return {
      iframeRef,
      fuseRef,
      url
    }
  }
})

export default Model
</script>

<style scoped lang="scss">
.laser-layer {
  position: absolute;
  z-index: 1;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;

  .scene-canvas {
    width: 100%;
    height: 100%;
    background-color: #ccc;
  }
}

.external {
  position: absolute;
  z-index: 1;
  border: none;
  top: calc(var(--editor-head-height) + var(--header-top));
  left: 0;
  height: calc(100% - (var(--editor-head-height) + var(--header-top)));
  width: 100%;
}

#direction {
  right: calc(var(--editor-menu-right) + var(--editor-toolbox-width)) !important;
  top: calc(var(--header-top) + var(--editor-head-height)) !important;
  margin: 10px;
  transition: top .3s ease, right .3s ease;
}
</style>
