<script setup lang="ts">
import type { NdmDeviceAlarmLogResultVO, Station } from '@/apis';
import { ALARM_TYPES, DEVICE_TYPE_LITERALS, DEVICE_TYPE_NAMES, FAULT_LEVELS, tryGetDeviceType } from '@/enums';
import { renderAlarmDateCell, renderAlarmTypeCell, renderDeviceTypeCell, renderFaultLevelCell } from '@/helpers';
import { useAlarmStore, useDeviceStore } from '@/stores';
import { downloadByData } from '@/utils';
import dayjs from 'dayjs';
import { NButton, NDataTable, NFlex, NGrid, NGridItem, NModal, NStatistic, NTag, type DataTableBaseColumn, type DataTableRowData, type PaginationProps } from 'naive-ui';
import { storeToRefs } from 'pinia';
import { computed, h, reactive, ref, toRefs, type CSSProperties } from 'vue';
import { useRoute, useRouter } from 'vue-router';

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

const show = defineModel<boolean>('show', { default: false });

const route = useRoute();
const router = useRouter();

const { station } = toRefs(props);

const deviceStore = useDeviceStore();
const { lineDevices } = storeToRefs(deviceStore);
const alarmStore = useAlarmStore();
const { lineAlarms } = storeToRefs(alarmStore);

const classifiedAlarmCounts = computed<{ label: string; count: number }[]>(() => {
  const stationCode = station.value?.code;
  if (!stationCode) return [];
  const stationAlarms = lineAlarms.value[stationCode];
  if (!stationAlarms) return [];
  return Object.values(DEVICE_TYPE_LITERALS).map<{ label: string; count: number }>((deviceType) => {
    return {
      label: DEVICE_TYPE_NAMES[deviceType],
      count: stationAlarms[deviceType].length,
    };
  });
});

const tableColumns = ref<DataTableBaseColumn<NdmDeviceAlarmLogResultVO>[]>([
  { title: '告警流水号', key: 'alarmNo' },
  { title: '告警时间', key: 'alarmDate', render: renderAlarmDateCell },
  { title: '设备类型', key: 'deviceType', render: renderDeviceTypeCell },
  {
    title: '设备名称',
    key: 'deviceName',
    render: (rowData) => {
      return h(
        'div',
        {
          style: { textDecoration: 'underline', cursor: 'pointer' } as CSSProperties,
          onClick: () => {
            const stationCode = rowData.stationCode;
            if (!stationCode) return;
            const deviceType = tryGetDeviceType(rowData.deviceType);
            if (!deviceType) return;
            const stationDevices = lineDevices.value[stationCode];
            if (!stationDevices) return;
            const classified = stationDevices[deviceType];
            const device = classified.find((device) => !!device.deviceId && device.deviceId === rowData.deviceId);
            if (!device) return;
            const deviceDbId = device.id;
            router.push({
              path: '/device',
              query: {
                stationCode,
                deviceType,
                deviceDbId,
                fromPage: route.path,
              },
            });
          },
        },
        `${rowData.deviceName}`,
      );
    },
  },
  { title: '告警类型', key: 'alarmType', align: 'center', render: renderAlarmTypeCell },
  { title: '故障级别', key: 'faultLevel', align: 'center', render: renderFaultLevelCell },
  // { title: '故障编码', key: 'faultCode', align: 'center' },
  // { title: '故障位置', key: 'faultLocation' },
  { title: '故障描述', key: 'faultDescription' },
  { title: '修复建议', key: 'alarmRepairSuggestion' },
  { title: '是否恢复', key: 'alarmCategory', align: 'center', render: (rowData) => (rowData.alarmCategory === '2' ? '是' : '否') },
  { title: '恢复时间', key: 'updatedTime' },
  {
    title: '告警确认',
    key: 'alarmConfirm',
    align: 'center',
    render: (rowData) => (rowData.alarmConfirm === '1' ? h(NTag, { type: 'default' }, { default: () => '已确认' }) : h(NTag, { type: 'warning' }, { default: () => '未确认' })),
  },
  // { title: '设备ID', key: 'deviceId' },
]);

