<script setup>
import {
  ref,
  onMounted,
  defineProps,
  computed,
  onUnmounted,
  watch,
  watchEffect,
  provide,
  inject,
} from "vue";
import { getUrn, getAccessToken } from "@/apis/forge";
import { twMerge } from "tailwind-merge";
import useSystemStatusByBaja from "@/hooks/baja/useSystemStatusByBaja";
import ForgeInfoModal from "./ForgeInfoModal.vue";
import useAlarmStore from "@/stores/useAlarmStore";
const FILE_BASEURL = import.meta.env.VITE_FILE_API_BASEURL;
const { forgeLock } = inject("app_toggle");
const props = defineProps({
  fullScreen: Boolean,
  initialData: Object,
  cubeStyle: {
    type: Object,
    default: {
      right: 25,
      top: 2,
    },
  },
});

const heat_bar_isShow = ref(false);
const updateHeatBarIsShow = (isShow) => {
  heat_bar_isShow.value = isShow;
};

const {
  subscribeData,
  visibleDbid,
  updateDbidPosition,
  hideAllObjects,
  updateForgeViewer,
  forgeViewer,
  urn,
  loadModel,
  updateInitialData,
  subComponents,
} = useSystemStatusByBaja(updateHeatBarIsShow);

watch(
  () => props.initialData,
  (newValue) => {
    newValue && updateInitialData(newValue);
  },
  {
    deep: true,
  }
);

const store = useAlarmStore();
const subscribeDataWithErrorMsg = computed(() => {
  let data = { ...subscribeData.value };

  for (let [key, value] of Object.entries(subscribeData.value)) {
    const alarm = store.alarmData.find(
      ({ device_number }) => device_number === key
    );
    data[key].alarmMsg = alarm ? alarm.msg : "";
  }
  console.log("baja update data: ", data);
  return data;
});

const forgeDom = ref(null);

const initViewer = (container) => {
  return new Promise(function (resolve, reject) {
    Autodesk.Viewing.Initializer(
      {
        env: "Local",
        language: "en",
      },
      function () {
        const config = {
          extensions: [
            "Autodesk.DataVisualization",
            "Autodesk.DocumentBrowser",
          ],
        };
        let viewer = new Autodesk.Viewing.GuiViewer3D(container, config);
        Autodesk.Viewing.Private.InitParametersSetting.alpha = true;
        viewer.start();
        resolve(viewer);
      }
    );
  });
};

const initForge = () => {
  initViewer(forgeDom.value).then((viewer) => {
    const localFilePath =
      import.meta.env.MODE === "production"
        ? `${FILE_BASEURL}/upload/forge/0.svf`
        : "/forge/0.svf";
    loadModel(viewer, localFilePath).then(() => {
      viewer.addEventListener(
        Autodesk.Viewing.GEOMETRY_LOADED_EVENT,
        async function () {
          console.log(
            "Autodesk.Viewing.GEOMETRY_LOADED_EVENT",
            viewer.isLoadDone()
          );
          updateForgeViewer(viewer);

          const tree = viewer.model.getData().instanceTree;
          hideAllObjects(tree, visibleDbid.value);

          // 印出被點選物件的 dbid
          // viewer.addEventListener(
          //   Autodesk.Viewing.SELECTION_CHANGED_EVENT,
          //   function (event) {
          //     console.log("你選取的 forge_dbid：", event.dbIdArray);
          //   }
          // );
        }
      );
      viewer.addEventListener(
        Autodesk.Viewing.CAMERA_CHANGE_EVENT,
        function (e) {
          viewer.isLoadDone() && updateDbidPosition(this, subscribeData.value);
          console.log(
            "camera position changed: ",
            NOP_VIEWER.navigation.getTarget(),
            e.camera.position
          );
        }
      );
    });
  });
};

onMounted(() => {
  console.log("Forge 加載");
  initForge();
});

