<script setup>
import { RouterView, useRoute } from "vue-router";
import { computed, watch, provide, ref, onMounted, onUnmounted } from "vue";
import SystemFloorBar from "./components/SystemFloorBar.vue";
import SystemDeptBar from "./components/SystemDeptBar.vue";
import useBuildingStore from "@/stores/useBuildingStore";
import ForgeForSystem from "@/components/forge/ForgeForSystem.vue";
import { getSystemDevices, getSystemRealTime } from "@/apis/system";
import { getOperationCompanyList } from "@/apis/operation";
import { getAssetSingle, getAssetFloorList } from "@/apis/asset";
import SystemSubBar from "./components/SystemSubBar.vue";
import SystemInfoModal from "./components/SystemInfoModal.vue";
import SystemMain from "./SystemMain.vue";
import SystemMode from "./components/SystemMode.vue";
import SystemFloor from "./SystemFloor.vue";
import { twMerge } from "tailwind-merge";
import dayjs from "dayjs";

const FILE_BASEURL = import.meta.env.VITE_FILE_API_BASEURL;
const buildingStore = useBuildingStore();

const statusList = computed(() => {
  const sub = buildingStore.selectedSystem;

  if (sub) {
    return {
      device_normal_color: sub.device_normal_color,
      device_normal_text: sub.device_normal_text,
      device_close_color: sub.device_close_color,
      device_close_text: sub.device_close_text,
      device_error_color: sub.device_error_color,
      device_error_text: sub.device_error_text,
    };
  }
  return null;
});

const raw_data = ref([]);
const data = ref([]); // filter data
const route = useRoute();
const floors = ref([]);
const deptData = ref([]);
const companyOptions = ref([]);
const selected_dbid = ref([]);
const imgBaseUrl = ref("");

const getFloors = async () => {
  const res = await getAssetFloorList();
  floors.value = res.data[0]?.floors.map((d) => ({ ...d, key: d.floor_guid }));
};

const getCompany = async () => {
  const res = await getOperationCompanyList();
  companyOptions.value = res.data.map((d) => ({ ...d, key: d.id }));
};

const getData = async () => {
  if (!route.params.sub_system_id) return;
  const res = await getSystemDevices({
    sub_system_tag: route.params.sub_system_id,
    building_guid: buildingStore.selectedBuilding?.building_guid,
    department_id_list: deptData.value,
  });
  const devices = res.data.map((d) => ({
    ...d,
    key: d.full_name,
    device_list: d.device_list.map((dev, index) => ({
      ...dev,
      forge_dbid: parseInt(dev.forge_dbid),
      room_dbid: parseInt(dev.room_dbid),
      device_coordinate_3d: dev.device_coordinate_3d
        ? JSON.parse(dev.device_coordinate_3d)
        : "",
      alarmMsg: "",
      is_show: true,
      currentColor: dev.device_normal_point_color,
      spriteDbId: 10 + dev.main_id,
      sensorTypes: dev.points ? dev.points.map(({ points }) => points) : [],
      floor_guid: d.floor_guid,
      is2DActive: false,
    })),
  }));

  raw_data.value = devices;
  data.value = devices;
  console.log("devices", res.data, devices);
};

const subscribeData = ref([]); // flat data

const getSubData = (value) => {
  let items = [];
  value.forEach((device) => {
    items = [...items, ...device.device_list];
  });
  return items;
};

watch(raw_data, (newValue) => {
  if (route.query.gas) {
    updateDataByGas(route.query.gas);
  } else {
    const items = getSubData(newValue);
    data.value = newValue;
    subscribeData.value = items;
  }
});

const updateDataByGas = (gas) => {
  let update_values = [];
  if (gas === "all") {
    update_values = raw_data.value;
  } else {
    update_values = raw_data.value.map((d) => ({
      ...d,
      device_list: d.device_list.filter(({ points }) => {
        if (points) {
          return points.some(({ points: p }) => p === gas);
        }
        return false;
      }),
    }));
  }
  data.value = update_values;
  subscribeData.value = getSubData(update_values);
};

watch(
  () => buildingStore.selectedBuilding,
  (newBuilding) => {
    if (Boolean(newBuilding)) {
      getData();
    }
  },
  {
    immediate: true,
    deep: true,
  }
);

watch(
  [() => buildingStore.previewImageExt, () => buildingStore.selectedBuilding?.building_guid],
  ([newExt, buildingGuid]) => {
    if (newExt && buildingGuid) {
      imgBaseUrl.value = `${FILE_BASEURL}/upload/setting/previewImage/${buildingGuid}${newExt}`;
    } else {
      imgBaseUrl.value = `${FILE_BASEURL}/upload/build_img.jpg`;
    }
  },
  { immediate: true }
);

watch(
  () => deptData.value,
  (newVal) => {
    if (newVal) {
      getData();
    }
  },
  {
    immediate: true,
    deep: true,
  }
);

watch(
  () => route.params.sub_system_id,
  (newRoute, oldRoute) => {
    if (buildingStore.selectedBuilding && newRoute !== oldRoute) {
      getData();
    }
  }
);

onMounted(() => {
  getFloors();
  getCompany();
});

const currentFloor = ref(null);

const updateCurrentFloor = (floor) => {
  currentFloor.value = floor;
};

const realtimeData = ref([]);
let timeId = null;
const getAllDeviceRealtime = async () => {
  // 立即執行一次
  const fetchData = async () => {
    const res = await getSystemRealTime(
      subscribeData.value.map((d) => d.device_number)
    );
    console.log("realtimeData",res.data);
    realtimeData.value = res.data;
  };
  await fetchData(); // 立即執行一次
  if (timeId) {
    clearInterval(timeId);
    timeId = null;
  }
  // 然後設定每 10 秒更新一次
  timeId = setInterval(fetchData, 10 * 1000);
};

