<script setup lang="ts">
import { LineChart } from 'echarts/charts'
import { GridComponent, LegendComponent, TooltipComponent } from 'echarts/components'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { NSelect, NSpin } from 'naive-ui'
import { computed, ref, watch } from 'vue'
import VChart from 'vue-echarts'

import { getInstanceTraffic } from '@/api/analytics'
import EmptyCard from '@/components/EmptyCard.vue'
import FootNote from '@/components/FootNote.vue'
import { fmtBytes } from '@/composables/useFormat'
import { useAsync } from '@/composables/useAsync'
import { useAppStore } from '@/stores/app'
import { darkTokens, tokens } from '@/theme/tokens'

use([LineChart, GridComponent, TooltipComponent, LegendComponent, CanvasRenderer])

/** echarts 不认 CSS 变量，色板按明暗主题从 tokens 取 */
const app = useAppStore()
const t = computed(() => (app.dark ? darkTokens : tokens))

const props = defineProps<{ cfgId: number; instanceId: string; region?: string }>()

const days = ref(7)

const traffic = useAsync(() =>
  getInstanceTraffic(props.cfgId, props.instanceId, days.value, props.region),
)

watch(days, () => void traffic.run())

const daysOptions = [
  { label: '近 7 天', value: 7 },
  { label: '近 30 天', value: 30 },
]

const series = computed(() => {
  const vnic = traffic.data.value?.vnics[0]
  if (!vnic) return null
  const labels = vnic.outbound.map((p) => p.timestamp.slice(5, 10))
  return {
    labels,
    outbound: vnic.outbound.map((p) => +(p.bytes / 1024 ** 3).toFixed(2)),
    inbound: vnic.inbound.map((p) => +(p.bytes / 1024 ** 3).toFixed(2)),
  }
})

const option = computed(() => ({
  grid: { left: 44, right: 16, top: 36, bottom: 26 },
  legend: { top: 4, left: 8, textStyle: { color: t.value.ink2, fontSize: 12 }, itemWidth: 14 },
  tooltip: {
    trigger: 'axis',
    backgroundColor: t.value.ink,
    borderWidth: 0,
    textStyle: { color: t.value.bg, fontSize: 12 },
    valueFormatter: (v: number) => `${v} GB`,
  },
  xAxis: {
    type: 'category',
    data: series.value?.labels ?? [],
    boundaryGap: false,
    axisLine: { lineStyle: { color: t.value.line } },
    axisTick: { show: false },
    axisLabel: { color: t.value.ink3, fontSize: 10.5 },
  },
  yAxis: {
    type: 'value',
    splitLine: { lineStyle: { color: t.value.lineSoft } },
    axisLabel: { color: t.value.ink3, fontSize: 10.5, formatter: '{value}G' },
  },
  series: [
    {
      name: '流出',
      type: 'line',
      data: series.value?.outbound ?? [],
      lineStyle: { color: t.value.chart, width: 2 },
      itemStyle: { color: t.value.chart },
      symbol: 'circle',
      symbolSize: 5,
    },
    {
      name: '流入',
      type: 'line',
      data: series.value?.inbound ?? [],
      lineStyle: { color: t.value.info, width: 2 },
      itemStyle: { color: t.value.info },
      symbol: 'circle',
      symbolSize: 5,
    },
  ],
}))
</script>

<template>
  <div class="panel">
    <div class="flex flex-wrap items-center gap-2.5 border-b border-line-soft px-4.5 py-3.5">
      <div class="text-sm font-semibold">流量</div>
      <div class="flex-1" />
      <div class="w-28">
        <NSelect
          v-model:value="days"
          size="small"
          :options="daysOptions"
          :loading="traffic.loading.value"
        />
      </div>
    </div>
    <div
      v-if="traffic.loading.value && !traffic.data.value"
      class="flex items-center justify-center py-14"
    >
      <NSpin size="small" />
    </div>
    <template v-else-if="traffic.data.value">
      <div class="flex flex-wrap gap-5 px-4.5 pt-3 text-[12.5px] text-ink-2">
        <span>
          <span class="mr-1.5 inline-block h-2 w-2 rounded-full" style="background: var(--color-chart)" />
          流出 · 合计 {{ fmtBytes(traffic.data.value.outboundBytes) }}
        </span>
        <span>
          <span class="mr-1.5 inline-block h-2 w-2 rounded-full" style="background: var(--color-info)" />
          流入 · 合计 {{ fmtBytes(traffic.data.value.inboundBytes) }}
        </span>
      </div>
      <div class="px-3 pb-2">
        <VChart class="w-full" style="height: 210px" :option="option" autoresize />
      </div>
    </template>
    <EmptyCard
      v-else
      title="暂无流量数据"
      note="该实例暂无 Monitoring 数据点（新建实例有数分钟延迟，终止实例不再产生数据）"
    />
    <FootNote>
      数据来自 Monitoring 指标（VnicToNetworkBytes 发送 / VnicFromNetworkBytes 接收），按日聚合
    </FootNote>
  </div>
</template>