const DEFAULT_PAGE_SIZE = 10;
const pagination = reactive<PaginationProps>({
  size: 'small',
  showSizePicker: true,
  page: 1,
  pageSize: DEFAULT_PAGE_SIZE,
  pageSizes: [5, 10, 20, 50, 80, 100],
  prefix: ({ itemCount }) => {
    return h('div', {}, { default: () => `共${itemCount}条` });
  },
  onUpdatePage: (page: number) => {
    pagination.page = page;
  },
  onUpdatePageSize: (pageSize: number) => {
    pagination.pageSize = pageSize;
    pagination.page = 1;
  },
});

const tableData = computed<DataTableRowData[]>(() => {
  const stationCode = station.value?.code;
  if (!stationCode) return [];
  const stationAlarms = lineAlarms.value[stationCode];
  if (!stationAlarms) return [];
  return stationAlarms['unclassified'];
});

const onAfterLeave = () => {
  pagination.page = 1;
  pagination.pageSize = 10;
};

const exportAlarms = () => {
  const keys = tableColumns.value.map((column) => column.key);
  const csvHeader = `${tableColumns.value.map((column) => column.title).join(',')}\n`;
  let csvRows = '';
  for (const row of tableData.value) {
    const alarm = row as NdmDeviceAlarmLogResultVO;
    const csvRow = `${keys
      .map((key) => {
        const fieldKey = key as keyof NdmDeviceAlarmLogResultVO;
        if (fieldKey === 'alarmDate') return dayjs(Number(alarm[fieldKey])).format('YYYY-MM-DD HH:mm:ss');
        if (fieldKey === 'deviceType') {
          const deviceType = tryGetDeviceType(alarm[fieldKey]);
          if (!deviceType) return '-';
          return DEVICE_TYPE_NAMES[deviceType];
        }
        if (fieldKey === 'alarmType') return ALARM_TYPES[alarm[fieldKey] ?? ''];
        if (fieldKey === 'faultLevel') return FAULT_LEVELS[alarm[fieldKey] ?? ''];
        if (fieldKey === 'alarmCategory') return alarm[fieldKey] === '2' ? '是' : '否';
        if (fieldKey === 'alarmConfirm') return alarm[fieldKey] === '1' ? '已确认' : '未确认';
        return alarm[fieldKey];
      })
      .join(',')}\n`;
    csvRows = csvRows.concat(csvRow);
  }
  const csvContent = csvHeader.concat(csvRows);
  const time = dayjs().format('YYYY-MM-DD_HH-mm-ss');
  downloadByData(csvContent, `${station.value?.name}_设备告警记录_${time}.csv`, 'text/csv;charset=utf-8', '\ufeff');
};
</script>

<template>
  <NModal v-model:show="show" preset="card" style="width: 100vw; height: 100vh" :close-on-esc="false" :mask-closable="false" @after-leave="onAfterLeave">
    <template #header>
      <span>{{ `${station?.name} - 设备告警详情` }}</span>
    </template>
    <template #default>
      <NFlex vertical :size="12" style="height: 100%">
        <NGrid cols="9" style="flex: 0 0 auto">
          <NGridItem v-for="item in classifiedAlarmCounts" :key="item.label" span="1">
            <NStatistic :label="item.label + '告警'" :value="item.count" />
          </NGridItem>
        </NGrid>

        <NFlex align="center" style="flex: 0 0 auto">
          <div style="font-size: medium">今日设备告警列表</div>
          <NButton type="primary" style="margin-left: auto" @click="exportAlarms">导出</NButton>
        </NFlex>

        <NDataTable flex-height style="height: 100%; min-height: 0; flex: 1 1 auto" :single-line="false" :columns="tableColumns" :data="tableData" :pagination="pagination" />
      </NFlex>
    </template>
  </NModal>
</template>

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