<template>
  <div class="store-page">
    <Breadcrumb />
    <a-card title="抢课客户端">
      <a-row :gutter="[16, 16]" class="stats-row" align="stretch">
        <a-col :xs="24" :md="10" :lg="8" class="stats-col">
          <div class="stats-panel stats-highlight">
            <a-progress
              type="circle"
              :percent="clientStats.occupancyRate / 100"
              :stroke-width="8"
              :width="isMobile ? 96 : 108"
              :color="occupancyColor"
            >
              <template #text>
                <div class="progress-text">
                  <div class="progress-value">{{ clientStats.occupancyRate }}%</div>
                  <div class="progress-label">槽位占用</div>
                </div>
              </template>
            </a-progress>
            <div class="stats-highlight-meta">
              <div class="highlight-title">在线客户端容量</div>
              <div class="highlight-desc">
                已占用 <strong>{{ clientStats.usedSlots }}</strong> / 总容量 <strong>{{ clientStats.totalSlots }}</strong>
              </div>
              <div class="highlight-desc">
                剩余可用槽位 <strong class="highlight-free">{{ clientStats.freeSlots }}</strong>
              </div>
            </div>
          </div>
        </a-col>
        <a-col :xs="24" :md="14" :lg="16" class="stats-col">
          <div class="stats-panel stats-grid-panel">
            <a-row :gutter="[12, 12]" class="stats-grid">
            <a-col :xs="12" :sm="8" :md="6">
              <div class="stat-card">
                <a-statistic title="任务总数" :value="taskStats.total" />
              </div>
            </a-col>
            <a-col :xs="12" :sm="8" :md="6">
              <div class="stat-card">
                <a-statistic title="抢课中" :value="taskStats.active" value-style="color: rgb(var(--orange-6))" />
              </div>
            </a-col>
            <a-col :xs="12" :sm="8" :md="6">
              <div class="stat-card">
                <a-statistic title="待分配" :value="taskStats.pending" value-style="color: rgb(var(--arcoblue-6))" />
              </div>
            </a-col>
            <a-col :xs="12" :sm="8" :md="6">
              <div class="stat-card">
                <a-statistic title="客户端总数" :value="clientStats.total" />
              </div>
            </a-col>
            <a-col :xs="12" :sm="8" :md="6">
              <div class="stat-card">
                <a-statistic title="在线客户端" :value="clientStats.online" value-style="color: rgb(var(--green-6))" />
              </div>
            </a-col>
            <a-col :xs="12" :sm="8" :md="6">
              <div class="stat-card">
                <a-statistic title="已禁用" :value="clientStats.disabled" />
              </div>
            </a-col>
            <a-col :xs="12" :sm="8" :md="6">
              <div class="stat-card">
                <a-statistic title="累计完成" :value="clientStats.totalCompleted" />
              </div>
            </a-col>
            <a-col :xs="12" :sm="8" :md="6">
              <div class="stat-card">
                <a-statistic title="累计成功" :value="clientStats.totalSuccess" value-style="color: rgb(var(--green-6))" />
              </div>
            </a-col>
            </a-row>
          </div>
        </a-col>
      </a-row>

      <a-table
        row-key="client_id"
        :data="data"
        :bordered="false"
        hoverable
        class="table app-data-table"
        :loading="loading"
        :pagination="false"
        :scroll="{ x: isMobile ? 960 : 1250 }"
      >
        <template #columns>
          <a-table-column title="客户端 ID" data-index="client_id" :width="180" ellipsis tooltip />
          <a-table-column title="备注" data-index="label" :width="140" ellipsis tooltip />
          <a-table-column title="状态" :width="90">
            <template #cell="{ record }">
              <a-tag :color="Number(record.enabled) === 1 ? 'arcoblue' : 'red'">
                {{ Number(record.enabled) === 1 ? '启用' : '已禁用' }}
              </a-tag>
            </template>
          </a-table-column>
          <a-table-column title="在线" :width="90">
            <template #cell="{ record }">
              <a-tag :color="Number(record.online) === 1 ? 'green' : 'gray'">
                {{ Number(record.online) === 1 ? '在线' : '离线' }}
              </a-tag>
            </template>
          </a-table-column>
          <a-table-column title="槽位" :width="120">
            <template #cell="{ record }">
              <div class="slot-cell">
                <div class="slot-cell__text">{{ record.current_slots }} / {{ record.max_slots }}</div>
                <div class="slot-bar">
                  <div
                    class="slot-bar__inner"
                    :style="{
                      width: `${slotPercent(record)}%`,
                      backgroundColor: slotBarColor(record)
                    }"
                  />
                </div>
              </div>
            </template>
          </a-table-column>
          <a-table-column title="机器名" data-index="hostname" :width="140" ellipsis tooltip />
          <a-table-column title="登录用户" data-index="os_username" :width="120" ellipsis tooltip />
          <a-table-column title="CPU" :width="220">
            <template #cell="{ record }">
              <AppTableEllipsis
                :row-key="`${record.client_id}-cpu`"
                :content="`${record.cpu_model || '-'} (${record.cpu_threads || '-'}线程)`"
              />
            </template>
          </a-table-column>
          <a-table-column title="内存" :width="140">
            <template #cell="{ record }">
              {{ record.free_mem_mb || '-' }} / {{ record.total_mem_mb || '-' }} MB
            </template>
          </a-table-column>
          <a-table-column title="系统" data-index="platform" :width="160" ellipsis tooltip />
          <a-table-column title="完成/成功" :width="120">
            <template #cell="{ record }">{{ record.total_completed }} / {{ record.total_success }}</template>
          </a-table-column>
          <a-table-column title="最后心跳" :width="180">
            <template #cell="{ record }">{{ formatTime(record.last_heartbeat_at) }}</template>
          </a-table-column>
          <a-table-column title="操作" :width="120" :fixed="tableFixed('right')">
            <template #cell="{ record }">
              <a-popconfirm
                v-if="Number(record.enabled) === 1"
                content="确认禁用该客户端？"
                @ok="deleteClient(record)"
              >
                <a-button type="text" status="danger" size="small">禁用</a-button>
              </a-popconfirm>
              <a-popconfirm
                v-else
                content="确认解禁该客户端？解禁后客户端可重新注册上线。"
                @ok="enableClient(record)"
              >
                <a-button type="text" status="success" size="small">解禁</a-button>
              </a-popconfirm>
            </template>
          </a-table-column>
        </template>
        <template #empty>
          <a-empty description="暂无抢课客户端" />
        </template>
      </a-table>
    </a-card>
  </div>
