<script lang="ts">
const CAMERA_TYPES = {
  '001': '模拟彩色云台摄像机',
  '002': '模拟彩色半球摄像机',
  '003': '模拟彩色固定摄像机',
  '004': '数字高清云台摄像机',
  '005': '数字高清半球摄像机',
  '006': '数字高清固定摄像机',
} as const;

type CameraType = keyof typeof CAMERA_TYPES;

const isCameraTypeCode = (code: string): code is CameraType => {
  return code in CAMERA_TYPES;
};
</script>

<script setup lang="ts">
import type { NdmCameraDiagInfo, NdmCameraResultVO, Station } from '@/apis';
import { DeviceCommonCard, DeviceHardwareCard, DeviceHeaderCard, type DeviceCommonCardProps } from '@/components';
import { useSettingStore } from '@/stores';
import { useQuery, useQueryClient } from '@tanstack/vue-query';
import axios from 'axios';
import destr from 'destr';
import { NDescriptions, NDescriptionsItem, NFlex } from 'naive-ui';
import { storeToRefs } from 'pinia';
import { computed, toRefs, watch } from 'vue';

const props = defineProps<{
  ndmDevice: NdmCameraResultVO;
  station: Station;
}>();

const settingStore = useSettingStore();
const { activeRequests } = storeToRefs(settingStore);

const queryClient = useQueryClient();

const { ndmDevice, station } = toRefs(props);

const cameraType = computed(() => {
  const gbCode = ndmDevice.value.gbCode;
  if (!gbCode) return '-';
  const cameraTypeCode = gbCode.slice(11, 14);
  if (!isCameraTypeCode(cameraTypeCode)) return '-';
  return CAMERA_TYPES[cameraTypeCode];
});

const QUERY_KEY = 'camera-installation-area-query';

const { data: installationArea } = useQuery({
  queryKey: computed(() => [QUERY_KEY, ndmDevice.value.gbCode, station.value.code]),
  enabled: computed(() => activeRequests.value),
  gcTime: 0,
  queryFn: async ({ signal }) => {
    const UNKNOWN_NAME = '-';

    const gbCode = ndmDevice.value.gbCode;
    if (!gbCode) return UNKNOWN_NAME;

    const MINIO_PREFIX = `/minio`;
    const CDN_VIMP_CODES_PREFIX = `${MINIO_PREFIX}/cdn/vimp/codes`;
    const CODE_STATIONS_JSON_PATH = `${CDN_VIMP_CODES_PREFIX}/codeStations.json`;
    const CODE_STATION_AREAS_JSON_PATH = `${CDN_VIMP_CODES_PREFIX}/codeStationAreas.json`;
    const CODE_PARKING_AREAS_JSON_PATH = `${CDN_VIMP_CODES_PREFIX}/codeParkingAreas.json`;
    const CODE_OCC_AREAS_JSON_PATH = `${CDN_VIMP_CODES_PREFIX}/codeOccAreas.json`;

    // minio中的编码表结构
    type Unit = { name: string; type: 'train' | 'station' | 'parking' | 'occ' };
    type Area = { code: string; name: string; subs: Array<{ code: string; name: string }> };

    const { data: unitCodes } = await axios.get<Record<string, Unit>>(CODE_STATIONS_JSON_PATH, { signal });

    // 根据国标编码的前6位匹配minio中的编码表
    const unitCode = gbCode.slice(0, 6);
    const unit = unitCodes[unitCode];
    if (!unit) return UNKNOWN_NAME;
    // 获取编码表中的线路/单位类型
    const unitType = unit.type;
    // 国标编码的第7位到第8位为1级区域编码
    const tier1AreaCode = gbCode.slice(6, 8);
    // 国标编码的第9位到第11位为2级区域编码
    const tier2AreaCode = gbCode.slice(8, 11);

    if (unitType === 'train') {
      return unit.name;
    }

    const areaJsonPaths: Record<string, string> = {
      station: CODE_STATION_AREAS_JSON_PATH,
      parking: CODE_PARKING_AREAS_JSON_PATH,
      occ: CODE_OCC_AREAS_JSON_PATH,
    };

    const jsonPath = areaJsonPaths[unitType];
    if (!jsonPath) return UNKNOWN_NAME;

    // 获取1级区域
    const { data: areaCodes } = await axios.get<Area[]>(jsonPath, { signal });
    const tier1Area = areaCodes.find((area) => area.code === tier1AreaCode);
    if (!tier1Area) return UNKNOWN_NAME;

    // 获取2级区域
    const tier2Area = tier1Area.subs.find((area) => area.code === `${tier1AreaCode}${tier2AreaCode}`);
    if (!tier2Area) return UNKNOWN_NAME;

    // 拼接1级和2级区域名称
    return `${tier1Area.name}-${tier2Area.name}`;
  },
});
watch(activeRequests, (active) => {
  if (!active) {
    queryClient.cancelQueries({ queryKey: [QUERY_KEY] });
  }
});

