<template>
  <div class="usage-panel">
    <div class="usage-panel__header">
      <h3>LLM 用量统计</h3>
      <a-radio-group v-model:value="selectedPeriod" size="small" @change="onPeriodChange">
        <a-radio-button value="today">今天</a-radio-button>
        <a-radio-button value="7d">7天</a-radio-button>
        <a-radio-button value="30d">30天</a-radio-button>
      </a-radio-group>
    </div>

    <div class="usage-summary">
      <div class="usage-summary__card">
        <div class="usage-summary__label">请求成功率</div>
        <div class="usage-summary__value" style="color: #10b981">
          {{ (summary.success_rate * 100).toFixed(1) }}%
        </div>
      </div>
      <div class="usage-summary__card">
        <div class="usage-summary__label">平均响应延迟</div>
        <div class="usage-summary__value" style="color: #7c3aed">
          {{ summary.avg_latency_ms.toFixed(0) }} ms
        </div>
      </div>
      <div class="usage-summary__card">
        <div class="usage-summary__label">总 Token 数</div>
        <div class="usage-summary__value" style="color: #7c3aed">
          {{ formatNumber(summary.total_tokens) }}
        </div>
      </div>
      <div class="usage-summary__card">
        <div class="usage-summary__label">总请求数</div>
        <div class="usage-summary__value" style="color: #f59e0b">
          {{ formatNumber(summary.total_requests) }}
        </div>
      </div>
    </div>

    <div v-if="usageData.length === 0 && !loading" class="usage-panel__empty">
      <a-empty description="暂无用量数据" />
    </div>
    <div v-else class="usage-panel__chart">
      <div ref="chartRef" class="echarts-container"></div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { RadioGroup as ARadioGroup, RadioButton as ARadioButton, Empty as AEmpty } from 'ant-design-vue'
import echarts from '@/utils/echarts'
import { evolutionApi } from '@/api/evolution'
import type { UsageRecord, UsageSummary } from '@/api/evolution'

const selectedPeriod = ref('7d')
const usageData = ref<UsageRecord[]>([])
const summary = ref<UsageSummary>({
  total_tokens: 0,
  total_requests: 0,
  success_rate: 0,
  avg_latency_ms: 0,
})
const loading = ref(false)

const chartRef = ref<HTMLDivElement>()
let chartInstance: echarts.ECharts | null = null
let resizeObserver: ResizeObserver | null = null

const PROVIDER_COLORS: Record<string, string> = {
  openai: '#10a37f',
  anthropic: '#d97706',
  azure: '#0078d4',
  deepseek: '#4d6bfe',
  zhipu: '#3b5cff',
  default: '#737373',
}

async function loadUsage() {
  loading.value = true
  try {
    const data = await evolutionApi.getUsage({ period: selectedPeriod.value })
    usageData.value = data.usage
    summary.value = data.summary
  } catch {
    usageData.value = []
    summary.value = { total_tokens: 0, total_requests: 0, success_rate: 0, avg_latency_ms: 0 }
  } finally {
    loading.value = false
  }
}

function onPeriodChange() {
  loadUsage()
}

function formatNumber(n: number): string {
  if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`
  if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`
  return String(n)
}

function initChart() {
  if (!chartRef.value) return
  chartInstance = echarts.init(chartRef.value)
  updateChart()
}

function updateChart() {
  if (!chartInstance || !usageData.value.length) return

  // Group by provider
  const providerMap = new Map<string, Map<string, number>>()
  const dateSet = new Set<string>()

  for (const record of usageData.value) {
    const provider = record.provider || 'default'
    if (!providerMap.has(provider)) {
      providerMap.set(provider, new Map())
    }
    providerMap.get(provider)!.set(record.date, (providerMap.get(provider)!.get(record.date) || 0) + record.tokens)
    dateSet.add(record.date)
  }

  const dates = Array.from(dateSet).sort()
  const providers = Array.from(providerMap.keys())

  const series = providers.map(provider => {
    const dataMap = providerMap.get(provider)!
    return {
      name: provider,
      type: 'line' as const,
      smooth: true,
      data: dates.map(d => dataMap.get(d) || 0),
      itemStyle: { color: PROVIDER_COLORS[provider] || PROVIDER_COLORS.default },
      symbol: 'circle',
      symbolSize: 6,
    }
  })

  chartInstance.setOption({
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'cross' },
    },
    legend: {
      data: providers,
      bottom: 0,
    },
    grid: {
      left: '3%',
      right: '4%',
      top: '8%',
      bottom: '15%',
      containLabel: true,
    },
    xAxis: {
      type: 'category',
      data: dates.map(d => d.slice(5)),
      boundaryGap: false,
    },
    yAxis: {
      type: 'value',
      name: 'Token 数',
      axisLabel: {
        formatter: (val: number) => formatNumber(val),
      },
    },
    series,
  }, true)
}

onMounted(() => {
  loadUsage()
  if (usageData.value.length > 0) {
    initChart()
  }
  if (chartRef.value) {
    resizeObserver = new ResizeObserver(() => {
      if (chartInstance) chartInstance.resize()
    })
    resizeObserver.observe(chartRef.value)
  }
})

onUnmounted(() => {
  chartInstance?.dispose()
  chartInstance = null
  resizeObserver?.disconnect()
})

// When usageData transitions from empty to non-empty, init chart after DOM update
watch(usageData, (newData) => {
  if (newData.length > 0 && !chartInstance) {
    nextTick(() => initChart())
  }
}, { deep: true })

watch(usageData, updateChart, { deep: true })
</script>

<style scoped>
.usage-panel {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--bg-primary);
  border: 1px solid var(--border-color-split);
  border-radius: 8px;
  padding: 16px;
}

.usage-panel__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  flex-shrink: 0;
}

.usage-panel__header h3 {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
}

.usage-summary {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 16px;
  flex-shrink: 0;
}

.usage-summary__card {
  background: var(--bg-secondary);
  border-radius: 6px;
  padding: 10px 12px;
  text-align: center;
}

.usage-summary__label {
  font-size: 12px;
  color: var(--text-tertiary);
  margin-bottom: 4px;
}

.usage-summary__value {
  font-size: 20px;
  font-weight: 600;
}

.usage-panel__empty {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.usage-panel__chart {
  flex: 1;
  min-height: 0;
}

.echarts-container {
  width: 100%;
  height: 100%;
  min-height: 300px;
}
</style>
