<script setup>
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'

import { fetchDockerStats, fetchRunningTasks, fetchServerInfo, fetchTaskStats } from '../api/tasks'

const loading = ref(false)

const server = ref({
  cpu_percent: '-',
  memory_used: '-',
  memory_total: '-',
  disk_used: '-',
  disk_total: '-',
  uptime: '-',
})

const docker = ref({
  status: 'Unknown',
  memory_usage: 'N/A',
  memory_limit: 'N/A',
  memory_percent: 'N/A',
  uptime: 'N/A',
})

const taskStats = ref({
  today: { success_tasks: 0, failed_tasks: 0, total_items: 0, total_attachments: 0 },
  total: { success_tasks: 0, failed_tasks: 0, total_items: 0, total_attachments: 0 },
})

const monitor = ref({
  running_count: 0,
  queuing_count: 0,
  max_concurrent: 0,
  running: [],
  queuing: [],
})

const sourceMap = {
  manual: { label: '手动', type: 'success' },
  scheduled: { label: '定时', type: 'primary' },
  immediate: { label: '即时', type: 'warning' },
  resumed: { label: '恢复', type: 'info' },
}

const statusColorMap = {
  初始化: '#6b7280',
  正在登录: '#f59e0b',
  正在浏览: '#10b981',
  浏览完成: '#3b82f6',
  正在截图: '#06b6d4',
}

function statusColor(text) {
  return statusColorMap[text] || '#6b7280'
}

const serverMemoryDisplay = computed(() => `${server.value.memory_used} / ${server.value.memory_total}`)
const serverDiskDisplay = computed(() => `${server.value.disk_used} / ${server.value.disk_total}`)

let stop = false
let timer = null

async function loadOnce() {
  loading.value = true
  try {
    const [serverInfo, dockerInfo, taskStat, running] = await Promise.all([
      fetchServerInfo(),
      fetchDockerStats(),
      fetchTaskStats(),
      fetchRunningTasks(),
    ])

    server.value = serverInfo || server.value
    docker.value = dockerInfo || docker.value
    taskStats.value = taskStat || taskStats.value
    monitor.value = running || monitor.value
  } catch {
    // handled by interceptor
  } finally {
    loading.value = false
  }
}

async function loop() {
  if (stop) return
  const start = Date.now()
  await loadOnce()
  if (stop) return
  const elapsed = Date.now() - start
  // server/info 正常会阻塞约 1s；如果异常很快失败，避免疯狂重试
  timer = window.setTimeout(loop, elapsed < 900 ? 1000 : 0)
}

onMounted(() => {
  stop = false
  loop()
})

onBeforeUnmount(() => {
  stop = true
  if (timer) window.clearTimeout(timer)
})
</script>

