<template>
  <div class="dashboard" v-loading="loading" element-loading-text="加载中...">
    <el-row :gutter="20">
      <el-col :span="6">
        <el-card shadow="hover" class="stat-card">
          <div class="stat-value">{{ stats.users }}</div>
          <div class="stat-label">用户数</div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover" class="stat-card">
          <div class="stat-value">{{ stats.workspaces }}</div>
          <div class="stat-label">工作空间</div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover" class="stat-card">
          <div class="stat-value">{{ stats.conversations }}</div>
          <div class="stat-label">对话数</div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover" class="stat-card">
          <div class="stat-value">{{ stats.messages }}</div>
          <div class="stat-label">消息数</div>
        </el-card>
      </el-col>
    </el-row>

    <el-card v-if="bandwidth" class="bw-card" style="margin-top: 20px">
      <template #header>
        <div class="bw-header">
          <span>应用带宽观测</span>
          <el-text type="info" size="small">{{ bwUpdatedAt }}</el-text>
        </div>
      </template>
      <el-alert type="info" :closable="false" show-icon class="bw-tip">
        以下为<strong>本 Go 进程</strong>统计的 HTTP 请求/响应字节量，用于粗估负载；若前面还有 Nginx/CDN，<strong>公网出口带宽</strong>可能更高。WebSocket（如直播信令）升级后的流量可能未完全计入。
      </el-alert>
      <el-row :gutter="16" class="bw-row">
        <el-col :xs="24" :sm="12" :md="6">
          <div class="bw-metric">
            <div class="bw-label">出站累计（用户下载为主）</div>
            <div class="bw-value">{{ formatBytes(bandwidth.bytes_out_total) }}</div>
          </div>
        </el-col>
        <el-col :xs="24" :sm="12" :md="6">
          <div class="bw-metric">
            <div class="bw-label">入站累计（上传/POST）</div>
            <div class="bw-value">{{ formatBytes(bandwidth.bytes_in_total) }}</div>
          </div>
        </el-col>
        <el-col :xs="24" :sm="12" :md="6">
          <div class="bw-metric">
            <div class="bw-label">近 60 秒出站 · 约 Mbps</div>
            <div class="bw-value accent">{{ bandwidth.recent_egress_mbps }}</div>
            <div class="bw-sub">{{ formatBytes(bandwidth.bytes_out_last_60s) }} / 60s</div>
          </div>
        </el-col>
        <el-col :xs="24" :sm="12" :md="6">
          <div class="bw-metric">
            <div class="bw-label">自启动平均出站 · Mbps</div>
            <div class="bw-value accent">{{ bandwidth.avg_egress_mbps }}</div>
            <div class="bw-sub">运行 {{ formatUptime(bandwidth.uptime_seconds) }}</div>
          </div>
        </el-col>
      </el-row>
      <el-row :gutter="16" class="bw-row bw-row--second">
        <el-col :xs="24" :sm="12">
          <div class="bw-metric bw-metric--inline">
            <span class="bw-label">近 60 秒入站约 Mbps</span>
            <span class="bw-value-inline">{{ bandwidth.recent_ingress_mbps }}</span>
            <span class="bw-sub">{{ formatBytes(bandwidth.bytes_in_last_60s) }} / 60s</span>
          </div>
        </el-col>
        <el-col :xs="24" :sm="12">
          <div class="bw-metric bw-metric--inline">
            <span class="bw-label">自启动平均入站 · Mbps</span>
            <span class="bw-value-inline">{{ bandwidth.avg_ingress_mbps }}</span>
          </div>
        </el-col>
      </el-row>
    </el-card>

    <el-card style="margin-top: 20px">
      <template #header>
        <span>快捷入口</span>
      </template>
      <el-space wrap>
        <el-button type="primary" @click="$router.push('/users')">用户管理</el-button>
        <el-button @click="$router.push('/workspaces')">工作空间</el-button>
        <el-button @click="$router.push('/conversations')">对话管理</el-button>
      </el-space>
    </el-card>
  </div>
</template>

<script setup>
import { reactive, ref, onMounted, onUnmounted, computed } from 'vue'
import { getStats } from '../api/admin'

const stats = reactive({
  users: 0,
  workspaces: 0,
  conversations: 0,
  messages: 0,
  files: 0
})

const bandwidth = ref(null)
const bwFetchAt = ref(0)

const bwUpdatedAt = computed(() => {
  if (!bwFetchAt.value) return ''
  const d = new Date(bwFetchAt.value)
  return `更新于 ${d.toLocaleTimeString()}`
})

const loading = ref(true)

function formatBytes(n) {
  if (n == null || !Number.isFinite(n) || n < 0) return '—'
  if (n < 1024) return `${n} B`
  const u = ['KB', 'MB', 'GB', 'TB']
  let v = n
  let i = -1
  do {
    v /= 1024
    i++
  } while (v >= 1024 && i < u.length - 1)
  return `${v < 10 ? v.toFixed(2) : v.toFixed(1)} ${u[i]}`
}

function formatUptime(sec) {
  if (sec == null || !Number.isFinite(sec) || sec < 0) return '—'
  const s = Math.floor(sec)
  const h = Math.floor(s / 3600)
  const m = Math.floor((s % 3600) / 60)
  const r = s % 60
  if (h > 0) return `${h} 小时 ${m} 分`
  if (m > 0) return `${m} 分 ${r} 秒`
  return `${r} 秒`
}

const fetchStats = async () => {
  loading.value = true
  try {
    const res = await getStats()
    const { bandwidth: bw, ...rest } = res
    Object.assign(stats, rest)
    if (bw && typeof bw === 'object') {
      bandwidth.value = bw
      bwFetchAt.value = Date.now()
    }
  } catch (e) {
    console.error('获取统计失败:', e)
    // 即使失败也显示 0，不阻塞页面
  } finally {
    loading.value = false
  }
}

let pollTimer = null

onMounted(() => {
  fetchStats()
  pollTimer = window.setInterval(() => {
    getStats()
      .then((res) => {
        const { bandwidth: bw, ...rest } = res
        Object.assign(stats, rest)
        if (bw && typeof bw === 'object') {
          bandwidth.value = bw
          bwFetchAt.value = Date.now()
        }
      })
      .catch(() => {})
  }, 8000)
})

onUnmounted(() => {
  if (pollTimer != null) {
    clearInterval(pollTimer)
    pollTimer = null
  }
})
</script>

<style scoped>
.stat-card {
  text-align: center;
  padding: 20px 0;
}
.stat-value {
  font-size: 32px;
  font-weight: bold;
  color: #409eff;
}
.stat-label {
  margin-top: 8px;
  color: #666;
  font-size: 14px;
}
.bw-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.bw-tip {
  margin-bottom: 16px;
}
.bw-row {
  margin-top: 0;
}
.bw-row--second {
  margin-top: 12px;
}
.bw-metric {
  padding: 12px 0;
  border-bottom: 1px solid var(--el-border-color-lighter);
}
.bw-metric--inline {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 12px;
  border-bottom: none;
  padding: 8px 0;
}
.bw-label {
  font-size: 13px;
  color: #606266;
  margin-bottom: 6px;
}
.bw-metric--inline .bw-label {
  margin-bottom: 0;
}
.bw-value {
  font-size: 22px;
  font-weight: 600;
  color: #303133;
}
.bw-value.accent {
  color: #409eff;
}
.bw-value-inline {
  font-size: 18px;
  font-weight: 600;
  color: #409eff;
}
.bw-sub {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
}
</style>
