<script lang="ts">
const formatDuration = (time: number) => {
  if (time < 1) {
    return '';
  }
  const d = Math.floor(time / 86400);
  const h = Math.floor((time % 86400) / 3600);
  const m = Math.floor((time % 3600) / 60);
  const s = Math.floor(time % 60);
  let result = '';
  if (d > 0) {
    result += `${d}天`;
  }
  if (h > 0) {
    result += `${h}小时`;
  }
  if (m > 0) {
    result += `${m}分钟`;
  }
  if (s > 0) {
    result += `${s}秒`;
  }
  return result;
};
</script>

<script setup lang="ts">
import type { NdmDeviceResultVO, NdmIcmpLogResultVO, NdmIcmpLogVO, PageParams, PageResult } from '@/apis/models';
import { postIcmpLogPage } from '@/apis/requests';
import { useMutation } from '@tanstack/vue-query';
import dayjs from 'dayjs';
import { NCard, NPagination, NScrollbar, NTimeline, NTimelineItem, type DatePickerProps, type PaginationProps, type TimelineItemProps } from 'naive-ui';
import { computed, h, reactive, ref, toRefs } from 'vue';

const props = defineProps<{
  stationCode: string;
  ndmDevice: NdmDeviceResultVO;
  dateTimeRange: DatePickerProps['value'];
}>();

const { stationCode, ndmDevice, dateTimeRange } = toRefs(props);

const icmpLogList = ref<NdmIcmpLogResultVO[]>([]);
const predecessorItem = ref<NdmIcmpLogResultVO>();

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

const { mutate: getDeviceIcmpLogList, isPending } = useMutation({
  mutationFn: async () => {
    if (!dateTimeRange.value) throw new Error('请选择时间范围');
    const range = dateTimeRange.value as [number, number];
    const id = ndmDevice.value.id;
    const createdTime_precisest = dayjs(range[0]).format('YYYY-MM-DD HH:mm:ss');
    const createdTime_preciseed = dayjs(range[1]).format('YYYY-MM-DD HH:mm:ss');
    const restParams: Omit<PageParams<{ id: string }>, 'model' | 'extra'> = {
      current: pagination.page ?? 1,
      size: pagination.pageSize ?? DEFAULT_PAGE_SIZE,
      sort: 'id',
      order: 'descending',
    };
    const currentPageRes = await postIcmpLogPage(stationCode.value, {
      model: { deviceId: id },
      extra: { createdTime_precisest, createdTime_preciseed },
      ...restParams,
    });
    let previousPageRes: PageResult<Partial<NdmIcmpLogVO>> | undefined = undefined;
    if ((pagination.page ?? 1) > 1) {
      previousPageRes = await postIcmpLogPage(stationCode.value, {
        model: { deviceId: id },
        extra: { createdTime_precisest, createdTime_preciseed },
        ...restParams,
        current: (pagination.page ?? 1) - 1,
      });
    }
    return { currentPageRes, previousPageRes };
  },
  onSuccess: ({ currentPageRes: { records, size, total }, previousPageRes }) => {
    pagination.pageSize = parseInt(size);
    pagination.itemCount = parseInt(total);
    icmpLogList.value = records;
    predecessorItem.value = previousPageRes?.records.at(-1);
  },
  onError: (error) => {
    console.error(`查询${ndmDevice.value.name}诊断数据失败:`, error);
    window.$message.error(error.message);
  },
});

const timelineItems = computed<TimelineItemProps[]>(() => {
  const items: TimelineItemProps[] = [];
  let prevIcmpLog = predecessorItem.value;
  for (const icmpLog of icmpLogList.value) {
    const { deviceStatus, createdTime } = icmpLog;
    const type: TimelineItemProps['type'] = deviceStatus === '10' ? 'success' : deviceStatus === '20' ? 'error' : 'warning';
    const title = deviceStatus === '10' ? '在线' : deviceStatus === '20' ? '离线' : '未知';
    const duration = prevIcmpLog ? dayjs(prevIcmpLog.createdTime).diff(dayjs(createdTime), 'second') : undefined;
    const content = `持续时长：${duration ? formatDuration(duration) : '至今'}`;
    const time = createdTime;
    items.push({
      type,
      title,
      content,
      time,
    });
    prevIcmpLog = icmpLog;
  }
  return items;
});

defineExpose({
  isPending,
  refresh: () => {
    pagination.page = 1;
    pagination.pageSize = DEFAULT_PAGE_SIZE;
    getDeviceIcmpLogList();
  },
});
</script>

<template>
  <NCard size="small" title="设备状态记录">
    <div v-if="timelineItems.length === 0" style="width: 100%; display: flex; color: #666">
      <div style="margin: auto">暂无记录</div>
    </div>
    <NScrollbar v-else x-scrollable style="height: 500px">
      <NTimeline>
        <NTimelineItem v-for="{ type, title, content, time } in timelineItems" :key="time" :type="type" :title="title" :content="content" :time="time"></NTimelineItem>
      </NTimeline>
    </NScrollbar>
    <template #footer>
      <NPagination
        v-model:page="pagination.page"
        v-model:page-size="pagination.pageSize"
        :page-sizes="pagination.pageSizes"
        :item-count="pagination.itemCount"
        size="small"
        show-size-picker
        @update-page="pagination.onUpdatePage"
        @update:page-size="pagination.onUpdatePageSize"
      />
    </template>
  </NCard>
</template>

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