<script setup lang="ts">
import type { NdmNvrResultVO, NdmRecordCheck, RecordItem, Station } from '@/apis';
import { getChannelListApi, getRecordCheckApi as getRecordCheckByParentIdApi, reloadAllRecordCheckApi as reloadAllRecordCheckApi, reloadRecordCheckApi as reloadRecordCheckByGbIdApi } from '@/apis';
import { exportRecordDiagCsv, transformRecordChecks } from '@/helper';
import { useStationStore } from '@/stores';
import { useMutation } from '@tanstack/vue-query';
import { DownloadOutlined } from '@vicons/antd';
import { RefreshOutline } from '@vicons/ionicons5';
import dayjs from 'dayjs';
import { NButton, NCard, NFlex, NIcon, NPagination, NPopconfirm, NPopover, NRadioButton, NRadioGroup, NTooltip, useThemeVars } from 'naive-ui';
import { computed, onMounted, ref, toRefs } from 'vue';

const props = defineProps<{
  stationCode: Station['code'];
  ndmNvr: NdmNvrResultVO;
}>();

const { stationCode, ndmNvr } = toRefs(props);

const recordChecks = ref<NdmRecordCheck[]>([]);

const lossInput = ref<number>(0);

const recordDiags = computed(() => {
  return transformRecordChecks(recordChecks.value).filter((recordDiag) => {
    if (lossInput.value === 0) {
      return true;
    } else if (lossInput.value === 1) {
      return recordDiag.lostChunks.length > 0;
    } else if (lossInput.value === 2) {
      return recordDiag.lostChunks.length === 0;
    }
    return false;
  });
});

const { mutate: getRecordCheckByParentId, isPending: loading } = useMutation({
  mutationFn: async () => {
    const checks = await getRecordCheckByParentIdApi(ndmNvr.value, 90, [], { stationCode: stationCode.value });
    return checks;
  },
  onSuccess: (checks) => {
    recordChecks.value = checks;
  },
  onError: (error) => {
    console.error(error);
    window.$message.error(error.message);
  },
});

const { mutate: reloadAllRecordCheck, isPending: reloading } = useMutation({
  mutationFn: async () => {
    await reloadAllRecordCheckApi(90, { stationCode: stationCode.value });
  },
  onSuccess: () => {
    window.$message.success('正在逐步刷新中，请稍后点击刷新按钮查看');
  },
  onError: (error) => {
    console.error(error);
    window.$message.error(error.message);
  },
});

const onExportRecordCheck = () => {
  const stationStore = useStationStore();
  const stationName = stationStore.stationList.find((station) => station.code === stationCode.value)?.name ?? '';
  exportRecordDiagCsv(recordDiags.value, stationName);
};

const page = ref(1);
const pageSize = ref(10);

const pagedRecordDiags = computed(() => {
  const startIndex = (page.value - 1) * pageSize.value;
  const endIndex = page.value * pageSize.value;
  return recordDiags.value.slice(startIndex, endIndex);
});

const getLostChunkDOMStyle = (lostChunk: RecordItem, duration: RecordItem) => {
  const chunk = dayjs(lostChunk.endTime).diff(dayjs(lostChunk.startTime));
  const offset = dayjs(lostChunk.startTime).diff(dayjs(duration.startTime));
  const total = dayjs(duration.endTime).diff(dayjs(duration.startTime));
  return {
    left: `${(offset / total) * 100}%`,
    width: `${(chunk / total) * 100}%`,
  };
};

const { mutate: reloadRecordCheckByGbId } = useMutation({
  mutationFn: async (params: { gbCode: string }) => {
    const channelList = await getChannelListApi(ndmNvr.value, { stationCode: stationCode.value });
    const channel = channelList.find((channel) => channel.code === params.gbCode);
    if (!channel) throw new Error('通道不存在');
    window.$message.loading('刷新耗时较长, 请不要多次刷新, 并耐心等待...', {
      duration: 1000 * 60 * 60 * 24 * 300,
    });
    const isSuccess = await reloadRecordCheckByGbIdApi(channel, 90, { stationCode: stationCode.value });
    window.$message.destroyAll();
    if (isSuccess) {
      window.$message.success('刷新成功');
    } else {
      window.$message.error('刷新失败');
    }
  },
  onSuccess: () => {
    getRecordCheckByParentId();
  },
  onError: (error) => {
    console.error(error);
    window.$message.error(error.message);
  },
});