<template>
  <div class="page-stack" v-loading="loading">
    <div class="app-page-title">
      <h2>统计</h2>
      <span class="app-muted">实时更新</span>
    </div>

    <el-row :gutter="12">
      <el-col :xs="12" :sm="8" :md="6">
        <el-card shadow="never" class="metric-card" :body-style="{ padding: '14px' }">
          <div class="metric-label">CPU</div>
          <div class="metric-value">{{ server.cpu_percent }}%</div>
        </el-card>
      </el-col>
      <el-col :xs="12" :sm="8" :md="6">
        <el-card shadow="never" class="metric-card" :body-style="{ padding: '14px' }">
          <div class="metric-label">内存</div>
          <div class="metric-value">{{ serverMemoryDisplay }}</div>
        </el-card>
      </el-col>
      <el-col :xs="12" :sm="8" :md="6">
        <el-card shadow="never" class="metric-card" :body-style="{ padding: '14px' }">
          <div class="metric-label">磁盘</div>
          <div class="metric-value">{{ serverDiskDisplay }}</div>
        </el-card>
      </el-col>
      <el-col :xs="12" :sm="8" :md="6">
        <el-card shadow="never" class="metric-card" :body-style="{ padding: '14px' }">
          <div class="metric-label">容器内存</div>
          <div class="metric-value">{{ docker.memory_limit !== 'N/A' ? `${docker.memory_usage} / ${docker.memory_limit}` : docker.memory_usage }}</div>
          <div v-if="docker.memory_percent !== 'N/A'" class="metric-sub app-muted">{{ docker.memory_percent }}</div>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="12">
      <el-col :xs="24" :md="14">
        <el-card shadow="never" class="card" :body-style="{ padding: '16px' }">
          <div class="section-head">
            <h3 class="section-title">实时监控</h3>
            <span class="app-muted">最大并发：{{ monitor.max_concurrent }}</span>
          </div>

          <el-row :gutter="12" class="count-row">
            <el-col :span="8">
              <el-card shadow="never" class="count-card ok" :body-style="{ padding: '12px' }">
                <div class="count-value">{{ monitor.running_count }}</div>
                <div class="count-label">运行中</div>
              </el-card>
            </el-col>
            <el-col :span="8">
              <el-card shadow="never" class="count-card warn" :body-style="{ padding: '12px' }">
                <div class="count-value">{{ monitor.queuing_count }}</div>
                <div class="count-label">排队中</div>
              </el-card>
            </el-col>
            <el-col :span="8">
              <el-card shadow="never" class="count-card" :body-style="{ padding: '12px' }">
                <div class="count-value">{{ monitor.max_concurrent }}</div>
                <div class="count-label">并发上限</div>
              </el-card>
            </el-col>
          </el-row>

          <div class="sub-title">运行中任务</div>
          <div v-if="monitor.running.length === 0" class="empty app-muted">暂无运行中的任务</div>
          <div v-else class="task-list">
            <div v-for="t in monitor.running" :key="`r-${t.account_id}`" class="task-item">
              <div class="task-left">
                <div class="task-line">
                  <el-tag :type="(sourceMap[t.source] || sourceMap.manual).type" effect="light" size="small">
                    {{ (sourceMap[t.source] || sourceMap.manual).label }}
                  </el-tag>
                  <span class="task-user">{{ t.user_username }}</span>
                  <span class="app-muted">→</span>
                  <span class="task-account">{{ t.username }}</span>
                  <el-tag effect="plain" size="small">{{ t.browse_type }}</el-tag>
                </div>
                <div class="task-line2">
                  <span class="dot" :style="{ background: statusColor(t.detail_status) }"></span>
                  <span class="task-status" :style="{ color: statusColor(t.detail_status) }">{{ t.detail_status }}</span>
                  <span v-if="t.progress_items || t.progress_attachments" class="app-muted"
                    >内容/附件：{{ t.progress_items }} / {{ t.progress_attachments }}</span
                  >
                </div>
              </div>
              <div class="task-right">{{ t.elapsed_display }}</div>
            </div>
          </div>

          <div class="sub-title">排队中任务</div>
          <div v-if="monitor.queuing.length === 0" class="empty app-muted">暂无排队中的任务</div>
          <div v-else class="task-list">
            <div v-for="t in monitor.queuing" :key="`q-${t.account_id}`" class="task-item queue">
              <div class="task-left">
                <div class="task-line">
                  <el-tag :type="(sourceMap[t.source] || sourceMap.manual).type" effect="light" size="small">
                    {{ (sourceMap[t.source] || sourceMap.manual).label }}
                  </el-tag>
                  <span class="task-user">{{ t.user_username }}</span>
                  <span class="app-muted">→</span>
                  <span class="task-account">{{ t.username }}</span>
                  <el-tag effect="plain" size="small">{{ t.browse_type }}</el-tag>
                </div>
                <div class="task-line2">
                  <span class="dot" style="background: #f59e0b"></span>
                  <span class="task-status" style="color: #f59e0b">{{ t.detail_status || '等待资源' }}</span>
                </div>
              </div>
              <div class="task-right warn">{{ t.elapsed_display }}</div>
            </div>
          </div>
        </el-card>
      </el-col>

      <el-col :xs="24" :md="10">
        <el-card shadow="never" class="card" :body-style="{ padding: '16px' }">
          <div class="section-head">
            <h3 class="section-title">任务统计</h3>
            <span class="app-muted">运行：{{ server.uptime }}</span>
          </div>

          <div class="stat-grid">
            <div class="stat-box ok">
              <div class="stat-name">成功任务</div>
              <div class="stat-row">
                <span class="stat-big">{{ taskStats.today.success_tasks }}</span>
                <span class="app-muted">今日</span>
              </div>
              <div class="stat-row2 app-muted">累计：{{ taskStats.total.success_tasks }}</div>
            </div>
            <div class="stat-box err">
              <div class="stat-name">失败任务</div>
              <div class="stat-row">
                <span class="stat-big">{{ taskStats.today.failed_tasks }}</span>
                <span class="app-muted">今日</span>
              </div>
              <div class="stat-row2 app-muted">累计：{{ taskStats.total.failed_tasks }}</div>
            </div>
            <div class="stat-box info">
              <div class="stat-name">浏览内容</div>
              <div class="stat-row">
                <span class="stat-big">{{ taskStats.today.total_items }}</span>
                <span class="app-muted">今日</span>
              </div>
              <div class="stat-row2 app-muted">累计：{{ taskStats.total.total_items }}</div>
            </div>
            <div class="stat-box info2">
              <div class="stat-name">查看附件</div>
              <div class="stat-row">
                <span class="stat-big">{{ taskStats.today.total_attachments }}</span>
                <span class="app-muted">今日</span>
              </div>
              <div class="stat-row2 app-muted">累计：{{ taskStats.total.total_attachments }}</div>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<style scoped>
