<script setup>
import { RouterView, useRoute } from 'vue-router';
import { computed, watch, provide, ref, onMounted, onBeforeUnmount } from "vue";
import SystemFloorBar from './components/SystemFloorBar.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 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 companyOptions = ref([]);
const selected_dbid = 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_tag: buildingStore.selectedBuilding?.building_tag,
  })
  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.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 }) => points.some(({ points: p }) => p === gas))
      }
    ))
  }
  data.value = update_values
  subscribeData.value = getSubData(update_values);
}

watch(
  () => buildingStore.selectedBuilding,
  (newBuilding) => {
    if (Boolean(newBuilding)) {
      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([])
const timeId = ref(null)
const getAllDeviceRealtime = () => {
  timeId.value = setInterval(async () => {
    const res = await getSystemRealTime(subscribeData.value.map(d => d.device_number))
    console.log(res.data)
    realtimeData.value = res.data
  }, 10000)
}

watch(subscribeData, (newValue) => {
  timeId.value && clearInterval(timeId.value)
  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(() => realtimeData.value?.find(({ device_number }) => device_number === selectedDevice.value?.value?.device_number)?.data)

const clearSelectedDeviceInfo = () => {

  selectedDevice.value.value = null;
}

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

onBeforeUnmount(() => {
  clearInterval(timeId.value);
});
</script>

<template>
  <SystemInfoModal :data="selectedDevice" />
  <SystemFloorBar />
  <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">
      <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>
    </div>
  </div>

</template>

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