onMounted(() => {
  getRecordCheckByParentId();
});

const themeVars = useThemeVars();
</script>

<template>
  <NCard size="small" hoverable>
    <template #header>
      <NFlex align="center" :size="24">
        <div>录像诊断</div>
        <NPopconfirm @positive-click="() => reloadAllRecordCheck()">
          <template #trigger>
            <NButton secondary size="small" :loading="reloading">更新所有通道录像诊断</NButton>
          </template>
          <template #default>
            <span>确认更新所有通道录像诊断吗？</span>
          </template>
        </NPopconfirm>
      </NFlex>
    </template>
    <template #header-extra>
      <NFlex>
        <NTooltip trigger="hover">
          <template #trigger>
            <NButton size="small" quaternary circle :loading="loading" @click="() => getRecordCheckByParentId()">
              <template #icon>
                <NIcon>
                  <RefreshOutline />
                </NIcon>
              </template>
            </NButton>
          </template>
          <template #default>
            <span>刷新数据</span>
          </template>
        </NTooltip>
        <NTooltip trigger="hover">
          <template #trigger>
            <NButton size="small" quaternary circle @click="onExportRecordCheck">
              <template #icon>
                <NIcon>
                  <DownloadOutlined />
                </NIcon>
              </template>
            </NButton>
          </template>
          <template #default>
            <span>导出录像诊断</span>
          </template>
        </NTooltip>
      </NFlex>
    </template>
    <template #default>
      <NFlex justify="flex-end" style="margin-bottom: 6px">
        <NRadioGroup size="small" v-model:value="lossInput">
          <NRadioButton label="全部" :value="0" />
          <NRadioButton label="有缺失" :value="1" />
          <NRadioButton label="无缺失" :value="2" />
        </NRadioGroup>
      </NFlex>
      <template v-for="{ gbCode, channelName, recordDuration, lostChunks } in pagedRecordDiags" :key="gbCode">
        <div style="display: flex; justify-content: space-between">
          <div>
            <span>{{ channelName }}</span>
            <span>{{ '\u3000' }}</span>
            <span>{{ recordDuration.startTime }} - {{ recordDuration.endTime }}</span>
          </div>
          <NPopconfirm trigger="click" @positive-click="() => reloadRecordCheckByGbId({ gbCode })">
            <template #trigger>
              <NButton ghost size="tiny" type="info">刷新</NButton>
            </template>
            <template #default>
              <span>是否确认刷新？</span>
            </template>
          </NPopconfirm>
        </div>
        <div style="position: relative; height: 24px; margin: 2px 0" :style="{ backgroundColor: lostChunks.length > 0 ? themeVars.infoColor : themeVars.successColor }">
          <template v-for="{ startTime, endTime } in lostChunks" :key="`${startTime}-${endTime}`">
            <NPopover trigger="hover">
              <template #trigger>
                <div style="position: absolute; height: 100%; cursor: pointer; background-color: #eee" :style="getLostChunkDOMStyle({ startTime, endTime }, recordDuration)" />
              </template>
              <template #default>
                <div>开始时间：{{ dayjs(startTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
                <div>结束时间：{{ dayjs(endTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
              </template>
            </NPopover>
          </template>
        </div>
      </template>
    </template>
    <template #action>
      <NFlex justify="flex-end">
        <NPagination size="small" :page="page" :page-size="pageSize" :page-count="Math.ceil(recordDiags.length / pageSize)" @update:page="(p) => (page = p)" />
      </NFlex>
    </template>
  </NCard>
</template>

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