<script setup>
import {
  ref,
  onMounted,
  defineProps,
  computed,
  onUnmounted,
  watch,
  watchEffect,
  provide,
  inject,
} from "vue";
import { twMerge } from "tailwind-merge";
import useSystemStatusByBaja from "@/hooks/baja/useSystemStatusByBaja";
import ForgeInfoModal from "./ForgeInfoModal.vue";
import useSearchParams from "@/hooks/useSearchParam";
const { searchParams } = useSearchParams();
const FILE_BASEURL = import.meta.env.VITE_FILE_API_BASEURL;
const { forgeLock } = inject("app_toggle");
const props = defineProps({
  fullScreen: Boolean,
  initialData: Object,
  pipeData: Array,
  realTime: String,
  meterList: Array,
  heatmapDevices: Array,
});

const {
  visibleDbid,
  updateMeterPositions,
  hideAllObjects,
  updateForgeViewer,
  forgeViewer,
  urn,
  loadModel,
  updateInitialData,
  updatePipeData,
  subComponents,
  clearSprites,
  updateTemp,
  fitToView,
} = useSystemStatusByBaja();

// 用於存儲 meter label 的 2D 位置
const meterPositions = ref(new Map());

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

watch(
  () => props.pipeData,
  (newValue, oldValue) => {
    if (JSON.stringify(newValue) === JSON.stringify(oldValue)) return;
    newValue && updatePipeData(newValue);
  },
  {
    deep: true,
  }
);

watch(
  () => props.heatmapDevices,
  (newValue) => {
    if (!newValue || newValue.length === 0) return;
    newValue &&
      updateTemp(newValue[0]?.forge_dbid, parseFloat(newValue[0]?.temperature));
  },
  {
    deep: true,
  }
);

// 更新 meter labels 的位置
const updateMeterPositionsLocal = () => {
  if (!props.meterList) return;
  const newPositions = updateMeterPositions(props.meterList);
  meterPositions.value = newPositions;
};

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" ||
      import.meta.env.MODE === "staging"
        ? `${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);
        }
      );

      // 添加 camera 變化事件監聽，更新 meter 位置
      viewer.addEventListener(Autodesk.Viewing.CAMERA_CHANGE_EVENT, () => {
        console.log("CAMERA_CHANGE_EVENT");
        updateMeterPositionsLocal();
      });
    });
  });
};

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

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);
  clearSprites();
  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 overflow-x-hidden',
          fullScreen ? 'min-h-screen ' : 'min-h-[600px]'
        )
      "
    >
      <!-- 回到 Home 視角 -->
      <div class="absolute top-0 right-[26%] z-30">
        <button
          class="p-4"
          @click="fitToView()"
          aria-label="回到初始視角"
          title="回到初始視角"
        >
          <!-- Home Icon -->
          <svg
            xmlns="http://www.w3.org/2000/svg"
            width="25"
            height="25"
            viewBox="0 0 24 24"
          >
            <path
              fill="currentColor"
              d="m21.743 12.331l-9-10c-.379-.422-1.107-.422-1.486 0l-9 10a1 1 0 0 0-.17 1.076c.16.361.518.593.913.593h2v7a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-4h4v4a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-7h2a.998.998 0 0 0 .743-1.669"
            />
          </svg>
        </button>
      </div>
      <p class="absolute z-10 top-14 left-[27%]">
        更新時間 : {{ props.realTime }}
      </p>
      <div v-show="searchParams?.option == 4" 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>
      <template v-if="searchParams?.option == 5">
        <label
          v-for="value in props.meterList"
          :key="value.main_id"
          :data-dbid="value.forge_dbid"
          v-show="meterPositions.get(value.main_id)?.visible !== false"
          :class="
            twMerge(
              '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 bg-green-600',
              '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: `${meterPositions.get(value.main_id)?.x || 0}px`,
            top: `${meterPositions.get(value.main_id)?.y || 0}px`,
          }"
        >
          <span class="mr-2">{{ value.name }}</span>
        </label>
      </template>
    </div>
  </div>
</template>

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

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

.viewcubeWrapper {
  right: 25% !important;
  top: 0% !important;
}

.homeViewWrapper {
  display: none !important;
}

.heatbar {
  left: 27% !important;
  top: 9% !important;
}
</style>