.page-stack {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.metric-card,
.card {
  border-radius: var(--app-radius);
  border: 1px solid var(--app-border);
}

.metric-label {
  font-size: 12px;
  color: var(--app-muted);
}

.metric-value {
  margin-top: 6px;
  font-size: 18px;
  font-weight: 800;
}

.metric-sub {
  margin-top: 4px;
  font-size: 12px;
}

.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
}

.section-title {
  margin: 0;
  font-size: 14px;
  font-weight: 800;
}

.count-row {
  margin-bottom: 10px;
}

.count-card {
  border-radius: 10px;
  border: 1px solid var(--app-border);
}

.count-card.ok {
  background: rgba(16, 185, 129, 0.08);
}

.count-card.warn {
  background: rgba(245, 158, 11, 0.08);
}

.count-value {
  font-size: 22px;
  font-weight: 900;
  line-height: 1.1;
}

.count-label {
  margin-top: 4px;
  font-size: 12px;
  color: var(--app-muted);
}

.sub-title {
  margin-top: 14px;
  margin-bottom: 8px;
  font-size: 13px;
  font-weight: 800;
}

.empty {
  padding: 10px 0;
}

.task-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.task-item {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--app-border);
  background: #fff;
}

.task-item.queue {
  background: rgba(245, 158, 11, 0.06);
}

.task-line {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.task-line2 {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 6px;
  font-size: 12px;
}

.task-user {
  font-weight: 600;
}

.task-account {
  font-weight: 700;
  color: #2563eb;
}

.dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  display: inline-block;
}

.task-status {
  font-weight: 700;
}

.task-right {
  font-size: 12px;
  font-weight: 700;
  color: #10b981;
  white-space: nowrap;
}

.task-right.warn {
  color: #f59e0b;
}

.stat-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.stat-box {
  border-radius: 12px;
  border: 1px solid var(--app-border);
  padding: 12px;
}

.stat-box.ok {
  background: rgba(16, 185, 129, 0.08);
}

.stat-box.err {
  background: rgba(239, 68, 68, 0.08);
}

.stat-box.info {
  background: rgba(59, 130, 246, 0.08);
}

.stat-box.info2 {
  background: rgba(6, 182, 212, 0.08);
}

.stat-name {
  font-size: 12px;
  font-weight: 800;
  margin-bottom: 6px;
}

.stat-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.stat-big {
  font-size: 20px;
  font-weight: 900;
}

.stat-row2 {
  margin-top: 6px;
  font-size: 12px;
}
</style>
