import { watch, inject, markRaw, ref, computed, onMounted } from "vue";
import { useRoute } from "vue-router";
import useHeatmapBarStore from "@/stores/useHeatmapBarStore";
import useSystemShowData from "@/hooks/useSystemShowData";

export default function useForgeHeatmap() {
  const route = useRoute();
  const { subscribeData, realtimeData } = inject("system_deviceList");

  const store = useHeatmapBarStore();

  const forgeViewer = ref(null);
  const dataVizExtn = ref(null);
  const updateViewExtension = (viewer, dataVisualization) => {
    forgeViewer.value = viewer;
    dataVizExtn.value = dataVisualization;
  };

  //create the heatmap
  function getSensorValue(device, sensorType, pointData) {
    const dev = realtimeData.value.find(
      ({ device_number }) => device_number === device.id
    );
    if (dev) {
      const [min, max] = store.heatmapConfig?.range;
      const point = dev.data.find(({ point }) => point === route.query?.gas);
      console.log(9, device, dev, point, (point?.value - min || 0) / max);

      return Math.random();
    }
    return 0;
  }

  const { flatSubData } = useSystemShowData();

  const data = computed(() =>
    flatSubData.value?.map((d) => {
      const pointsMap = d.points ? Object.fromEntries(d.points.map(({ point, value }) => [point, 0])) : {};
      return {
        ...d,
        ...pointsMap,
      };
    })
  );

  watch(
    () => realtimeData,
    () => {
      dataVizExtn.value &&
        Object.keys(dataVizExtn.value?.surfaceShading)?.length &&
        dataVizExtn.value.updateSurfaceShading(getSensorValue);
    },
    {
      deep: true,
    }
  );

  const createHeatMap = async () => {
    if (route.query?.gas === "all" || !route.query?.gas || !dataVizExtn.value) return;
    const heatMapName = `iot_heatmap_${route.query?.gas}`;
    console.log("createHeatMap", heatMapName);
    const {
      SurfaceShadingData,
      SurfaceShadingPoint,
      SurfaceShadingNode,
      SurfaceShadingGroup,
    } = Autodesk.DataVisualization.Core;
    const shadingGroup = new SurfaceShadingGroup(`${heatMapName}`);
    const rooms = new Map();

    const roomSet = new Set(data.value.filter(({ device_coordinate_3d }) => device_coordinate_3d).map(({ room_dbid }) => room_dbid));
    // 每個room是一個node
    [...roomSet].forEach((roomDbId) => {
      if (!roomDbId) {
        return;
      }
      const room = new SurfaceShadingNode(`room_${roomDbId}`, roomDbId);

      //相同room內的設備
      data.value
        .filter(({ room_dbid }) => room_dbid === roomDbId)
        .forEach(
          ({
            device_number: id,
            device_coordinate_3d: position,
            sensorTypes,
          }) =>
            room.addPoint(new SurfaceShadingPoint(id, position, sensorTypes))
        );

      shadingGroup.addChild(room);
    });

    // data.value.forEach(
    //   ({
    //     device_number: id,
    //     room_dbid: roomDbId,
    //     device_coordinate_3d: position,
    //     sensorTypes,
    //   }) => {
    //     if (!id || roomDbId == -1 || !roomDbId) {
    //       return;
    //     }
    //     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, route.query.gas));
    //   }
    // );
    const shadingData = new SurfaceShadingData(`${heatMapName}`);
    shadingData.addChild(shadingGroup);
    shadingData.initialize(forgeViewer.value?.model);
    await dataVizExtn.value.setupSurfaceShading(
      forgeViewer.value.model,
      shadingData
    );
    dataVizExtn.value.registerSurfaceShadingColors(
      route.query?.gas,
      store.heatmapConfig?.color
    );
    dataVizExtn.value.renderSurfaceShading(
      heatMapName,
      route.query?.gas,
      getSensorValue
    );
  };

  watch(
    data,
    (newValue, oldValue) => {
      dataVizExtn.value?.removeSurfaceShading();
      createHeatMap(route.query.gas);
    },
    { deep: true }
  );

  return { createHeatMap, updateViewExtension };
}