const lastDiagInfo = computed(() => {
  const result = destr<any>(ndmDevice.value.lastDiagInfo);
  if (!result) return null;
  if (typeof result !== 'object') return null;
  return result as NdmCameraDiagInfo;
});

const commonInfo = computed<DeviceCommonCardProps['commonInfo']>(() => {
  const { stCommonInfo } = lastDiagInfo.value ?? {};
  const { 设备ID, 软件版本, 设备厂商, 设备别名, 设备型号, 硬件版本 } = stCommonInfo ?? {};
  const { ethInfo, ipInfo } = lastDiagInfo.value ?? {};
  const {
    createdTime,
    updatedTime,
    manufacturer,
    gb28181Enabled,
    onvifPort,
    onvifUsername,
    onvifPassword,
    onvifMajorIndex,
    onvifMinorIndex,
    icmpEnabled,
    community,
    ipAddress,
    //
  } = ndmDevice.value;

  let operStatus = '-';
  if (!!ethInfo?.operStatus) {
    operStatus = ethInfo?.operStatus === '1' ? '正常' : '异常';
  }

  return [
    {
      title: '设备型号信息',
      items: [
        { label: '设备ID', value: 设备ID || '-' },
        { label: '软件版本', value: 软件版本 || '-' },
        { label: '设备厂商', value: 设备厂商 || manufacturer || '-' },
        { label: '设备别名', value: 设备别名 || '-' },
        { label: '设备型号', value: 设备型号 || '-' },
        { label: '硬件版本', value: 硬件版本 || '-' },
      ],
    },
    {
      title: '设备网卡信息',
      items: [
        { label: 'IP地址', value: ipAddress || '-' },
        { label: '子网掩码', value: ipInfo?.mASK || '-' },
        { label: 'MAC地址', value: ethInfo?.macAddress || '-' },
        { label: '连接速率', value: ethInfo?.speed || '-' },
        { label: 'MTU', value: ethInfo?.mTU || '-' },
        { label: '运行状态', value: operStatus },
      ],
    },
    {
      title: '设备接入信息',
      items: [
        { label: '创建时间', value: createdTime || '-' },
        { label: '更新时间', value: updatedTime || '-' },
        { label: 'GB28181启用', value: `${!!gb28181Enabled ? '是' : '否'}` },
        { label: 'ICMP启用', value: `${!!icmpEnabled ? '是' : '否'}` },
        { label: 'ONVIF用户名', value: onvifUsername || '-' },
        { label: 'ONVIF密码', value: onvifPassword || '-' },
        { label: 'ONVIF主流索引', value: `${onvifMajorIndex ?? '-'}` },
        { label: 'ONVIF辅流索引', value: `${onvifMinorIndex ?? '-'}` },
        { label: 'ONVIF端口', value: `${onvifPort ?? '-'}` },
        { label: '团体字符串', value: community || '-' },
      ],
    },
  ];
});

const cpuUsage = computed(() => lastDiagInfo.value?.stCommonInfo?.CPU使用率);
const memUsage = computed(() => lastDiagInfo.value?.stCommonInfo?.内存使用率);
</script>

<template>
  <NFlex vertical>
    <DeviceHeaderCard :ndm-device="ndmDevice" :station="station">
      <template #append-info>
        <NDescriptions bordered size="small" label-placement="left" :columns="1" style="width: 60%; min-width: 400px">
          <NDescriptionsItem label="摄像机类型" :span="1">{{ cameraType }}</NDescriptionsItem>
          <NDescriptionsItem label="建议安装区域" :span="1">{{ installationArea ?? '-' }}</NDescriptionsItem>
        </NDescriptions>
      </template>
    </DeviceHeaderCard>
    <DeviceCommonCard :common-info="commonInfo" />
    <DeviceHardwareCard :cpu-usage="cpuUsage" :mem-usage="memUsage" />
  </NFlex>
</template>

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