<script setup lang="ts">
import type { NdmDeviceAlarmLogResultVO } from '@/apis/models';
import { ndmDeviceAlarmLogDefaultExportByTemplate, postNdmDeviceAlarmLogPage } from '@/apis/requests';
import { JAVA_INTEGER_MAX_VALUE } from '@/constants';
import { DeviceType, DeviceTypeName, type DeviceTypeCode } from '@/enums/device-type';
import { useStationStore } from '@/stores/station';
import { downloadByData } from '@/utils/download';
import { useMutation } from '@tanstack/vue-query';
import dayjs from 'dayjs';
import type { DataTableColumns, DataTableRowData, PaginationProps, SelectOption } from 'naive-ui';
import { NForm, NInput, NButton, NSpace, NDataTable, NFormItemGi, NGrid, NSelect, NGridItem, NDatePicker } from 'naive-ui';
import { storeToRefs } from 'pinia';
import { ref, reactive, onBeforeMount, h, shallowRef, watch } from 'vue';

const stationStore = useStationStore();
const { stationList } = storeToRefs(stationStore);

const stationSelectOptions = shallowRef<SelectOption[]>([]);
watch(
  stationList,
  (list) => {
    const next = list.map<SelectOption>((station) => ({
      label: station.name,
      value: station.deviceIdPrefix,
    }));
    stationSelectOptions.value.splice(0, stationSelectOptions.value.length, ...next);
  },
  {
    immediate: true,
    deep: true,
  },
);

const searchFields = reactive({
  stationCode_in: [] as string[],
  deviceType_in: [] as string[],
  deviceName_like: '',
  // deviceId_likeRight: '',
  alarmDate: [dayjs().startOf('date').subtract(7, 'day').valueOf(), dayjs().endOf('date').valueOf()] as [number, number],
});
const resetSearchFields = () => {
  searchFields.stationCode_in = [];
  searchFields.deviceType_in = [];
  searchFields.deviceName_like = '';
  searchFields.alarmDate = [dayjs().startOf('date').subtract(7, 'day').valueOf(), dayjs().endOf('date').valueOf()];
};

const tableColumns: DataTableColumns<NdmDeviceAlarmLogResultVO> = [
  { title: '告警流水号', key: 'alarmNo' },
  {
    title: '告警时间',
    key: 'alarmDate',
    render: (rowData /* , rowIndex */) => {
      return dayjs(Number(rowData.alarmDate ?? 0)).format('YYYY-MM-DD HH:mm:ss');
    },
  },
  {
    title: '设备类型',
    key: 'deviceType',
    render: (rowData) => {
      return DeviceTypeName[(rowData.deviceType ?? DeviceType.Camera) as DeviceTypeCode];
    },
  },
  { title: '设备名称', key: 'deviceName' },
  { title: '告警类型', key: 'alarmType', align: 'center' },
  { title: '故障级别', key: 'faultLevel', align: 'center' },
  { title: '故障编码', key: 'faultCode', align: 'center' },
  { title: '故障位置', key: 'faultLocation' },
  { title: '故障描述', key: 'faultDescription' },
  { title: '修复建议', key: 'alarmRepairSuggestion' },
  {
    title: '是否恢复',
    key: 'alarmCategory',
    align: 'center',
    render: (rowData) => {
      return rowData.alarmCategory === '2' ? '是' : '否';
    },
  },
  { title: '恢复时间', key: 'updatedTime' },
  {
    title: '告警确认',
    key: 'alarmConfirm',
    align: 'center',
    render: (rowData) => {
      return rowData.alarmConfirm === '1' ? '已确认' : '未确认';
    },
  },
  // { title: '设备ID', key: 'deviceId' },
];

const tableData = ref<DataTableRowData[]>([]);

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

