<template>
  <div ref="container" :class="'vivify '+ buttonClass" :style="cardStyle"
       style="height: 100%;width: 100%;overflow: hidden">
    <div v-if="props.showToolBar" class="scoped-web3dc-header">
      <div class="scoped-web3dc-header-breadcrumbs">

        <div class="scoped-web3dc-header-breadcrumbs1" style="padding-left:15px ">

          <i class="iconfont  icon-liti" style="display: inline-block"></i>
          <div class="scoped-web3dc-header-breadcrumbs2"> {{
              props?.customSceneName
                  ? props.customSceneName
                  : props.sceneData?.name
            }}
          </div>

        </div>

      </div>
      <div class="scoped-web3dc-header-toolBar">
        <i class="iconfont icon-quanping1" @click="switchFullScreen"></i>
        <!-- <i class="iconfont icon-jiansuo"></i>
        <i class="iconfont icon-liebiao1" @click="switchDropDown"></i> -->
      </div>
      <div v-if="showDropDown" class="scoped-web3dc-header-toolBar-dropDown">
        <div v-for="(key,index) in Object.keys(datalist)" :key="'web3d-group' + index" style="width: 100%">
          <div style="margin: 0 8px 8px 5px">{{ key }}</div>
          <div style='display: flex;flex-wrap: wrap'>
            <div v-for="(name,index) in Object.keys(datalist[key])" :key="'web3d-device' + index"
                 class="scoped-web3dc-header-toolBar-dropDown-item">
              <div class="scoped-web3dc-header-toolBar-dropDown-item1">
                <span>{{ name + '(' + datalist[key][name] + ')' }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <canvas ref="domCanvas" style="height: 100%;width: 100%" @load="eventHandler.load"
            @loadingHide="eventHandler.loadingHide"
            @render="eventHandler.render" @tap="eventHandler.tap"/>
    <div v-if="isShowFooter && props.showToolBar " class="scoped-web3dspace-footer">
      <div class="scoped-web3dspace-footer-left">
        <div class='scoped-web3dspace-footer-left-set'>
          <div :class="{'scoped-web3dspace-footer-left-set-active':cameraPerspective}"
               class="scoped-web3dspace-footer-left-set1"
               @click="switchCameraPerspective(true)">
            <!--                        透视图-->
            <i class="iconfont icon-toushitu"></i>
          </div>
          <div :class="{'scoped-web3dspace-footer-left-set-active':!cameraPerspective}"
               class="scoped-web3dspace-footer-left-set1"
               @click="switchCameraPerspective(false)">
            <!--                        顶视图-->
            <i class="iconfont icon-dingshitu"></i>
          </div>
        </div>
        <div>
        </div>
      </div>
      <div class="scoped-web3dspace-footer-right">
        <div class="scoped-web3dspace-footer-right-item">
          <div class="scoped-web3dspace-footer-right-item-title">
            点击聚焦
          </div>
          <div :class="[openFocus ?'scoped-web3dspace-footer-right-item-model-active': '']"
               :title="openFocus ? $t('CloseFocus') : $t('TurnOnTheFocus')"
               class="scoped-web3dspace-footer-right-item-model margin4"
               @click="isOpenFocus(!openFocus)">
            <div class="kf-switch-box">
              <div v-show="!openFocus" class="kf-switch-con"></div>
            </div>
            <div class="kf-switch-box">
              <div v-show="openFocus" class="kf-switch-con"></div>
            </div>
          </div>
        </div>
        <div class="scoped-web3dspace-footer-right-item" @click.stop="reset">
          <i class="iconfont icon-shuaxin"></i>
        </div>
        <div class="scoped-web3dspace-footer-right-item" @click="isOpenFooter">
          <i v-if="isShowFooter" class="iconfont icon-jiantou_liebiaozhankai"></i>
        </div>
      </div>

    </div>
    <div v-if="!isShowFooter && props.showViewBar" style="position: absolute;bottom: 7px;right:16px;z-index: 10"
         @click="isOpenFooter">
      <i class="iconfont icon-jiantou_liebiaoshouqi"></i>
    </div>
    <PanelSets :bound="viewportBound" :panelSets="panelsObjectSet" :weakKey="weakKey"/>
  </div>
</template>
<script>
import {computed, getCurrentInstance, isRef, onMounted, onUnmounted, ref, watch} from 'vue';

import Const from '@/utils/const';
import Stats from 'stats.js';
import {isRestSceneModeFromScene, sceneMode} from '@/model/globalData';
import {each, eachObject, isArray, isDefined, isObject, loopFactory} from '@/utils/tools';
import {initCamerasThumbnails, isRestCamerasThumbnailsFromScene} from '@/model/cameras';
import envModel from '@/model/env';
import oemManager from '@/utils/oem';
import Axios from 'axios';
import {default as PanelSets} from '@/components/widgets/componentPanel/index.vue';
import styleManager from '@/components/ui/utils/style.vue';
import Dc3Tools from '@/components/ui/widgets/kfWeb3dImpl';
import pageModel from '@/components/ui/model/page';
import {scaleData} from '@/components/ui/model/domNode';
import dataMapModel, {mapping} from '@/model/dataMapping';
import {SysTopo} from '@/model/sysTopo';
import globalEventManager from '@/utils/globalEvent';
import detailPanel from '@/components/ui/model/detailPanel';
import utils from '@/utils/utils.js';
import _ from 'lodash';
import {getToken} from '@/utils/auth.js';

export default {
  name: 'kfWeb3d',
  components: {
    PanelSets,
  },
  props: {
    props: {
      type: Object,
      default: () => {},
    },
    eventScript: {
      type: String,
    },
  },
  emits: ['sceneLoad', 'loaderHide', 'render', 'tap'],
  setup(props, {emit}) {
    let cardStyle = ref({});
    let buttonClass = ref('');
    const {proxy} = getCurrentInstance();
    let tempSceneData = null;
    let isSameScene = function(sceneData, sceneUIData) {
      sceneData = JSON.stringify(sceneData) + ',' + JSON.stringify(sceneUIData);
      if (tempSceneData !== sceneData) {
        tempSceneData = sceneData;
        return false;
      }
      return true;
    };
    let tempPosition = {
      x: props.props.x,
      y: props.props.y,
      width: props.props.width,
      height: props.props.height,
    };
    let localIsFullScreen = props.props.isFullScreen;
    pageModel.watchProps(props, watch, proxy, (changes) => {
      //refreshEvents();
      if (styleManager.styleChanged('kfWeb3d', changes)) {
        cardStyle.value = styleManager.updateStyle(proxy);
      }
      if (styleManager.classChanged('kfWeb3d', changes)) {
        buttonClass.value = styleManager.updateClass(proxy);
      }
    });
    let reloadScene = () => {
      if (getEngine() && !isSameScene(props.props.sceneData, props.props.sceneUrl+props.props.sceneDataUI)) {
        /*let sceneData = props.props.sceneData && props.props.sceneData.uuid ? props.props.sceneData : undefined; // 有可能是空数据
        let sceneDataUI = sceneData ? props.props.sceneDataUI : undefined; // UI加载的前提是有三维

        let urls = [];
        if (sceneData) {
          urls.push(sceneData.projectUuid + '/' + sceneData.uuid + (sceneData.type !== 'artist' ? '.k3ds' : '.json'));
          if (sceneDataUI && sceneDataUI.uuid) {
            urls.push(
                sceneDataUI.projectUuid + '/' + sceneDataUI.uuid + (sceneDataUI.type !== 'artist' ? '.k3ds' : '.json'));
          }
        }*/
        let sceneData = {};
        let url = props.props.sceneUrl;
        let urlPart = url.split('/');
        if (url.indexOf('.') === -1) {
          url += '.json';
          sceneData.type = 'artist';
          sceneData.uuid = parseInt(urlPart[1]);
        } else if (url.indexOf('.k3ds') !== -1) {
          sceneData.type = 'tron';
          sceneData.uuid = parseInt(urlPart[1].replaceAll('.k3ds', ''));
        }
        sceneData.projectUuid = parseInt(urlPart[0]);
        props.props.sceneData = sceneData;
        let urls = [url];

        loadSceneFromUrl(urls);
      }
    };
    watch(props, (newValue, oldValue) => {
      reloadScene();
      containerStyle.value = styleManager.updateStyle(proxy);

      if (localIsFullScreen !== newValue.props.isFullScreen) {
        if (newValue.props.isFullScreen) {
          tempPosition = {
            x: newValue.props.x,
            y: newValue.props.y,
            width: newValue.props.width,
            height: newValue.props.height,
            zIndex: 'auto',
          };
          let rect =
              container.value.parentElement.parentElement.getBoundingClientRect();
          newValue.props.x = 0;
          newValue.props.y = 0;
          newValue.props.zIndex = 5;
          newValue.props.width = rect.width / scaleData.value.scale;
          newValue.props.height = rect.height / scaleData.value.scale;
        } else {
          pageModel.setPropValue(
              props.props,
              props.props.key,
              'height',
              tempPosition.height,
              null,
              null,
              false,
          );
          pageModel.setPropValue(
              props.props,
              props.props.key,
              'width',
              tempPosition.width,
              null,
              null,
              false,
          );
          pageModel.setPropValue(
              props.props,
              props.props.key,
              'zIndex',
              tempPosition.zIndex,
              null,
              null,
              false,
          );
          container.value.style.display = 'none';
          setTimeout(() => {
            pageModel.setPropValue(
                props.props,
                props.props.key,
                'x',
                tempPosition.x,
                null,
                null,
                false,
            );
            pageModel.setPropValue(
                props.props,
                props.props.key,
                'y',
                tempPosition.y,
                null,
                null,
                false,
            );
            container.value.style.display = 'block';
          }, 100);
        }
        localIsFullScreen = newValue.props.isFullScreen;
      }
    });
    let isInitOK = false;
    let isDisposed = false;
    let expectedLoadingTime = 0;
    let loadingTextTimer = null;
    let loadingTextIndex = 0;
    let stats = null;
    let loaded = false;
    let puzzle = null;
    let netMsgRouter = null;
    let handleVueEvent = null;
    let tapHandlers = [];
    let currSceneId = 0;
    let loadStartTime = 0;
    const domCanvas = ref();

    let defaultHandler = ref({
      load: () => {
        console.log("场景加载完成", currScene), emit("sceneLoad", { scene: currScene });
      },
      tap: (f) => {
        console.log("触发点击", f), emit("tap", { point: f });
      },
      loadingHide: () => {
        console.log("隐藏加载界面", currScene), emit("loaderHide", { scene: currScene });
      },
      render: (f, l) => {
        emit("render", { engine: f, sceneManager: l, scene: currScene });
      }
    });
    let panelsObjectSet = ref({});
    let container = ref(null);
    let editState = ref(false);
    let currScene = null;
    let dc3Tools = new Dc3Tools();
    let datalist = ref([]);
    let showDropDown = ref(false);
    let isShowFooter = ref(true);
    let openFocus = ref(props.props.openFocus);
    let cameraPerspective = ref(true);
    let eventCallbacks = {};
    const eventHandler = computed(() => defaultHandler.value);
    let containerStyle = ref({});
    const weakKey = {componentKey: props.props.key};

    const getHardwareScalingLevel = function(width, height) {
      const k = 2.5;
      const w = 1920 * k;
      const h = 1080 * k;
      if (width <= w && height <= h) {
        return 1 / window.devicePixelRatio;
      }
      if (width / height > w / h) {
        return width / w;
      } else {
        return height / h;
      }
    };
    const getCanvas = function() {
      window.Kc = window.Kc || {};
      return window.Kc[props.props.id + '_canvas'];
    };
    const switchCameraPerspective = function(isPerspective) {
      globalEventManager.issueEvent('/web3d_camera_perspective', {
        componentKey: props.props.id,
        data: isPerspective,
      });
    };
    const getEngine = function() {
      window.Kc = window.Kc || {};
      return window.Kc[props.props.id + '_engine'];
    };
    const initLoader = function() {
      let canvas = getCanvas();
      let engine = getEngine();

      let loadingScreen = new (window.Kingfisher.Runtime.LoadingScreenV2 || window.Kingfisher.Runtime.LoadingScreen)(
          canvas,
      );
      if (props.props.logo) {
        loadingScreen.customLogoSrc = props.props.logo;
        loadingScreen.style = 'custom';
        if (props.props.logoSize) {
          let size = props.props.logoSize.split(',');
          if (size.length === 2) {
            loadingScreen.logoSize = {
              width: size[0],
              height: size[1],
            };
          }
        }
        loadingScreen.hideMiniLogo = true;
      } else if (!oemManager.beSame('product', 'logo')) {
        loadingScreen.logoSrc = oemManager.getImage(
            'product',
            'logo',
            '3dc',
        );
        loadingScreen.hideMiniLogo = true;
      }
      engine.loadingScreen = loadingScreen;
      loadingScreen.onHide = onLoaderHide();
    };
    const showLoadingText = function() {
      //let loadingText = "";

      if (props.props.showPoem) {
        // loadingText = lines[Math.floor(loadingTextIndex / 5)];
        loadingTextIndex++;

        if (loadingTextIndex === lines.length * 5) {
          loadingTextIndex = 0;
        }
      }

      let engine = getEngine();
      if (engine != null && engine.loadingScreen != null) {
        let loadingTime = new Date().getTime() - loadStartTime;
        let percentage = (loadingTime / expectedLoadingTime).toFixed(2);
        if (percentage > 0.99) {
          percentage = 0.99;
        }
        //engine.loadingScreen.loadingUIText = loadingText + "<br/>" + (percentage * 100).toFixed(0) + "%";
        if (engine.loadingScreen.updateProgress) {
          engine.loadingScreen.updateProgress(
              Math.floor(percentage * 100),
          );
        }
      }
    };

    const createEngine = function() {
      let global = window.Kc || {};
      window.Kc = global;

      let canvas = domCanvas.value;
      if(canvas){
        canvas.oncontextmenu = function(e) {
          e.preventDefault();
          e.stopPropagation();
        };
      }
      canvas.toBase64Image = () => {
        return new Promise((resolve, reject) => {
          if (currScene && sceneManager && sceneManager.rootScene.subScenes.length) {
            sceneManager.rootScene.subScenes[0].getScreenshot({precision: 0.2}, 'image/png', (res) => {
              resolve(res);
            });
          } else {
            resolve('');
          }
        });
      };
      global[props.props.id + '_canvas'] = canvas;
      // console.log(canvas);
      let engine = new window.Kingfisher.Engine(canvas, true);
      console.log('create engine.');
      engine.netMsgRouter = netMsgRouter;
      try {
        if (props.props.sceneUrl.includes('.k3ds')) {
          window.Kf.requireLib(engine, "3dc");
        } else {
          window.Kf.requireLib(engine, "designer");
        }
      } catch (e) {
        console.log(e);
      }
      global[props.props.id + '_engine'] = engine;
      let scalingLevel = getHardwareScalingLevel(
          canvas.clientWidth,
          canvas.clientHeight,
      );
      engine.setHardwareScalingLevel(scalingLevel);

      window.Kingfisher.Runtime.Puzzle = window.Kingfisher.Runtime.PuzzleInterface;
      window.Kingfisher.Runtime.Part = window.Kingfisher.Runtime.PartInterface;

      function resizeHandler() {
        let scaling = getHardwareScalingLevel(
            canvas.clientWidth,
            canvas.clientHeight,
        );
        engine.setHardwareScalingLevel(scaling);
        engine.resize(canvas.clientWidth, canvas.clientHeight);
      }

      window.addEventListener('resize', resizeHandler);

      let resizeObserver = new ResizeObserver(resizeHandler);
      resizeObserver.observe(domCanvas.value);

      initLoader();
    };
    const initScene = function() {
      window.Kingfisher.sceneLoadedCallback = function(
          scene,
          parsedData,
      ) {
        setTimeout(function() {
          if (isRestSceneModeFromScene.value) {
            sceneMode.value = parsedData.sceneMode
                ? parsedData.sceneMode
                : 'scene3D';
            isRestSceneModeFromScene.value = false;
          }
        }, 1000);
        scene.k3dc = scene.k3dc
            ? scene.k3dc
            : {
              panels: {},
            };
        scene.k3dc.serialize = function() {
          const check = function(_loopData, targetData, store) {
            let loopData = _loopData;
            if (isObject(loopData)) {
              if (!isDefined(targetData)) {
                targetData = {};
              }
              eachObject(loopData, (item, i, key) => {
                if (isObject(item)) {
                  item = isRef(item) ? item.value : item;
                  targetData[key] = {};
                  store.push({
                    loopData: item,
                    targetData: targetData[key],
                  });
                } else if (isArray(item)) {
                  targetData[key] = [];
                  store.push({
                    loopData: item,
                    targetData: targetData[key],
                  });
                } else if (key !== 'serialize') {
                  targetData[key] = item;
                }
              });
            }
            if (isArray(loopData)) {
              if (!isDefined(targetData)) {
                targetData = [];
              }
              each(loopData, (item, i) => {
                if (isObject(item)) {
                  item = isRef(item) ? item.value : item;
                  targetData[i] = {};
                  store.push({
                    loopData: item,
                    targetData: targetData[i],
                  });
                } else if (isArray(item)) {
                  targetData[i] = [];
                  store.push({
                    loopData: item,
                    targetData: targetData[i],
                  });
                } else {
                  targetData[i] = item;
                }
              });
            }
          };
          let target = {};
          let loop = loopFactory(
              [{loopData: scene.k3dc, targetData: target}],
              function(data, store) {
                let {loopData, targetData} = data;
                if (isRef(loopData)) {
                  check(loopData.value, targetData, store);
                } else {
                  check(loopData, targetData, store);
                }
              },
          );
          loop.loopFn();
          return target;
        };
        scene.k3dc = ref(scene.k3dc).value;
        scene.k3dc.panels = scene.k3dc.panels ? scene.k3dc.panels : {};
        panelsObjectSet.value = scene.k3dc.panels;
        scene.k3dc.dataMaps = scene.k3dc?.dataMaps ?? {};
        scene.k3dc.subDataMaps = scene.k3dc?.subDataMaps ?? {}; // 系统拓扑图 订阅数据的映射关系对象
        initCamerasThumbnails(parsedData.camerasThumbnail);
        envModel.afterLoading();

        // scene 参数传入 初始化数据
        if (props.props?.sceneData) {
          let {projectUuid, uuid, type} = props.props.sceneData;
          if (type !== 'artist') {
            dataMapModel.dataModel.initDataMapping(scene, projectUuid, uuid);
            if (!Object.hasOwn(SysTopo.sysTopoList, scene.uid)) {
              let sysTopoModel = new SysTopo(projectUuid, scene);
              sysTopoModel.initSysTopoWs(projectUuid, scene);

              SysTopo.sysTopoList[scene.uid] = sysTopoModel;  // 创建的实例化对象，加入到 sysTopo 管理对象中
            }
          }
        }
      };
      if (props.props.disabled) {
        loaded = true;
        return;
      }

      // no netMsgRouter
      // puzzle = window.Kingfisher.Runtime.Puzzle;
      // if (props.props.msgSync) {
      //     try {
      //         netMsgRouter = new window.Kingfisher.Runtime.NetMsgRouter(
      //             props.props.group,
      //             props.props.role,
      //             findWsUrl()
      //         );
      //         handleVueEvent =
      //             new window.Kingfisher.Runtime.HandleVueEvent(
      //                 netMsgRouter,
      //                 undefined,
      //                 { context: proxy }
      //             );
      //     } catch (e) {
      //         console.error(e);
      //     }
      // }
      createEngine();
      let sceneManager =
          window.Kc[props.props.id + '_sceneManager'] ||
          new window.Kingfisher.SceneManager(getEngine());
      window.sceneManager = sceneManager;
      window.Kc[props.props.id + '_sceneManager'] = sceneManager;

      window.Kingfisher.Database.IDBStorageEnabled = true;
      let engine = getEngine();

      reloadScene();
      engine.runRenderLoop(() => {
        try {
          let currEngine = getEngine();
          if (currEngine && !currEngine.isDisposed) {
            try {
              if (eventHandler.value.render) {
                eventHandler.value.render(engine, sceneManager);
              }
            } catch (e) {
              console.error(e);
            }
            sceneManager.rootScene.render();
          }
        } catch (e) {
          console.error(e);
        }
        if (stats) {
          stats.update();
        }
      });
    };
    const initStats = function() {
      if (Const.develop && props.props.showFps) {
        stats = new Stats();
        stats.setMode(0);
        stats.domElement.style.position = 'absolute';
        stats.domElement.style.left = '5px';
        stats.domElement.style.top = '5px';
        domCanvas.value.parentNode.appendChild(stats.domElement);
      }
    };
    const handleMessage = function(e) {
   // console.log(props.props.id);
 /*if (typeof e.data == "object") {
   let message = e.data;
   if (message.action === "kfWeb3dPropsUpdate") {
     if(message?.value?.field === 'sceneUrl'){
       loadSceneFromUrl(props.props.sceneUrl);
     }
   }
 }*/
    };
    const onLoaderHide = function() {
      clearInterval(loadingTextTimer);
      localStorage.setItem(
          props.props.sceneUrl + '_loadingtime',
          new Date().getTime() - loadStartTime - 1000,
      );
      if (window.onSceneLoaded) {
        window.onSceneLoaded();
      }
      if (eventHandler.value.loadingHide) {
        eventHandler.value.loadingHide();
      }
    };
    const registerContext = function(scene) {
      let register =
          scene && scene.puzzleLogic
              ? scene.puzzleLogic.registerContext
              : window.registerContext;
      if (register) {
        register('contextPath', '');
        register(
            'context',
            Object.assign(
                {
                  registerContext: registerContext,
                  project: tempSceneData.scene,
                },
                proxy,
            ),
        );

        register('canvas', getCanvas());
        register('axios', Axios);
        register('kingfisher', window.Kingfisher);
        register('scene', scene);
      }
    };
    const loadScene = function(sceneUrls, onLoad, onTap) {
      // currSceneId = id;
      // tapHandlers = tapHandlers || {};
      //  tapHandlers[id] = onTap;

      loadingTextTimer = setInterval(showLoadingText, 50);
      loadStartTime = new Date().getTime();

      let formatSceneFile = function(sceneFile) {
        if (sceneFile.includes('version')) {
          let version = sceneFile.split('=')[1];
          let id = sceneFile.split('.')[0];
          let suffix = sceneFile.split('.')[1].split('&')[0];
          return `${id}_${version}.${suffix}`;
        }
        return sceneFile;
      };

      let sceneManager = window.Kc[props.props.id + '_sceneManager'];
      sceneManager.setAllRenderEnabled(false);

      let promises = [];
      for (let i = 0; i < sceneUrls.length; i++) {
        let scenePath = sceneUrls[i];
        let rootUrl = scenePath.substring(0, scenePath.lastIndexOf('/') + 1);
        let sceneFile = scenePath.substring(scenePath.lastIndexOf('/') + 1);
        let isK3dc = sceneFile.indexOf('.k3d') > 0;
        sceneFile = formatSceneFile(sceneFile);
        console.log(sceneFile);
        promises.push(new Promise((resolve, reject) => {
          sceneManager.getOrLoadScene(
              sceneFile, 'root://',
              sceneFile, '',
              (loadedScene, isFirstTime) => {
                let scene = loadedScene.subScene;
                window.Kc[props.props.id + '_scene'] = scene;
                if (!i) {
                  currScene = loadedScene.subScene;
                }
                // window.scene = currScene;
                loadedScene.setRenderEnabled(true, 0.5, () => {
                });
                if (isFirstTime) {
                  scene.onBeforeRenderObservable.add((data, state) => {
                        let bound = domCanvas.value.getBoundingClientRect();
                        detailPanel.updateAllLine(scene, bound);
                      },
                  );
                  scene.activeCamera.attachControl(domCanvas.value, true);
                  scene.onPointerObservable.add((eventData, eventState) => {
                    if (eventData.type === 1) {
                      if (eventHandler.value.tap) {
                        try {
                          eventHandler.value.tap(eventData.event);
                        }
                        catch (e) {
                          console.error(e);
                        }
                      }
                    }
                  });
                }
                window.needFireAfterLoad = true;

                if (isK3dc) {
                  isRestCamerasThumbnailsFromScene.value = true;
                  isRestSceneModeFromScene.value = true;
                  dc3Tools.setScene(scene);
                  webPageSceneMap.set(weakKey, scene);
                  datalist.value = dc3Tools.getDeviceList();
                  scene.forcePickable = true;
                }

                let loadLogic = (code) => {
                  try {
                    window.onSceneLoaded = null;
                    //if(sceneType.value === 'k3dc'){
                    let logicStr = code.replace(
                        '__sceneId',
                        sceneFile,
                    );
                    //}

                    window.scene = scene;
                    eval(logicStr);
                    scene.puzzleLogic = window.puzzleLogic;
                    delete window.puzzleLogic;
                    delete window.scene;
                    registerContext(scene);
                    scene.puzzleLogic._pGlob.editState = editState;
                    scene.puzzleLogic._pGlob.autoFocus = openFocus.value;
                    if (scene.puzzleLogic.onSceneLoaded) {
                      scene.puzzleLogic.onSceneLoaded(isFirstTime);
                    }
                    // afterSceneLoaded();
                    if (onLoad) {
                      onLoad(scene, isFirstTime);
                    }
                    resolve();
                  } catch (e) {
                    console.error([code]);
                    console.error(e);
                    resolve();
                  }
                };
                if (scene.logicJS !== undefined) {
                  loadLogic(scene.logicJS);
                } else {
                  let logic = '';
                  let logicFile = sceneFile.replace('.json', '_logic.js');
                  logicFile = logicFile.replace('.k3ds', '_logic.js');

                  logic = window.Kingfisher.FileTools.GetAbsoluteUrl(
                      'root://' +
                      logicFile +
                      '&t=' +
                      new Date().getTime(),
                  );

                  Axios.get(logic, {headers: {'Authentication': getToken()}}).then(function(res) {
                    if (res && res.data) {
                      loadLogic(res.data);
                    }
                  }).catch(function() {
                    resolve();
                  });
                }
              },
              null,
              null,
              i,
          );
        }));

        Promise.all(promises).then(() => {
          isInitOK = true;
        });
      }

    };
    const updateDataItem = function(item) {
      item.active = !item.active;
    };
    const loadSceneFromUrl = function(
        sceneUrls,
        animation,
        loadListener,
        tapListener,
        cb,
    ) {
      if (!Array.isArray(sceneUrls)) {
        sceneUrls = [sceneUrls];
      }
      if (sceneUrls[0] === sceneUrls[1]) { // 场景和UI不能是同一个
        sceneUrls.pop();
      }
      if (sceneUrls[0]) {
        let sceneUrl = sceneUrls[0];
        let p = sceneUrl.indexOf('/');
        let scenePart = [
          sceneUrl.substring(0, p),
          sceneUrl.substring(p + 1),
        ];
        let schemes = {};
        const root = window.Kf.config.server + '/cloud/';
        if (sceneUrl.indexOf('.k3d') === -1) {
          schemes = {
            'root://': root + 'api/repo/kf-scene/find-resources?path=' + scenePart[0],
            'resources://': root + 'resources/',
            'lib://': root + '3dc/static/',
          };
        } else {
          let temp = root + 'api/repo/kf-scene-3d/find-resources?path=' + scenePart[0];
          schemes = {
            'root://': temp,
            'k3dc://': temp,
            'resources://': root + 'resources/',
            'lib://': root + '3dc/static/',
          };
        }
        window.Kingfisher.FileTools.RegisterSchemes(schemes);
      }

      loadScene(
          sceneUrls,
          function(scene) {
            try {
              if (loadListener) {
                loadListener();
              }
              if (eventHandler.value.load) {
                eventHandler.value.load(scene);
              }

              if (cb) {
                cb();
              }
            } catch (e) {
              console.error(e);
            }
          },
          tapListener,
      );
    };

    const switchDropDown = function() {
      showDropDown.value = !showDropDown.value;
    };

    let canvasInitFlag = false;

    const initCanvas = function() {
      if (domCanvas.value != null && !canvasInitFlag) {
        let dom = domCanvas.value;
        dom.style.width = '100%';
        dom.style.height = '100%';
        canvasInitFlag = true;

        utils.runUntil(() => {
          return window.Kingfisher?.Engine != null;
        }, () => {
          initScene();
        });
        initStats();
      }
    };

    const init = () => {
      if (isDisposed) {
        return;
      }
      if (window.Kf || window.Kf.login || window.Kf.ssoReady) {
        console.log('进入3D组件');

        initStats();
        let loadingTime = localStorage.getItem(
            props.props.id + '_loadingtime',
        );
        if (loadingTime == null) {
          loadingTime = 10 * 1000;
        }
        expectedLoadingTime = loadingTime;

        /*let initSceneID = 'initScene' + props.props.id;
        window[initSceneID] = () => {
          initScene();
          setTimeout(() => {
            delete window[initSceneID];
          }, 2000);
        };
        window.Kf.loadLib(
            'static/kingfisher.lib',
            'static/kingfisher.lic',
            initSceneID,
        );*/

        watch(domCanvas, initCanvas);

        containerStyle.value = styleManager.updateStyle(proxy);
        window.addEventListener('message', handleMessage);
        let observer = new ResizeObserver(function(entries) {
          for (let entry of entries) {
            if (entry.contentRect.width > 0) {
              let canvas = domCanvas.value;
              let containerDom = container.value;
              let scaling = getHardwareScalingLevel(
                  canvas.clientWidth,
                  canvas.clientHeight,
              );
              if (getEngine()) {
                getEngine().setHardwareScalingLevel(scaling);
                getEngine().resize(
                    containerDom.clientWidth,
                    containerDom.clientHeight,
                );
              }
            }
          }
        });
        observer.observe(container.value);
      } else {
        window.setTimeout(init, 100);
      }
    };

    onMounted(() => {
      init();
      initCanvas();
      cardStyle.value = styleManager.updateStyle(proxy);
      buttonClass.value = styleManager.updateClass(proxy);
    });
    const isOpenFooter = function() {
      isShowFooter.value = !isShowFooter.value;
    };
    onUnmounted(() => {
      isDisposed = true;
      //setWeb3dModelNull();
      for (let key in eventCallbacks) {
        globalEventManager.removeCallbackById(eventCallbacks[key]);
      }
      eventCallbacks = {};
      try {
        console.log('销毁三维组件');
        let engine = getEngine();
        if (engine) {
          if (loadingTextTimer) {
            clearInterval(loadingTextTimer);
          }
          if (engine.loadingScreen) {
            engine.loadingScreen.hideLoadingUI();
          }
          engine.dispose();
          console.log('引擎已经销毁');
          delete window.Kc[props.props.id + '_engine'];
          delete window.Kc[props.props.id + '_scene'];
          delete window.Kc[props.props.id + '_sceneManager'];
          delete window.Kc[props.props.id + '_container'];
        }
        console.log('组件已经销毁');
        if (currScene) {  // 拓扑图断开链接和解除订阅
          let stInstance = SysTopo.getSysTopoInstance(currScene);
          stInstance && stInstance.endSysTopoWs();
        }
        if (props.props?.sceneData) {
          let {type} = props.props.sceneData;
          if (type !== 'artist') {
            mapping.destroyScript(); // 脚本mapping的数据销毁
          }
        }
      } catch (e) {
        console.error(e);
      }
    });
    const isOpenFocus = function(bool) {
      globalEventManager.issueEvent('/web3d_auto_focus', {
        componentKey: props.props.id,
        data: bool,
      });
    };
    isOpenFocus(openFocus.value);
    eventCallbacks['/web3d_auto_focus'] = globalEventManager.addCallback(
        '/web3d_auto_focus',
        (args) => {
          if (
              args.data.componentKey &&
              args.data.componentKey !== props.props.id
          ) {
            return;
          }
          openFocus.value = !!args.data.data;
          if (currScene && currScene.puzzleLogic) {
            currScene.puzzleLogic._pGlob.autoFocus = openFocus.value;
          }
        },
    );

    eventCallbacks['/web3d_camera_perspective'] =
        globalEventManager.addCallback(
            '/web3d_camera_perspective',
            (args) => {
              if (
                  args.data.componentKey &&
                  args.data.componentKey !== props.props.id
              ) {
                return;
              }
              cameraPerspective.value = !!args.data.data;
              if (!currScene || currScene.isDisposed) {
                return;
              }
              let camera = currScene.activeCamera;
              if (cameraPerspective.value) {
                camera.yaw = 0.63;
                camera.pitch = -0.4;
              } else {
                camera.yaw = 0;
                camera.pitch = -1.6818939830448931;
              }
              camera.focusOnObject(currScene.kPartLoaders, 1, {
                ratio: 1.2,
                minDistance: 35,
              });
            },
        );

    const switchFullScreen = function() {
      pageModel.setPropValue(
          props.props,
          props.props.key,
          'isFullScreen',
          !props.props.isFullScreen,
      );
    };

    const reset = function() {
      // 重置按钮生效：执行恢复默认相机位置，关闭所有开启的弹窗，清理过滤设置
      showDropDown.value = false;
      cameraPerspective.value = true;
      switchCameraPerspective(true);
      pageModel.setPropValue(
          props.props,
          props.props.key,
          'isFullScreen',
          false,
      );
    };

    const viewportBound = computed(() => {
      let result = {
        width: 1908,
        height: 912,
        x: 0,
        y: 0,
      };
      if (domCanvas.value) {
        result = domCanvas.value.getBoundingClientRect();
      }

      return result;
    });

    const issueEvent = function(event, params) {
      window.postMessage({action: 'puzzleEvent', event: {name: event, args: _.cloneDeep(params)}}, '*');
    };

    return {
      viewportBound,
      domCanvas,
      container,
      containerStyle,
      eventHandler,
      panelsObjectSet,
      dc3Tools,
      showDropDown,
      updateDataItem,
      switchDropDown,
      datalist,
      isShowFooter,
      isOpenFooter,
      isOpenFocus,
      openFocus,
      cameraPerspective,
      switchCameraPerspective,
      switchFullScreen,
      weakKey,
      buttonClass,
      cardStyle,
      loadSceneFromUrl,
      reset,
      issueEvent,
    };
  },
  widgetConfig: {
    rank: 3,
    label: {
      zh: Kf.t('3dComponent'),
    },
    category: Kf.t('3d'),
    component: 'kfWeb3d',
    display: true,
    version: 1,
    icon: 'icon-anniu',
    defaultSize: {
      x: 800,
      y: 600,
    },
    minSize: {
      width: 400,
      height: 400,
    },

    state: {
      isAdd: false,
      isCondition: false,
    },
  },
};
</script>


<style lang="scss" scoped>
.scoped-web3dspace-footer {
  position: absolute;
  bottom: 0;
  left: 0;
  width: calc(100% - 1px);
  height: 32px;
  background-color: #282828;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 2px 8px;
  font-size: 12px;
  box-sizing: border-box;

  .scoped-web3dspace-footer-left {
    .scoped-web3dspace-footer-left-set {
      width: 122px;
      border-radius: 6px;
      display: flex;
      justify-content: space-between;
      align-items: flex-start;
      border: 1px solid rgba(255, 255, 255, 0.05);

      .scoped-web3dspace-footer-left-set1 {
        height: 26px;
        line-height: 26px;
        font-size: 12px;
        color: rgba(255, 255, 255, 0.8);
        text-align: center;
        flex: 1 1 50%;
      }

      .scoped-web3dspace-footer-left-set-active {
        border-radius: 5px;
        border: 1px solid rgba(255, 255, 255, 0.12);
        background: rgba(48, 87, 146, 0.5);
      }
    }
  }

  .scoped-web3dspace-footer-right {
    height: 28px;
    line-height: 28px;
    color: #ffffff88;
    display: flex;

    .scoped-web3dspace-footer-right-item {
      display: flex;
      margin: 0 8px;
      align-items: center;

      .scoped-web3dspace-footer-right-item-title {
        font-size: 12px;
        margin: 0 4px;
      }

      .scoped-web3dspace-footer-right-item-title {
        height: 28px;
        line-height: 28px;
      }

      .scoped-web3dspace-footer-right-item-model {
        width: 48px;
        height: 22px;
        background: rgba(255, 255, 255, 0.05);
        border-radius: 12px;
        display: flex;
        box-sizing: border-box;

        .kf-switch-box {
          flex: 1 1 50%;
          cursor: pointer;

          .kf-switch-con {
            width: 12px;
            height: 12px;
            border-radius: 6px;
            background: #868686;
            margin: 4px 6px;
            cursor: pointer;
          }
        }
      }

      .scoped-web3dspace-footer-right-item-model-active {
        background: rgba(48, 87, 146, 0.5);

        .kf-switch-box {
          .kf-switch-con.kf-switch-con-active {
            background: #fff;
          }
        }
      }
    }
  }
}

.scoped-web3dc-header {
  height: 40px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #282828;
  position: absolute;
  width: calc(100% - 1px);
  padding: 10px 0;
  left: 0;
  top: 0;
  border-top: 1px solid rgba(255, 255, 255, 0.05);
  border-left: 1px solid rgba(255, 255, 255, 0.05);

  .scoped-web3dc-header-breadcrumbs {
    display: flex;
    font-size: 16px;
    height: 20px;
    line-height: 20px;

    .scoped-web3dc-header-breadcrumbs1 {
      display: flex;
      color: rgba(255, 255, 255, 0.8);

      .scoped-web3dc-header-breadcrumbs2 {
        margin: 0 4px;
        padding: 0 6px;
        color: rgba(255, 255, 255, 0.8);
        font-size: 12px;
        pointer-events: auto;
      }
    }
  }

  .scoped-web3dc-header-toolBar {
    display: flex;
    padding-right: 4px;

    .iconfont {
      display: block;
      margin: 0 4px;
      padding: 0 4px;
      pointer-events: auto;
    }
  }

  .scoped-web3dc-header-toolBar-dropDown {
    height: 128px;
    width: 100%;
    overflow: auto;
    position: absolute;
    top: 40px;
    display: flex;
    padding: 6px 12px;
    background-color: #0e0e0e;
    flex-wrap: wrap;
    font-size: 12px;

    .scoped-web3dc-header-toolBar-dropDown-item {
      height: 32px;
      display: flex;
      width: auto;
      flex-wrap: nowrap;
      padding: 4px 8px;
      justify-content: center;
      align-items: center;
      border-radius: 6px;
      border: 1px solid rgba(255, 255, 255, 0.12);
      background: #0c0c0c;
      margin: 3px;
      pointer-events: auto;

      .scoped-web3dc-header-toolBar-dropDown-item1 {
        margin: 0 4px;
      }

      .scoped-check {
        * {
          pointer-events: none !important;
        }
      }
    }
  }
}
</style>
