<script setup lang="ts">
import { getAllPushApi, type NdmServerResultVO, type Station } from '@/apis';
import { DEVICE_TYPE_LITERALS, tryGetDeviceType } from '@/enums';
import { useSettingStore } from '@/stores';
import { useQuery, useQueryClient } from '@tanstack/vue-query';
import { NCard, NCollapse, NCollapseItem, NFlex, NTag, NText } from 'naive-ui';
import { storeToRefs } from 'pinia';
import { computed, toRefs, watch } from 'vue';

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

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

const queryClient = useQueryClient();

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

const deviceType = computed(() => tryGetDeviceType(ndmDevice.value.deviceType));

const showCard = computed(() => deviceType.value === DEVICE_TYPE_LITERALS.ndmMediaServer);

const SERVER_STREAM_PUSH_KEY = 'server-stream-push-query';

const deviceUniqueKey = computed(() => [station.value.code, ndmDevice.value.id]);

const { data: streamPushes } = useQuery({
  queryKey: computed(() => [SERVER_STREAM_PUSH_KEY, deviceUniqueKey.value, ndmDevice.value.lastDiagTime]),
  enabled: computed(() => activeRequests.value && showCard.value),
  refetchInterval: 30 * 1000,
  gcTime: 0,
  queryFn: async ({ signal }) => {
    const streamPushes = await getAllPushApi({ stationCode: station.value.code, signal });
    return streamPushes;
  },
});
watch(activeRequests, (active) => {
  if (!active) {
    queryClient.cancelQueries({ queryKey: [SERVER_STREAM_PUSH_KEY] });
  }
});

interface StreamPushStat {
  ip: string;
  port: number | null;
  ssrc: string | null;
  channelIds: string[];
}
const streamPushStat = computed(() => {
  const stat: StreamPushStat[] = [];
  streamPushes.value?.forEach((push) => {
    if (!push.ip || !push.channelId) return;
    const existIndex = stat.findIndex((item) => item.ip === push.ip);
    if (existIndex === -1) {
      stat.push({ ip: push.ip, port: push.port, ssrc: push.ssrc, channelIds: [push.channelId] });
    } else {
      const statItem = stat[existIndex];
      if (!statItem) return;
      statItem.channelIds.push(push.channelId);
    }
  });
  return stat;
});
</script>

<template>
  <NCard v-if="showCard" hoverable size="small">
    <template #header>
      <span>推流统计</span>
    </template>
    <template #default>
      <template v-if="!activeRequests">
        <span>-</span>
      </template>
      <template v-else>
        <NFlex vertical>
          <NText depth="3">共 {{ streamPushStat.length }} 个推流目标</NText>
          <NCollapse v-if="streamPushStat.length > 0">
            <NCollapseItem v-for="{ ip, port, ssrc, channelIds } in streamPushStat" :key="`${ip}:${port}:${ssrc}`" :name="`${ip}:${port}:${ssrc}`">
              <template #header>
                <span>{{ ip }}</span>
              </template>
              <template #header-extra>
                <span>{{ channelIds.length }} 路</span>
              </template>
              <template #default>
                <NFlex>
                  <NTag v-for="channelId in channelIds" :key="channelId" size="small" type="info" :bordered="false">{{ channelId }}</NTag>
                </NFlex>
              </template>
            </NCollapseItem>
          </NCollapse>
        </NFlex>
      </template>
    </template>
  </NCard>
</template>

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