const { mutate: getAlarmList, isPending: isTableLoading } = useMutation({
  mutationFn: async () => {
    const res = await postNdmDeviceAlarmLogPage('', {
      model: {},
      extra: {
        stationCode_in: [...searchFields.stationCode_in],
        deviceName_like: searchFields.deviceName_like,
        deviceType_in: searchFields.deviceType_in,
        alarmDate_ge: searchFields.alarmDate[0],
        alarmDate_le: searchFields.alarmDate[1],
      },
      size: tablePagination.pageSize!,
      current: tablePagination.page!,
      sort: 'id',
      order: 'descending',
    });
    const { records, pages, size, total } = res;
    tablePagination.pageSize = parseInt(size);
    tablePagination.pageCount = parseInt(pages);
    tablePagination.itemCount = parseInt(total);
    return records;
  },
  onSuccess: (records) => {
    tableData.value = records;
  },
  onError: (error) => {
    window.$message.error(error.message);
  },
});

const onClickReset = () => {
  resetSearchFields();
  tablePagination.page = 1;
  tablePagination.pageSize = 10;
  tablePagination.pageCount = 1;
  tablePagination.itemCount = 0;
  getAlarmList();
};
const onClickQuery = () => getAlarmList();

const { mutate: downloadTableData, isPending: isDownloading } = useMutation({
  mutationFn: async () => {
    const data = await ndmDeviceAlarmLogDefaultExportByTemplate('', {
      model: {},
      extra: {
        stationCode_in: [...searchFields.stationCode_in],
        deviceName_like: searchFields.deviceName_like,
        deviceType_in: searchFields.deviceType_in,
        alarmDate_ge: searchFields.alarmDate[0],
        alarmDate_le: searchFields.alarmDate[1],
      },
      current: 1,
      size: JAVA_INTEGER_MAX_VALUE,
      sort: 'id',
      order: 'descending',
    });
    return data;
  },
  onSuccess: (data) => {
    downloadByData(data, `设备告警记录.xlsx`);
  },
  onError: (error) => {
    window.$message.error(error.message);
  },
});

const exportTableData = () => downloadTableData();

onBeforeMount(() => getAlarmList());
</script>

<template>
  <!-- 容器：上下布局，表格自适应剩余高度 -->
  <div style="height: 100%; display: flex; flex-direction: column">
    <!-- 查询面板 -->
    <div style="flex: 0 0 auto; padding: 8px">
      <NForm>
        <NGrid :cols="3" :x-gap="24">
          <NFormItemGi :span="1" label="车站" label-placement="left">
            <NSelect v-model:value="searchFields.stationCode_in" :options="stationSelectOptions" multiple clearable />
          </NFormItemGi>
          <NFormItemGi :span="1" label="设备类型" label-placement="left">
            <NSelect
              v-model:value="searchFields.deviceType_in"
              :options="[
                ...Object.values(DeviceType).map<SelectOption>((deviceType) => {
                  return {
                    label: DeviceTypeName[deviceType],
                    value: deviceType,
                  };
                }),
              ]"
              placeholder="请选择设备类型"
              multiple
              clearable
            />
          </NFormItemGi>
          <NFormItemGi :span="1" label="设备名称" label-placement="left">
            <NInput v-model:value="searchFields.deviceName_like" placeholder="请输入设备名称" clearable />
          </NFormItemGi>
          <NFormItemGi :span="1" label="告警发生时间" label-placement="left">
            <NDatePicker v-model:value="searchFields.alarmDate" type="datetimerange" />
          </NFormItemGi>
        </NGrid>
        <!-- 按钮 -->
        <NGrid :cols="1">
          <NGridItem>
            <NSpace>
              <NButton @click="onClickReset">重置</NButton>
              <NButton type="primary" :loading="isTableLoading" @click="onClickQuery">查询</NButton>
            </NSpace>
          </NGridItem>
        </NGrid>
      </NForm>
    </div>

    <!-- 工具栏：横向、右对齐按钮） -->
    <div style="flex: 0 0 auto; display: flex; align-items: center; padding: 8px">
      <div style="font-size: medium">设备告警列表</div>
      <NSpace style="margin-left: auto">
        <NButton type="primary" :loading="isDownloading" @click="exportTableData">导出</NButton>
      </NSpace>
    </div>

    <!-- 表格区域：填满剩余空间 -->
    <div style="flex: 1 1 auto; min-height: 0; padding: 8px">
      <NDataTable remote :columns="tableColumns" :data="tableData" :pagination="tablePagination" :loading="isTableLoading" :single-line="false" flex-height style="height: 100%" />
    </div>
  </div>
</template>

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