</template>

<script setup>
import { computed, onMounted, onUnmounted, reactive, ref } from 'vue'
import { Notification } from '@arco-design/web-vue'
import { adminQkClientDelete, adminQkClientEnable, adminQkClientList, adminQkTaskList } from '@/api/qk'
import { useResponsiveTable } from '@/hooks/useResponsiveTable'

const { tableFixed, isMobile } = useResponsiveTable()

const data = ref([])
const loading = ref(false)
const taskStats = reactive({
  total: 0,
  active: 0,
  pending: 0
})

const clientStats = computed(() => {
  const list = data.value || []
  const enabled = list.filter(item => Number(item.enabled) === 1)
  const online = enabled.filter(item => Number(item.online) === 1)
  const totalSlots = online.reduce((sum, item) => sum + Math.max(0, Number(item.max_slots) || 0), 0)
  const usedSlots = online.reduce((sum, item) => sum + Math.max(0, Number(item.current_slots) || 0), 0)
  const freeSlots = Math.max(0, totalSlots - usedSlots)
  const occupancyRate = totalSlots > 0 ? Math.min(100, Math.round((usedSlots / totalSlots) * 100)) : 0
  return {
    total: list.length,
    online: online.length,
    disabled: list.length - enabled.length,
    totalSlots,
    usedSlots,
    freeSlots,
    occupancyRate,
    totalCompleted: list.reduce((sum, item) => sum + (Number(item.total_completed) || 0), 0),
    totalSuccess: list.reduce((sum, item) => sum + (Number(item.total_success) || 0), 0)
  }
})

const occupancyColor = computed(() => {
  const rate = clientStats.value.occupancyRate
  if (rate >= 90) return '#F53F3F'
  if (rate >= 70) return '#FF7D00'
  return '#165DFF'
})

const slotPercent = (record) => {
  const max = Math.max(0, Number(record.max_slots) || 0)
  const current = Math.max(0, Number(record.current_slots) || 0)
  if (!max) return 0
  return Math.min(100, Math.round((current / max) * 100))
}

const slotBarColor = (record) => {
  const percent = slotPercent(record)
  if (percent >= 90) return '#F53F3F'
  if (Number(record.online) !== 1 || Number(record.enabled) !== 1) return '#C9CDD4'
  return '#165DFF'
}

const formatTime = (time) => {
  if (!time) return '-'
  return new Date(Number(time)).toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  })
}

const fetchTaskStats = async () => {
  try {
    const [allRes, runningRes, assignedRes, pendingRes] = await Promise.all([
      adminQkTaskList({ current: 1, pagesize: 1 }),
      adminQkTaskList({ current: 1, pagesize: 1, status: 'running' }),
      adminQkTaskList({ current: 1, pagesize: 1, status: 'assigned' }),
      adminQkTaskList({ current: 1, pagesize: 1, status: 'pending' })
    ])
    if (allRes?.code === 0) taskStats.total = allRes.data?.total || 0
    const running = runningRes?.code === 0 ? (runningRes.data?.total || 0) : 0
    const assigned = assignedRes?.code === 0 ? (assignedRes.data?.total || 0) : 0
    taskStats.active = running + assigned
    if (pendingRes?.code === 0) taskStats.pending = pendingRes.data?.total || 0
  } catch (_) {}
}

