<script setup lang="ts">
import { onMounted, ref, useTemplateRef } from 'vue';
import { useFullscreen } from '@vueuse/core';
import { message } from 'ant-design-vue';

import Visual2DEditor from '@/components/visual-2d/Visual2DEditor.vue';
import Visual2DPreview from '@/components/visual-2d/Visual2DPreview.vue';
import { useRefreshView } from '@/hooks/refresh-view';
import { useRequest } from '@/hooks/request';
import { t } from '@/i18n';
import { equipmentDetails, getGroupModuleInfo, getPageList, noPaginationDevicesList } from '@/api';
import { VisualModuleType } from '@/constants';

import { DeviceType, ValveType } from '../device-work-status/device-card';

import DeviceControl from './device-control/DeviceControl.vue';
import DeviceBatchExe from './DeviceBatchExe.vue';
import DeviceCtrlModal from './DeviceCtrlModal.vue';

import type {
  AllDevicesList,
  DevGroupTabCompProps,
  DeviceGroupItem,
  DeviceGroupTree,
  DeviceGroupTreeChild,
  EquipmentDetailsItem,
  GroupModuleInfo,
} from '@/types';

const props = defineProps<DevGroupTabCompProps>();

const deviceControlRef = useTemplateRef('deviceControl');
const deviceCtrlModalRef = useTemplateRef('deviceCtrlModal');
const deviceBatchExeRef = useTemplateRef('deviceBatchExe');
const visual2DEditorRef = useTemplateRef('visual2DEditor');
const visual2DPreviewRef = useTemplateRef('visual2DPreview');

const { isLoading, handleRequest } = useRequest();
const { renderView, refreshView } = useRefreshView();
const moduleInfo = ref<GroupModuleInfo>();
const deviceList = ref<DeviceGroupTree[]>([]);
const deviceInfo = ref<EquipmentDetailsItem>();
const deviceValveType = ref<number | string>();

onMounted(() => {
  refreshView();

  handleRequest(async () => {
    const groups = await getPageList();
    const devices = await noPaginationDevicesList();
    deviceList.value = transformGroupsAndDevices(groups, devices);

    moduleInfo.value = await getGroupModuleInfo({
      groupId: props.deviceGroupId,
      moduleType: VisualModuleType.Module2D,
    });
  });
});

const transformGroupsAndDevices = (groups: DeviceGroupItem[], devices: AllDevicesList[]): DeviceGroupTree[] => {
  // 创建一个映射表，用于快速查找每个组ID对应的设备
  const deviceMap = new Map<number, AllDevicesList[]>();

  devices.forEach((device) => {
    if (!deviceMap.has(device.groupId)) {
      deviceMap.set(device.groupId, []);
    }

    deviceMap.get(device.groupId)!.push(device);
  });

  // 转换顶级分组
  return groups
    .map((group) => {
      // 转换当前组
      const transformed: DeviceGroupTree = {
        ...group,
        label: group.groupName,
        children: [],
      };

      // 转换子分组（二级分组），并过滤掉没有设备的分组
      if (group.deviceGroupChilds && group.deviceGroupChilds.length > 0) {
        transformed.children = group.deviceGroupChilds
          .map((child) => {
            const transformedChild: DeviceGroupTreeChild = {
              ...child,
              label: child.groupName,
              children: [],
            };

            // 查找并添加属于这个二级分组的设备
            const childDevices = deviceMap.get(child.id) || [];

            transformedChild.children = childDevices.map((device) => ({
              ...device,
              label: device.deviceName,
            }));

            return transformedChild;
          })
          .filter((child) => child.children.length > 0); // 过滤掉没有设备的二级分组
      }

      return transformed;
    })
    .filter((parent) => parent.children.length > 0); // 过滤掉没有二级分组的一级分组
};

const checkModuleInfo = () => {
  if (!moduleInfo.value?.leId) {
    message.error(t('realTimeMonitor.templateDataNotFound'));
  }
};

const openEditor = () => {
  checkModuleInfo();
  visual2DEditorRef.value?.showView();
};

const ctrlDeviceTypes = [DeviceType.冷水主机, DeviceType.冷却塔, DeviceType.冷却泵, DeviceType.冷冻泵];

const openDevCtrlModal = (id: number, valveType: number) => {
  if (!id) {
    // message.error(t('realTimeMonitor.unboundDevice'));
    return;
  }

  handleRequest(async () => {
    const data = await equipmentDetails(id);
    const { deviceQueryVo } = data;
    const isBypassValve = valveType === ValveType.旁通阀 && deviceQueryVo?.deviceType === DeviceType.控制柜;

    if (deviceQueryVo && (ctrlDeviceTypes.includes(deviceQueryVo.deviceType) || isBypassValve)) {
      deviceInfo.value = data;
      deviceValveType.value = valveType;
      deviceCtrlModalRef.value?.showView();
    }
  });
};

const exportImg = () => {
  checkModuleInfo();
  visual2DPreviewRef.value?.exportImg();
};

const { isFullscreen, enter } = useFullscreen();

const maximizeView = () => {
  enter();
};

defineExpose({
  openEditor,
  exportImg,
  maximizeView,
});
</script>

<template>
  <div :class="['real-time-monitor-container', { 'real-time-fullscreen': isFullscreen }]">
    <div v-show="!isFullscreen" class="real-time-monitor-operate">
      <AButton class="icon-button" @click="openEditor">
        <SvgIcon name="edit-o" />
        {{ $t('common.editor') }}
      </AButton>
      <AButton class="icon-button" @click="exportImg">
        <SvgIcon name="export" />
        {{ $t('common.exportImg') }}
      </AButton>
      <AButton class="icon-button" @click="maximizeView">
        <SvgIcon name="maximize" />
        {{ $t('common.maximize') }}
      </AButton>
    </div>
    <template v-if="moduleInfo?.leId">
      <Visual2DPreview
        v-if="renderView"
        ref="visual2DPreview"
        :info="moduleInfo"
        :device-list="deviceList"
        @click="deviceControlRef?.closeCtrlPanel"
        @open-dev-ctrl-modal="openDevCtrlModal"
      />
      <Visual2DEditor ref="visual2DEditor" :info="moduleInfo" :device-list="deviceList" @close="refreshView" />
      <DeviceControl ref="deviceControl" :info="moduleInfo" />
    </template>
    <DeviceCtrlModal
      ref="deviceCtrlModal"
      :info="deviceInfo"
      :valve-type="deviceValveType"
      @open-dev-batch-exe="deviceBatchExeRef?.showView"
    />
    <DeviceBatchExe ref="deviceBatchExe" :group-id="props.deviceGroupId" />
    <ASpin v-if="isLoading" class="center-loading" :spinning="true" />
  </div>
</template>

<style lang="scss" scoped>
.real-time-monitor-container {
  height: 100%;
  background: #1e2530;
  border-radius: 12px;
}

.real-time-fullscreen {
  position: fixed;
  inset: 0;
  border-radius: 0;
}

.real-time-monitor-operate {
  position: absolute;
  top: -48px;
  right: 0;

  button {
    color: var(--antd-color-primary);
    border-color: var(--antd-color-primary);

    + button {
      margin-left: 16px;
    }
  }
}
</style>