// 傳遞目前點擊資訊
const currentInfoModalData = ref(null);
const isMobile = (pointerType) => {
  return pointerType !== "mouse"; // is desktop
};
const getCurrentInfoModalData = (e, position, value) => {
  const mobile = isMobile(e.pointerType);
  currentInfoModalData.value = {
    initPos: mobile
      ? { left: `50%`, top: `50%` }
      : { left: `${position.left}px`, top: `${position.top}px` },
    value,
    isMobile: mobile,
  };
  forge_info_modal.showModal();
};

watch([forgeViewer, forgeLock], ([newViewer, newLock]) => {
  if (newViewer && newLock !== undefined) {
    newViewer.setNavigationLock(newLock); // 鎖定視角
    newViewer.navigation.setZoomTowardsPivot(!newLock); // 滾輪縮放
    newViewer.navigation.setReverseZoomDirection(newLock); // 滑動變更視角
  }
});

onUnmounted(() => {
  console.log("Forge 銷毀");
  console.log("sub", subComponents);
  subComponents.value?.unsubscribeAll();
  subComponents.value?.detach();
  updateForgeViewer(null);
  NOP_VIEWER.tearDown();
});
</script>

<template>
  <ForgeInfoModal :data="currentInfoModalData" />
  <div
    :class="
      twMerge(
        fullScreen
          ? 'absolute top-0 left-0 w-screen h-full z-0'
          : 'w-full relative'
      )
    "
  >
    <div
      id="forge-preview"
      ref="forgeDom"
      :class="
        twMerge(
          'relative w-full h-full',
          fullScreen ? 'min-h-screen ' : 'min-h-[600px]'
        )
      "
    >
      <div v-show="heat_bar_isShow" class="absolute z-10 heatbar">
        <div class="w-40 flex justify-between text-[10px] mb-1">
          <span class="text-gradient-1">-20°C</span>
          <span class="text-gradient-2">0°C</span>
          <span class="text-gradient-3">20°C</span>
          <span class="text-gradient-4">40°C</span>
        </div>
        <div
          class="w-40 h-3"
          style="
            background: linear-gradient(
              to right,
              #0000ff 0%,
              #00ff00 33%,
              #ffff00 66%,
              #ff0000 100%
            );
          "
        ></div>
      </div>

      <label
        v-for="(value, key) in subscribeDataWithErrorMsg"
        :key="key"
        :data-dbid="value.forge_dbid"
        :class="
          twMerge(
            `after:border-t-[${value.currentColor}]`,
            'flex items-center justify-center h-12 -translate-x-1/2 -translate-y-1/5 absolute z-50 px-5 py-4 text-center rounded-md text-lg border-2 border-white',
            'after:absolute after:border-t-[10px] after:border-x-[12px] after:border-x-transparent after:-bottom-[8px] after:left-1/2 after:-translate-x-1/2 ',
            'before:absolute before:border-t-[12px] before:border-x-[14px] before:border-x-transparent before:-bottom-[12px] before:left-1/2 before:-translate-x-1/2 before:border-white'
          )
        "
        :style="{
          left: `${Math.floor(value.device_coordinate_3d.x)}px`,
          top: `${Math.floor(value.device_coordinate_3d.y) - 100}px`,
          display: value.is_show,
          backgroundColor: value.currentColor,
        }"
        @click.prevent="
          (e) =>
            getCurrentInfoModalData(
              e,
              { left: e.clientX, top: e.clientY },
              value
            )
        "
      >
        <span class="mr-2">{{ value.full_name }}</span>
        <span v-if="value.alarmMsg">{{ value.alarmMsg }}</span>
        <span v-else>{{ value.show_value }}</span>
      </label>
    </div>
  </div>
</template>

<style lang="css">
.adsk-viewing-viewer {
  background-color: transparent !important;
}

#guiviewer3d-toolbar {
  display: none;
  bottom: 200px;
}

.viewcubeWrapper {
  right: v-bind("`${props.cubeStyle.right}%`") !important;
  top: v-bind("`${props.cubeStyle.top}%`") !important;
}

.homeViewWrapper {
  transform: scale(1.5) !important;
}

.heatbar {
  right: v-bind("`${props.cubeStyle.right + 2}%`") !important;
  top: 0% !important;
}
</style>
