<script setup lang="ts">
import { computed, onUnmounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router';
import { useFullscreen } from '@vueuse/core';

import BitSwitchConfirm from '@/components/BitSwitchConfirm.vue';
import InputSave from '@/components/InputSave.vue';
import SvgIcon from '@/components/SvgIcon.vue';
import { useRequest } from '@/hooks/request';
import { useViewVisible } from '@/hooks/view-visible';
import { getDevStartStopStatus, getGroupModuleDevData, updateGroupModuleDevData } from '@/api';
import { isNotEmptyVal } from '@/utils';
import {
  DevParamBypassValve,
  DevParamChilledValve,
  DevParamChillerUnit,
  DevParamCommon,
  DevParamCoolingTower,
  DevParamCoolingValve,
  DevParamInletValve,
  DevParamOutletValve,
} from '@/constants/device-params';

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

import type { DevStartStopStatus, EquipmentDetailsItem, GroupModuleDevData, GroupModuleDevParam } from '@/types';

interface Props {
  info?: EquipmentDetailsItem;
  valveType?: number | string;
}

const props = defineProps<Props>();

defineEmits<{
  openDevBatchExe: [];
}>();

const { visible, showView, hideView } = useViewVisible();
const { isLoading, handleRequest } = useRequest();
const deviceData = ref<GroupModuleDevData>();
const devStartStopStatus = ref<DevStartStopStatus>();
let deviceRTDTimer: number | undefined;

const monitorParams = computed<GroupModuleDevParam[]>(() => {
  if (!deviceData.value?.dataListRO.length) {
    return [];
  }

  return sortDeviceParam(deviceData.value.dataListRO);
});

const controlParams = computed<GroupModuleDevParam[]>(() => {
  if (!deviceData.value?.dataListRW.length) {
    return [];
  }

  return sortDeviceParam(deviceData.value.dataListRW);
});

const deviceType = computed(() => {
  return props.info?.deviceQueryVo.deviceType;
});

watch(visible, () => {
  if (visible.value) {
    getDeviceData();
  } else {
    deviceData.value = undefined;
    devStartStopStatus.value = undefined;
    clearTimeout(deviceRTDTimer);
  }
});

onUnmounted(() => {
  deviceData.value = undefined;
  devStartStopStatus.value = undefined;
  clearTimeout(deviceRTDTimer);
});

const getDeviceData = () => {
  clearTimeout(deviceRTDTimer);

  handleRequest(async () => {
    if (!props.info?.deviceQueryVo) {
      return;
    }

    const { id, deviceType } = props.info.deviceQueryVo;

    if (props.valveType) {
      deviceData.value = await getGroupModuleDevData(id, DeviceType.阀门, props.valveType as number);
      devStartStopStatus.value = await getDevStartStopStatus(id, DeviceType.阀门, props.valveType as number);
    } else {
      deviceData.value = await getGroupModuleDevData(id, deviceType);
      devStartStopStatus.value = await getDevStartStopStatus(id, deviceType);
    }
  });

  deviceRTDTimer = window.setTimeout(getDeviceData, 10000);
};

const updateDeviceData = (paramCode: string, value?: string | number | null) => {
  handleRequest(async () => {
    if (!props.info?.deviceQueryVo) {
      return;
    }

    const { id } = props.info.deviceQueryVo;

    if (isNotEmptyVal(value)) {
      await updateGroupModuleDevData(id, paramCode, value);
    }
  });
};

const getDeviceParamName = (param: GroupModuleDevParam, showUnit: boolean = false) => {
  const { dataName } = param;
  const unit = showUnit && param.unit ? `（${param.unit}）` : '';

  if (dataName.includes('开到位信号')) {
    return '开到位信号';
  }

  if (dataName.includes('关到位信号')) {
    return '关到位信号';
  }

  if (dataName.includes('本地远程状态')) {
    return '本地/远程';
  }

  if (dataName.includes('开关指令')) {
    return '开关控制';
  }

  if (dataName.includes('开度反馈')) {
    return '开度反馈';
  }

  if (dataName.includes('开度最终设定')) {
    return '开度最终设定';
  }

  if (dataName.includes('压差设定')) {
    return '压差设定' + unit;
  }

  if (dataName.includes('开度上限设定')) {
    return '开度上限设定' + unit;
  }

  if (dataName.includes('开度下限设定')) {
    return '开度下限设定' + unit;
  }

  if (dataName.includes('开度手动设定')) {
    return '开度设定' + unit;
  }

  if (dataName.includes('开度控制模式')) {
    return '开度控制模式';
  }

  if (dataName.endsWith('冷冻水出水温度')) {
    return '冷冻水出水温度';
  }

  if (dataName.includes('运行时间')) {
    return '累计运行时间';
  }

  if (dataName.includes('禁启用状态')) {
    return '启用/禁用';
  }

  if (dataName.includes('手自动状态')) {
    return '自动/手动';
  }

  if (dataName.includes('手动启停')) {
    return '启停控制';
  }

  return dataName + unit;
};

const getDeviceParamUnit = (param: GroupModuleDevParam) => {
  const { unit } = param;

  if (unit?.includes('本地/远程')) {
    return '';
  }

  return unit;
};

const sortDeviceParam = (paramList: GroupModuleDevParam[]) => {
  const paramOrder = getParamOrder();

  return paramList.sort((a, b) => {
    const indexA = paramOrder.indexOf(a.dataCode);
    const indexB = paramOrder.indexOf(b.dataCode);

    // 如果不在指定顺序中，将其放在末尾
    if (indexA === -1) return 1;
    if (indexB === -1) return -1;

    return indexA - indexB;
  });
};

const getParamOrder = (): string[] => {
  if (props.valveType) {
    switch (props.valveType) {
      case ValveType.冷冻侧阀:
        return [
          DevParamChilledValve.冷冻侧阀开到位信号,
          DevParamChilledValve.冷冻侧阀关到位信号,
          DevParamChilledValve.冷冻侧阀本地远程状态,
          DevParamChilledValve.冷冻侧阀手自动状态,
          DevParamChilledValve.冷冻侧阀开关指令,
        ];
      case ValveType.冷却侧阀:
        return [
          DevParamCoolingValve.冷却侧阀开到位信号,
          DevParamCoolingValve.冷却侧阀关到位信号,
          DevParamCoolingValve.冷却侧阀本地远程状态,
          DevParamCoolingValve.冷却侧阀手自动状态,
          DevParamCoolingValve.冷却侧阀开关指令,
        ];
      case ValveType.进口阀:
        return [
          DevParamInletValve.进口阀开到位信号,
          DevParamInletValve.进口阀关到位信号,
          DevParamInletValve.进口阀本地远程状态,
          DevParamInletValve.进口阀手自动状态,
          DevParamInletValve.进口阀开关指令,
        ];
      case ValveType.出口阀:
        return [
          DevParamOutletValve.出口阀开到位信号,
          DevParamOutletValve.出口阀关到位信号,
          DevParamOutletValve.出口阀本地远程状态,
          DevParamOutletValve.出口阀手自动状态,
          DevParamOutletValve.出口阀开关指令,
        ];
      case ValveType.旁通阀:
        return [
          DevParamBypassValve.旁通阀开度反馈,
          DevParamBypassValve.旁通阀开度控制模式,
          DevParamBypassValve.旁通阀开度手动设定,
          DevParamBypassValve.旁通阀压差设定,
          DevParamBypassValve.旁通阀开度上限设定,
          DevParamBypassValve.旁通阀开度下限设定,
        ];
      default:
        return [];
    }
  }

  switch (props.info?.deviceQueryVo.deviceType) {
    case DeviceType.冷水主机:
      return [
        DevParamChillerUnit.本地远程状态,
        DevParamChillerUnit.冷冻水出水温度,
        DevParamChillerUnit.有功功率,
        DevParamChillerUnit.负载率,
        DevParamChillerUnit.运行时间,
        DevParamCommon.禁启用状态,
        DevParamCommon.手自动状态,
        DevParamCommon.手动启停,
        DevParamChillerUnit.冷冻水出水温度设定值,
        DevParamChillerUnit.负载率限制设定值,
      ];
    case DeviceType.冷却塔:
    case DeviceType.冷却泵:
    case DeviceType.冷冻泵:
      return [
        DevParamCoolingTower.本地远程状态,
        DevParamCoolingTower.有功功率,
        DevParamCoolingTower.频率反馈,
        DevParamCoolingTower.运行时间,
        DevParamCommon.禁启用状态,
        DevParamCommon.手自动状态,
        DevParamCommon.手动启停,
        DevParamCommon.频率控制模式,
      ];
    default:
      return [];
  }
};

const isParamSwitch = (param: GroupModuleDevParam) => {
  return param.bitAddress0Detail && param.bitAddress0Status && param.bitAddress1Detail && param.bitAddress1Status;
};

const router = useRouter();
const { exit } = useFullscreen();

const goDevWorkStatus = () => {
  if (!props.info?.deviceQueryVo) {
    return;
  }

  const { id, groupId, deviceType } = props.info.deviceQueryVo;
  exit();

  router.push({
    path: `/ai-smart-ctrl/device-group/${groupId}`,
    query: {
      tab: 'deviceWorkStatus',
      deviceId: id,
      deviceType,
      r: Date.now(),
    },
  });
};

defineExpose({
  showView,
  hideView,
});
</script>

<template>
  <AModal
    v-model:open="visible"
    wrap-class-name="hvac-modal"
    :closable="false"
    :centered="true"
    :width="460"
    :footer="null"
  >
    <template #title>
      <div class="dev-ctrl-modal-header">
        <span>{{ deviceData?.deviceName }}</span>
        <span v-show="deviceData" class="dev-ctrl-modal-operate" @click="goDevWorkStatus">
          {{ $t('common.viewMore') }}
          <SvgIcon name="right" />
        </span>
      </div>
    </template>
    <AEmpty v-show="!monitorParams.length && !controlParams.length" />
    <div class="dev-ctrl-modal-item" v-for="item in monitorParams" :key="item.dataCode">
      <span>{{ getDeviceParamName(item) }}</span>
      <span>{{ item.value || '-' }}{{ getDeviceParamUnit(item) }}</span>
    </div>
    <div v-show="monitorParams.length && controlParams.length" class="dev-ctrl-modal-separator"></div>
    <!-- <div class="dev-ctrl-modal-item">
      <span></span>
      <span class="dev-ctrl-modal-operate" @click="$emit('openDevBatchExe')">
        {{ $t('common.batchExecution') }}
        <SvgIcon name="right" />
      </span>
    </div> -->
    <div class="dev-ctrl-modal-item" v-for="item in controlParams" :key="item.dataCode">
      <span>{{ getDeviceParamName(item, true) }}</span>
      <BitSwitchConfirm
        v-if="isParamSwitch(item)"
        :info="item"
        :device-type="deviceType"
        :start-stop-status="devStartStopStatus"
        @ok="updateDeviceData(item.dataCode, $event)"
      />
      <InputSave v-else :info="item" width="120px" @ok="updateDeviceData(item.dataCode, $event)" />
    </div>
    <ASpin v-if="isLoading" class="center-loading" :spinning="true" />
  </AModal>
</template>

<style lang="scss" scoped>
.dev-ctrl-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.dev-ctrl-modal-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  line-height: 24px;

  > span {
    &:first-child {
      color: var(--antd-color-text-secondary);
    }

    &:last-child {
      color: var(--antd-color-text);
    }
  }

  > span.dev-ctrl-modal-operate {
    color: var(--antd-color-primary);
  }

  & + & {
    margin-top: 16px;
  }
}

.dev-ctrl-modal-separator {
  margin-block: 16px;
  border: 1px solid #e4e7ed;
}

.dev-ctrl-modal-operate {
  display: flex;
  align-items: center;
  font-size: 14px;
  font-weight: 500;
  color: var(--antd-color-primary);
  cursor: pointer;

  i {
    margin-left: 8px;
    font-size: 12px;
  }
}
</style>