watch(
  subscribeData,
  (newValue) => {
    console.log("subscribeData changed:", newValue);

    if (timeId) {
      clearInterval(timeId);
    }
    newValue.length > 0 && getAllDeviceRealtime();
  },
  { deep: true, immediate: true }
);

provide("system_deviceList", {
  data,
  subscribeData,
  currentFloor,
  updateCurrentFloor,
  updateDataByGas,
  realtimeData,
});

const selectedDevice = ref(null);
const selectedDeviceCog = ref({});
// const selectedDevice = computed(() => {
//   return {
//     ...currentInfo.value,
//     points: realtimeData.value.find(({ device_number }) => device_number === currentInfo.value?.value.device_number)
//   }
// });
// 傳遞目前點擊資訊
const isMobile = (e) => {
  return e.pointerType !== "mouse" && e.type !== "click"; // is mobile
};

const getCurrentInfoModalData = async (e, position, value) => {
  if (value.main_id) {
    const res = await getAssetSingle(value.main_id);
    if (res.isSuccess) {
      selectedDeviceCog.value = {
        ...res.data,
        key: res.data.id,
        floor: floors.value.find(
          ({ floor_guid }) => res.data.floor_guid === floor_guid
        )?.full_name,
        company: companyOptions.value.find(
          ({ id }) => res.data.operation_id === id
        )?.name,
        buying_date: res.data?.buying_date
          ? dayjs(res.data.buying_date).format("YYYY-MM-DD")
          : "",
        created_at: res.data?.created_at
          ? dayjs(res.data.created_at).format("YYYY-MM-DD")
          : "",
      };
    }
  }
  const mobile = isMobile(e);
  selectedDevice.value = {
    initPos: { left: `50%`, top: `50%` },
    value,
    isMobile: mobile,
  };
  document.getElementById("system_info_modal").showModal();
};

const selectedDeviceRealtime = computed(() => {
  const deviceNumber = selectedDevice.value?.value?.device_number;
  if (!deviceNumber) return [];
  return realtimeData.value
    .filter(item => item.device_number === deviceNumber && Array.isArray(item.data))
    .flatMap(item => item.data.map(dataItem => ({ ...dataItem, topic_publish: item.topic_publish })));
});

const clearSelectedDeviceInfo = () => {
  selectedDevice.value.value = null;
};

provide("system_selectedDevice", {
  selectedDeviceRealtime,
  selectedDevice,
  getCurrentInfoModalData,
  clearSelectedDeviceInfo,
  selectedDeviceCog,
  selected_dbid,
  deptData,
});

onUnmounted(() => {
  if (timeId) {
    clearInterval(timeId);
    timeId = null;
  }
});
</script>

<template>
  <SystemInfoModal :data="selectedDevice" />
  <div class="border border-info px-4 py-2">
    <h5 class="text-md font-extrabold me-4">
      {{ buildingStore.selectedSystem?.full_name }}
    </h5>
    <SystemFloorBar />
    <SystemDeptBar />
  </div>
  <div class="grid grid-cols-2 gap-5 mt-8 mb-4">
    <div class="col-span-1 h-[calc(100vh-170px)] flex flex-col justify-start">
      <div>
        <div class="flex mb-4 items-center">
          <span
            class="flex items-center mr-3"
            v-if="statusList?.device_normal_text"
          >
            <span
              class="w-7 h-7 rounded-full inline-block mr-1"
              :style="{ backgroundColor: statusList.device_normal_color }"
            ></span>
            <span>{{ statusList.device_normal_text }}</span>
          </span>
          <span
            class="flex items-center mr-3"
            v-if="statusList?.device_close_text"
          >
            <span
              class="w-7 h-7 rounded-full inline-block mr-1"
              :style="{ backgroundColor: statusList.device_close_color }"
            ></span>
            <span>{{ statusList.device_close_text }}</span>
          </span>
          <span
            class="flex items-center mr-3"
            v-if="statusList?.device_error_text"
          >
            <span
              class="w-7 h-7 rounded-full inline-block mr-1"
              :style="{ backgroundColor: statusList.device_error_color }"
            ></span>
            <span>{{ statusList.device_error_text }}</span>
          </span>
        </div>
        <SystemSubBar class="mt-2 mb-4" />
      </div>
      <div class="h-full pr-2 overflow-y-auto">
        <RouterView />
      </div>
    </div>
    <div class="col-span-1 h-full flex flex-col justify-between">
      <template v-if="buildingStore.showForgeArea">
        <SystemMode />
        <div class="h-full relative">
          <SystemFloor
            :class="
              twMerge(
                'absolute h-full w-full',
                route.query.mode === '2D' ? 'opacity-100 z-10' : 'opacity-0 z-0'
              )
            "
          />
          <div
            :class="
              twMerge(
                'absolute h-full w-full',
                route.query.mode === '3D' ? 'opacity-100 z-10' : 'opacity-0 z-0'
              )
            "
          >
            <ForgeForSystem :initialData="{}" />
          </div>
        </div>
      </template>
      <template v-else>
        <div class="h-full relative">
          <img
            alt="build"
            :src="imgBaseUrl"
            :class="
              twMerge(
                'absolute w-full h-full transition-opacity duration-300',
                route.params.floor_id === 'main'
                  ? 'opacity-100  z-10'
                  : 'opacity-0  z-0'
              )
            "
          />
          <SystemFloor
            :class="
              twMerge(
                'absolute h-full w-full',
                route.params.floor_id !== 'main'
                  ? 'opacity-100 z-10'
                  : 'opacity-0 z-0'
              )
            "
          />
        </div>
      </template>
    </div>
  </div>
</template>

<style lang="scss" scoped></style>