const getList = async (silent = false) => {
  try {
    if (!silent) loading.value = true
    const res = await adminQkClientList()
    if (!res || res.code !== 0) {
      if (!silent) {
        Notification.error({ title: '获取客户端失败', content: res?.msg || '请稍后再试' })
      }
      return
    }
    data.value = res.data || []
  } catch (error) {
    if (!silent) {
      Notification.error({ title: '获取客户端失败', content: error.message || '请稍后再试' })
    }
  } finally {
    if (!silent) loading.value = false
  }
}

const deleteClient = async (record) => {
  const res = await adminQkClientDelete({ client_id: record.client_id })
  if (!res || res.code !== 0) {
    return Notification.error({ title: '禁用客户端失败', content: res?.msg || '请稍后再试' })
  }
  Notification.success({ title: '已禁用' })
  getList()
  fetchTaskStats()
}

const enableClient = async (record) => {
  const res = await adminQkClientEnable({ client_id: record.client_id })
  if (!res || res.code !== 0) {
    return Notification.error({ title: '解禁客户端失败', content: res?.msg || '请稍后再试' })
  }
  Notification.success({ title: '已解禁', content: '客户端下次上线时可正常注册' })
  getList()
  fetchTaskStats()
}

let pollTimer = null
let statsTimer = null

const startPolling = () => {
  if (!pollTimer) {
    pollTimer = setInterval(() => getList(true), 5000)
  }
  if (!statsTimer) {
    statsTimer = setInterval(fetchTaskStats, 30000)
  }
}

const stopPolling = () => {
  if (pollTimer) {
    clearInterval(pollTimer)
    pollTimer = null
  }
  if (statsTimer) {
    clearInterval(statsTimer)
    statsTimer = null
  }
}

onMounted(() => {
  getList()
  fetchTaskStats()
  startPolling()
})

onUnmounted(() => {
  stopPolling()
})
</script>

<style scoped lang="less">
@import '@/styles/store-theme.less';

.stats-row {
  margin-bottom: 24px;
}

.stats-col {
  display: flex;
}

.stats-panel {
  width: 100%;
  min-height: 148px;
  box-sizing: border-box;
}

.stats-highlight {
  display: flex;
  align-items: center;
  gap: 16px;
  height: 100%;
  padding: 16px;
  border: 1px solid var(--color-border-2);
  border-radius: 12px;
  background: linear-gradient(135deg, rgba(var(--primary-1), 0.35), rgba(var(--primary-1), 0.08));
}

.stats-grid-panel {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 12px;
  border: 1px solid var(--color-border-2);
  border-radius: 12px;
  background: var(--color-bg-1);
}

.stats-grid {
  flex: 1;
  align-content: stretch;
}

.stat-card {
  height: 100%;
  min-height: 72px;
  padding: 12px;
  border: 1px solid var(--color-border-2);
  border-radius: 10px;
  background: var(--color-bg-2);
  display: flex;
  flex-direction: column;
  justify-content: center;
  box-sizing: border-box;
}

:deep(.stat-card .arco-statistic-title) {
  margin-bottom: 4px;
  font-size: 13px;
}

:deep(.stat-card .arco-statistic-value) {
  font-size: 22px;
  line-height: 1.2;
}

.slot-cell {
  width: 96px;
  max-width: 100%;
}

.slot-cell__text {
  font-size: 13px;
  line-height: 1.4;
  white-space: nowrap;
}

.slot-bar {
  height: 6px;
  margin-top: 6px;
  border-radius: 999px;
  background: var(--color-fill-3);
  overflow: hidden;
}

.slot-bar__inner {
  height: 100%;
  border-radius: 999px;
  min-width: 0;
  max-width: 100%;
  transition: width 0.2s ease;
}

.progress-text {
  text-align: center;
}

.progress-value {
  font-size: 18px;
  font-weight: 600;
  line-height: 1.2;
}

.progress-label {
  margin-top: 2px;
  font-size: 12px;
  color: var(--color-text-3);
}

.stats-highlight-meta {
  flex: 1;
  min-width: 0;
}

.highlight-title {
  font-size: 15px;
  font-weight: 600;
  margin-bottom: 8px;
}

.highlight-desc {
  color: var(--color-text-2);
  font-size: 13px;
  line-height: 1.6;

  strong {
    color: var(--color-text-1);
  }
}

.highlight-free {
  color: rgb(var(--green-6));
}

.info-alert {
  margin-bottom: 24px;
}

.table {
  margin-top: 4px;
}

@media (max-width: 768px) {
  .stats-panel {
    min-height: auto;
  }

  .stats-highlight {
    flex-direction: column;
    align-items: center;
    text-align: center;
  }

  .stats-highlight-meta {
    width: 100%;
  }

  .stat-card {
    min-height: 64px;
  }
}
</style>
