// to deal with the temperature heatmap
import { ref, watch, markRaw, onUnmounted } from "vue";
import useSearchParams from "@/hooks/useSearchParam";

export default function useSystemHeatmap() {
  const { searchParams } = useSearchParams();

  // Viewer and DataVisualization Extension References
  const forgeViewer = ref(null);
  const dataVizExtension = ref(null);
  const deviceList = ref([]);
  const heatMaps = ref({});
  const isHeatMapSetup = ref(false); // 狀態標記，追蹤是否已初始化熱圖

  // Initialize Heatmap
  const initHeatMap = async (viewer) => {
    forgeViewer.value = markRaw(viewer);
    const dataVizExtn = await viewer.loadExtension(
      "Autodesk.DataVisualization"
    );
    dataVizExtension.value = markRaw(dataVizExtn);
  };

  // Update Heatmap Data
  const updateHeatMapData = (deviceArr) => {
    deviceList.value = Object.values(deviceArr).map((d) => ({
      ...d,
      id: d.forge_dbid, // An ID to identify this device
      roomDbId: d.room_dbid,
      position: JSON.parse(d.device_coordinate_3d),
      sensorTypes: ["temperature"], // The types/properties this device exposes
      temp: 0,
      dbId: d.forge_dbid,
      subSys: "freezer",
    }));
  };

  //create the heatmap
  function getSensorValue(device, sensorType, pointData) {
    const dev = deviceList.value.find(
      ({ forge_dbid }) =>forge_dbid === device.id
    );
    console.log(9, device, dev);
    // 假設溫度範圍 -20 ~ 40
    const temp = parseFloat(dev?.temp ?? 0);
    const min = -20,
      max = 40;
    const ratio = (temp - min) / (max - min);
    return Math.max(0, Math.min(1, ratio));
  }

  // Update Specific Device Temperature
  const updateTemp = (forge_dbid, temp) => {
    const subDevIndex = deviceList.value.findIndex(
      (d) => d.forge_dbid === forge_dbid
    );
    if (subDevIndex !== -1) {
      deviceList.value[subDevIndex] = {
        ...deviceList.value[subDevIndex],
        temp,
      };
      if (isHeatMapSetup.value) {
        dataVizExtension.value.updateSurfaceShading(getSensorValue);
      }
    }
  };

  // Create Heatmap
  const createHeatMap = async (heatMapName) => {
    const {
      SurfaceShadingData,
      SurfaceShadingPoint,
      SurfaceShadingNode,
      SurfaceShadingGroup,
    } = Autodesk.DataVisualization.Core;

    const shadingGroup = new SurfaceShadingGroup(`iot_heatmap_${heatMapName}`);
    const rooms = new Map();

    for (const { id, roomDbId, position, sensorTypes } of deviceList.value) {
      if (!id || roomDbId == -1 || !roomDbId) continue;

      if (!rooms.has(roomDbId)) {
        const room = new SurfaceShadingNode(id, roomDbId);
        shadingGroup.addChild(room);
        rooms.set(roomDbId, room);
      }

      const room = rooms.get(roomDbId);
      room.addPoint(new SurfaceShadingPoint(id, position, sensorTypes));
    }

    const shadingData = new SurfaceShadingData();
    shadingData.addChild(shadingGroup);
    shadingData.initialize(forgeViewer.value?.model);

    try {
      await dataVizExtension.value.setupSurfaceShading(
        forgeViewer.value.model,
        shadingData
      );
      dataVizExtension.value.registerSurfaceShadingColors(
        "temperature",
        [0x0000ff, 0x00ff00, 0xffff00, 0xff0000]
      );
      dataVizExtension.value.renderSurfaceShading(
        `iot_heatmap_${heatMapName}`,
        "temperature",
        getSensorValue
      );

      isHeatMapSetup.value = true; // 標記初始化完成
      console.log(`熱圖 ${heatMapName} 初始化完成`);
    } catch (error) {
      console.error("初始化熱圖時出現錯誤：", error);
      isHeatMapSetup.value = false;
    }
  };

  // Cleanup Heatmap
  const cleanupHeatMap = () => {
    if (isHeatMapSetup.value) {
      try {
        dataVizExtension.value?.removeSurfaceShading();
        console.log("成功清理熱圖資源");
      } catch (error) {
        console.error("清理熱圖資源時出現錯誤：", error);
      } finally {
        isHeatMapSetup.value = false;
      }
    }
  };

  watch(
    () => searchParams.value.option,
    (newOption, oldOption) => {
      console.log("熱圖更新 (option changed)", { newOption, oldOption });
      switch (parseInt(newOption)) {
        case 4:
          createHeatMap("frozen");
          break;
        default:
          if (isHeatMapSetup.value) {
            dataVizExtension.value?.removeSurfaceShading();
            isHeatMapSetup.value = false;
            console.log("成功移除熱圖");
          } else {
            console.warn(
              "跳過 removeSurfaceShading，因為尚未 setupSurfaceShading"
            );
          }
          break;
      }
    },
    { immediate: true }
  );

  // Cleanup on Component Unmount
  onUnmounted(() => {
    cleanupHeatMap();
  });

  return { updateHeatMapData, updateTemp, initHeatMap };
}
