<script setup>
import { computed, inject, onMounted, onUnmounted, ref } from 'vue'
import {
  Calendar,
  ChatLineSquare,
  Clock,
  Cpu,
  Key,
  Loading,
  Message,
  Star,
  Tickets,
  Tools,
  TrendCharts,
  UserFilled,
} from '@element-plus/icons-vue'

import { fetchFeedbackStats } from '../api/feedbacks'
import { fetchEmailStats } from '../api/email'
import { fetchDockerStats, fetchRunningTasks, fetchServerInfo, fetchTaskStats } from '../api/tasks'
import { fetchBrowserPoolStats } from '../api/browser_pool'
import { fetchSystemConfig } from '../api/system'
import MetricGrid from '../components/MetricGrid.vue'

const refreshStats = inject('refreshStats', null)
const adminStats = inject('adminStats', null)

const loading = ref(false)
const refreshing = ref(false)
const lastUpdatedAt = ref('')

const taskStats = ref(null)
const runningTasks = ref(null)
const emailStats = ref(null)
const feedbackStats = ref(null)
const serverInfo = ref(null)
const dockerStats = ref(null)
const browserPoolStats = ref(null)
const systemConfig = ref(null)
const queueTab = ref('running')

function recordUpdatedAt() {
  try {
    lastUpdatedAt.value = new Date().toLocaleString('zh-CN', { hour12: false, timeZone: 'Asia/Shanghai' })
  } catch {
    lastUpdatedAt.value = ''
  }
}

function normalizeCount(value) {
  const n = Number(value)
  return Number.isFinite(n) ? n : 0
}

function parsePercent(value) {
  const text = String(value ?? '').trim()
  if (!text) return 0
  const cleaned = text.endsWith('%') ? text.slice(0, -1) : text
  const n = Number(cleaned)
  if (!Number.isFinite(n)) return 0
  if (n < 0) return 0
  if (n > 1000) return 1000
  return n
}

function percentText(value) {
  return `${Math.round(parsePercent(value))}%`
}

function sourceLabel(source) {
  const raw = String(source ?? '').trim()
  if (!raw) return '手动'
  if (raw === 'manual') return '手动'
  if (raw === 'scheduled') return '系统定时'
  if (raw === 'batch') return '批量执行'
  if (raw === 'resumed') return '断点续跑'
  if (raw.startsWith('user_scheduled:')) return '用户定时'
  return raw
}

const overviewCards = computed(() => {
  const s = adminStats?.value || {}
  const liveMax = normalizeCount(runningTasks.value?.max_concurrent)
  return [
    { label: '总用户数', value: normalizeCount(s.total_users), icon: UserFilled, tone: 'blue' },
    { label: '今日注册', value: normalizeCount(s.new_users_today), icon: Calendar, tone: 'green' },
    { label: '近7天注册', value: normalizeCount(s.new_users_7d), icon: TrendCharts, tone: 'purple' },
    { label: '总账号数', value: normalizeCount(s.total_accounts), icon: Key, tone: 'cyan' },
    { label: 'VIP用户', value: normalizeCount(s.vip_users), icon: Star, tone: 'orange' },
    {
      label: '运行中任务',
      value: normalizeCount(runningTasks.value?.running_count),
      icon: Loading,
      tone: 'green',
      sub: liveMax ? `并发上限 ${liveMax}` : '',
    },
    { label: '排队任务', value: normalizeCount(runningTasks.value?.queuing_count), icon: Clock, tone: 'purple' },
  ]
})

const taskToday = computed(() => taskStats.value?.today || {})
const taskTotal = computed(() => taskStats.value?.total || {})
const runningTaskList = computed(() => runningTasks.value?.running || [])
const queuingTaskList = computed(() => runningTasks.value?.queuing || [])
const runningCount = computed(() => normalizeCount(runningTasks.value?.running_count))
const queuingCount = computed(() => normalizeCount(runningTasks.value?.queuing_count))

const browserPoolWorkers = computed(() => {
  const workers = browserPoolStats.value?.workers
  if (!Array.isArray(workers)) return []
  return [...workers].sort((a, b) => normalizeCount(a?.worker_id) - normalizeCount(b?.worker_id))
})

const browserPoolTotalWorkers = computed(() => normalizeCount(browserPoolStats.value?.total_workers))
const browserPoolActiveWorkers = computed(() => browserPoolWorkers.value.filter((w) => Boolean(w?.has_browser)).length)
const browserPoolIdleWorkers = computed(() => normalizeCount(browserPoolStats.value?.idle_workers))
const browserPoolQueueSize = computed(() => normalizeCount(browserPoolStats.value?.queue_size))
const browserPoolBusyWorkers = computed(() => normalizeCount(browserPoolStats.value?.active_workers))

function workerPoolStatusType(worker) {
  if (!worker?.thread_alive) return 'danger'
  if (worker?.has_browser) return 'success'
  return 'info'
}

function workerPoolStatusLabel(worker) {
  if (!worker?.thread_alive) return '异常'
  if (worker?.has_browser) return '活跃'
  return '空闲'
}

function workerRunTagType(worker) {
  if (!worker?.thread_alive) return 'danger'
  return worker?.idle ? 'info' : 'warning'
}

function workerRunLabel(worker) {
  if (!worker?.thread_alive) return '停止'
  return worker?.idle ? '空闲' : '忙碌'
}

const taskTodaySuccessRate = computed(() => {
  const success = normalizeCount(taskToday.value.success_tasks)
  const failed = normalizeCount(taskToday.value.failed_tasks)
  const total = success + failed
  return total > 0 ? Math.round((success / total) * 1000) / 10 : 0
})

const emailSuccessRate = computed(() => normalizeCount(emailStats.value?.success_rate))

const taskTodayCards = computed(() => [
  { label: '总任务', value: normalizeCount(taskToday.value.total_tasks), tone: 'blue' },
  { label: '成功', value: normalizeCount(taskToday.value.success_tasks), tone: 'green' },
  { label: '失败', value: normalizeCount(taskToday.value.failed_tasks), tone: 'red' },
  { label: '浏览内容', value: normalizeCount(taskToday.value.total_items), tone: 'purple' },
  { label: '查看附件', value: normalizeCount(taskToday.value.total_attachments), tone: 'cyan' },
])

const taskTotalCards = computed(() => [
  { label: '总任务', value: normalizeCount(taskTotal.value.total_tasks), tone: 'blue' },
  { label: '成功', value: normalizeCount(taskTotal.value.success_tasks), tone: 'green' },
  { label: '失败', value: normalizeCount(taskTotal.value.failed_tasks), tone: 'red' },
  { label: '浏览内容', value: normalizeCount(taskTotal.value.total_items), tone: 'purple' },
  { label: '查看附件', value: normalizeCount(taskTotal.value.total_attachments), tone: 'cyan' },
])

const emailCards = computed(() => [
  { label: '总发送', value: normalizeCount(emailStats.value?.total_sent), tone: 'blue' },
  { label: '成功', value: normalizeCount(emailStats.value?.total_success), tone: 'green' },
  { label: '失败', value: normalizeCount(emailStats.value?.total_failed), tone: 'red' },
  { label: '成功率', value: `${emailSuccessRate.value}%`, tone: 'purple' },
])

const emailTypeCards = computed(() => [
  { label: '注册验证', value: normalizeCount(emailStats.value?.register_sent), tone: 'cyan' },
  { label: '密码重置', value: normalizeCount(emailStats.value?.reset_sent), tone: 'orange' },
  { label: '邮箱绑定', value: normalizeCount(emailStats.value?.bind_sent), tone: 'purple' },
  { label: '任务完成', value: normalizeCount(emailStats.value?.task_complete_sent), tone: 'green' },
])

const feedbackCards = computed(() => [
  { label: '总反馈', value: normalizeCount(feedbackStats.value?.total), tone: 'blue' },
  { label: '待处理', value: normalizeCount(feedbackStats.value?.pending), tone: 'orange' },
  { label: '已回复', value: normalizeCount(feedbackStats.value?.replied), tone: 'green' },
])

const browserPoolCards = computed(() => [
  { label: '总 Worker', value: browserPoolTotalWorkers.value, tone: 'blue' },
  { label: '活跃 Worker', value: browserPoolActiveWorkers.value, tone: 'green' },
  { label: '空闲 Worker', value: browserPoolIdleWorkers.value, tone: 'cyan' },
  { label: '忙碌 Worker', value: browserPoolBusyWorkers.value, tone: 'orange' },
  { label: '队列', value: browserPoolQueueSize.value, tone: 'purple' },
])

const scheduleEnabled = computed(() => (systemConfig.value?.schedule_enabled ?? 0) === 1)
const scheduleTime = computed(() => systemConfig.value?.schedule_time || '-')
const scheduleBrowseType = computed(() => systemConfig.value?.schedule_browse_type || '-')
const scheduleWeekdays = computed(() => String(systemConfig.value?.schedule_weekdays || '').trim())
const scheduleWeekdaysDisplay = computed(() => {
  const raw = scheduleWeekdays.value
  if (!raw) return ''
  const map = {
    1: '周一',
    2: '周二',
    3: '周三',
    4: '周四',
    5: '周五',
    6: '周六',
    7: '周日',
  }
  const parts = raw
    .split(',')
    .map((x) => x.trim())
    .filter(Boolean)
  if (!parts.length) return raw
  return parts.map((p) => map[Number(p)] || p).join('、')
})

const proxyEnabled = computed(() => (systemConfig.value?.proxy_enabled ?? 0) === 1)
const proxyApiUrl = computed(() => systemConfig.value?.proxy_api_url || '')
const proxyExpireMinutes = computed(() => normalizeCount(systemConfig.value?.proxy_expire_minutes))

const maxConcurrentGlobal = computed(() => normalizeCount(systemConfig.value?.max_concurrent_global))
const maxConcurrentPerAccount = computed(() => normalizeCount(systemConfig.value?.max_concurrent_per_account))
const maxScreenshotConcurrent = computed(() => normalizeCount(systemConfig.value?.max_screenshot_concurrent))

const runningCountsLabel = computed(() => {
  const runningCount = normalizeCount(runningTasks.value?.running_count)
  const queuingCount = normalizeCount(runningTasks.value?.queuing_count)
  const maxGlobal = normalizeCount(runningTasks.value?.max_concurrent)
  return `运行中 ${runningCount} / 排队 ${queuingCount} / 并发上限 ${maxGlobal || maxConcurrentGlobal.value || '-'}`
})

const overviewModuleItems = computed(() =>
  overviewCards.value.map((item) => ({
    label: item.label,
    value: item.sub ? `${item.value}（${item.sub}）` : item.value,
  })),
)

const taskModuleItems = computed(() => [
  { label: '今日总任务', value: normalizeCount(taskToday.value.total_tasks) },
  { label: '今日成功', value: normalizeCount(taskToday.value.success_tasks) },
  { label: '今日失败', value: normalizeCount(taskToday.value.failed_tasks) },
  { label: '今日成功率', value: `${taskTodaySuccessRate.value}%` },
  { label: '累计任务', value: normalizeCount(taskTotal.value.total_tasks) },
  { label: '累计成功', value: normalizeCount(taskTotal.value.success_tasks) },
])

const queueModuleItems = computed(() => [
  { label: '运行中', value: runningCount.value },
  { label: '排队中', value: queuingCount.value },
  { label: '并发上限', value: normalizeCount(runningTasks.value?.max_concurrent) || maxConcurrentGlobal.value || '-' },
  { label: '排队首条来源', value: sourceLabel(queuingTaskList.value[0]?.source) },
  { label: '排队首条状态', value: queuingTaskList.value[0]?.detail_status || queuingTaskList.value[0]?.status || '-' },
  { label: '最长等待', value: queuingTaskList.value[0]?.elapsed_display || '-' },
])

const emailModuleItems = computed(() => [
  { label: '总发送', value: normalizeCount(emailStats.value?.total_sent) },
  { label: '成功', value: normalizeCount(emailStats.value?.total_success) },
  { label: '失败', value: normalizeCount(emailStats.value?.total_failed) },
  { label: '成功率', value: `${emailSuccessRate.value}%` },
  { label: '注册验证', value: normalizeCount(emailStats.value?.register_sent) },
  { label: '重置密码', value: normalizeCount(emailStats.value?.reset_sent) },
])

const feedbackModuleItems = computed(() => [
  { label: '总反馈', value: normalizeCount(feedbackStats.value?.total) },
  { label: '待处理', value: normalizeCount(feedbackStats.value?.pending) },
  { label: '已回复', value: normalizeCount(feedbackStats.value?.replied) },
])

const resourceModuleItems = computed(() => [
  { label: 'CPU', value: percentText(serverInfo.value?.cpu_percent) },
  { label: '内存', value: percentText(serverInfo.value?.memory_percent) },
  { label: '磁盘', value: percentText(serverInfo.value?.disk_percent) },
  { label: '容器状态', value: dockerStats.value?.status || '-' },
  { label: '容器名', value: dockerStats.value?.container_name || '-' },
  { label: '容器运行', value: dockerStats.value?.uptime || '-' },
])

const workerModuleItems = computed(() => [
  { label: '总 Worker', value: browserPoolTotalWorkers.value },
  { label: '活跃 Worker', value: browserPoolActiveWorkers.value },
  { label: '忙碌 Worker', value: browserPoolBusyWorkers.value },
  { label: '空闲 Worker', value: browserPoolIdleWorkers.value },
  { label: '任务队列', value: browserPoolQueueSize.value },
])

const configModuleItems = computed(() => [
  { label: '定时任务', value: scheduleEnabled.value ? '启用' : '关闭' },
  { label: '执行时间', value: scheduleTime.value || '-' },
  { label: '浏览类型', value: scheduleBrowseType.value || '-' },
  { label: '代理', value: proxyEnabled.value ? '启用' : '关闭' },
  { label: '代理有效期', value: proxyExpireMinutes.value ? `${proxyExpireMinutes.value} 分钟` : '-' },
  { label: '全局并发', value: maxConcurrentGlobal.value || '-' },
  { label: '单账号并发', value: maxConcurrentPerAccount.value || '-' },
  { label: '截图并发', value: maxScreenshotConcurrent.value || '-' },
])

const mobileModules = computed(() => [
  {
    key: 'overview',
    title: '平台概览',
    desc: lastUpdatedAt.value ? `更新 ${lastUpdatedAt.value}` : '核心指标',
    tone: 'blue',
    items: overviewModuleItems.value,
  },
  {
    key: 'task',
    title: '任务概览',
    desc: normalizeCount(taskToday.value.total_tasks) > 0 ? `今日成功率 ${taskTodaySuccessRate.value}%` : '今日暂无任务',
    tone: 'purple',
    items: taskModuleItems.value,
  },
  {
    key: 'queue',
    title: '队列监控',
    desc: runningCountsLabel.value,
    tone: 'blue',
    items: queueModuleItems.value,
  },
  {
    key: 'email',
    title: '邮件报表',
    desc: `成功率 ${emailSuccessRate.value}%`,
    tone: 'cyan',
    items: emailModuleItems.value,
  },
  {
    key: 'feedback',
    title: '反馈概览',
    desc: `待处理 ${normalizeCount(feedbackStats.value?.pending)} 条`,
    tone: 'orange',
    items: feedbackModuleItems.value,
  },
  {
    key: 'resource',
    title: '系统资源',
    desc: serverInfo.value?.uptime ? `运行 ${serverInfo.value.uptime}` : '运行状态获取中',
    tone: 'green',
    items: resourceModuleItems.value,
  },
  {
    key: 'worker',
    title: '截图线程池',
    desc: `活跃 ${browserPoolActiveWorkers.value} · 忙碌 ${browserPoolBusyWorkers.value}`,
    tone: 'cyan',
    items: workerModuleItems.value,
  },
  {
    key: 'config',
    title: '配置概览',
    desc: '并发 / 代理 / 定时任务',
    tone: 'red',
    items: configModuleItems.value,
  },
])

async function refreshAll(options = {}) {
  const showLoading = options.showLoading ?? true
  if (refreshing.value) return
  refreshing.value = true
  if (showLoading) {
    loading.value = true
  }
  try {
    const [
      taskResult,
      runningResult,
      emailResult,
      feedbackResult,
      serverResult,
      dockerResult,
      browserPoolResult,
      configResult,
    ] = await Promise.allSettled([
      fetchTaskStats(),
      fetchRunningTasks(),
      fetchEmailStats(),
      fetchFeedbackStats(),
      fetchServerInfo(),
      fetchDockerStats(),
      fetchBrowserPoolStats(),
      fetchSystemConfig(),
    ])

    if (taskResult.status === 'fulfilled') taskStats.value = taskResult.value
    if (runningResult.status === 'fulfilled') runningTasks.value = runningResult.value
    if (emailResult.status === 'fulfilled') emailStats.value = emailResult.value
    if (feedbackResult.status === 'fulfilled') feedbackStats.value = feedbackResult.value
    if (serverResult.status === 'fulfilled') serverInfo.value = serverResult.value
    if (dockerResult.status === 'fulfilled') dockerStats.value = dockerResult.value
    if (browserPoolResult.status === 'fulfilled') browserPoolStats.value = browserPoolResult.value
    if (configResult.status === 'fulfilled') systemConfig.value = configResult.value

    await refreshStats?.()
    recordUpdatedAt()
  } finally {
    refreshing.value = false
    if (showLoading) {
      loading.value = false
    }
  }
}

let refreshTimer = null

onMounted(() => {
  refreshAll({ showLoading: false })
  refreshTimer = setInterval(() => refreshAll({ showLoading: false }), 5000)
})

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

<template>
  <div class="page-stack">
    <section class="report-hero">
      <div class="hero-head">
        <div class="hero-main">
          <h2>报表中心</h2>
          <div class="hero-meta app-muted">
            <span v-if="lastUpdatedAt">更新时间：{{ lastUpdatedAt }}</span>
            <span v-if="serverInfo?.uptime" class="hero-dot">·</span>
            <span v-if="serverInfo?.uptime">运行 {{ serverInfo.uptime }}</span>
          </div>
        </div>

      </div>

      <MetricGrid class="hero-overview-grid" :items="overviewCards" :loading="loading" :min-width="165" />
    </section>

    <section class="mobile-report">
      <el-card
        v-for="module in mobileModules"
        :key="module.key"
        shadow="never"
        class="mobile-module-card"
        :class="`mobile-tone-${module.tone}`"
        :body-style="{ padding: '12px' }"
      >
        <div class="mobile-module-head">
          <div class="mobile-module-title">{{ module.title }}</div>
          <div class="mobile-module-desc app-muted">{{ module.desc }}</div>
        </div>
        <div class="mobile-metrics">
          <div v-for="item in module.items" :key="`${module.key}-${item.label}`" class="mobile-metric-item">
            <div class="mobile-metric-label app-muted">{{ item.label }}</div>
            <div class="mobile-metric-value">{{ item.value }}</div>
          </div>
        </div>
      </el-card>
    </section>

    <div class="desktop-report">
    <el-row :gutter="12">
      <el-col :xs="24" :lg="12">
        <el-card shadow="never" class="panel" :body-style="{ padding: '16px' }">
          <div class="panel-head">
            <div class="head-left">
              <div class="head-icon tone-purple">
                <el-icon><TrendCharts /></el-icon>
              </div>
              <div class="head-text">
                <div class="panel-title">任务概览</div>
                <div class="panel-sub app-muted">
                  <template v-if="normalizeCount(taskToday.total_tasks) > 0">
                    今日成功率 {{ taskTodaySuccessRate }}% · {{ runningCountsLabel }}
                  </template>
                  <template v-else>今日无任务 · {{ runningCountsLabel }}</template>
                </div>
              </div>
            </div>
            <el-progress
              type="circle"
              :percentage="normalizeCount(taskToday.total_tasks) > 0 ? Math.round(taskTodaySuccessRate) : 0"
              :width="74"
              :stroke-width="10"
              :status="normalizeCount(taskToday.total_tasks) === 0 ? 'success' : taskTodaySuccessRate >= 90 ? 'success' : taskTodaySuccessRate >= 60 ? 'warning' : 'exception'"
            />
          </div>

          <div class="metrics-block">
            <div class="block-title">今日</div>
            <MetricGrid :items="taskTodayCards" :loading="loading" :min-width="120" />
          </div>

          <div class="divider"></div>

          <div class="metrics-block">
            <div class="block-title">累计</div>
            <MetricGrid :items="taskTotalCards" :loading="loading" :min-width="120" />
          </div>
        </el-card>
      </el-col>

      <el-col :xs="24" :lg="12">
        <el-card shadow="never" class="panel" :body-style="{ padding: '16px' }">
          <div class="panel-head">
            <div class="head-left">
              <div class="head-icon tone-blue">
                <el-icon><Tickets /></el-icon>
              </div>
              <div class="head-text">
                <div class="panel-title">队列监控</div>
                <div class="panel-sub app-muted">{{ runningCountsLabel }}</div>
              </div>
            </div>
          </div>

          <el-tabs v-model="queueTab" class="queue-tabs" stretch>
            <el-tab-pane name="running">
              <template #label>
                <span class="tab-label">
                  运行中
                  <el-tag size="small" effect="light" type="success">{{ runningCount }}</el-tag>
                </span>
              </template>
              <div class="table-wrap">
                <el-table :data="runningTaskList.slice(0, 10)" size="small" style="width: 100%">
                  <el-table-column label="用户" min-width="120">
                    <template #default="{ row }">{{ row.user_username || '-' }}</template>
                  </el-table-column>
                  <el-table-column label="账号" min-width="150">
                    <template #default="{ row }">{{ row.username || '-' }}</template>
                  </el-table-column>
                  <el-table-column label="来源" width="100">
                    <template #default="{ row }">{{ sourceLabel(row.source) }}</template>
                  </el-table-column>
                  <el-table-column label="类型" width="90">
                    <template #default="{ row }">{{ row.browse_type || '-' }}</template>
                  </el-table-column>
                  <el-table-column label="进度" width="100">
                    <template #default="{ row }">{{ row.progress_items }}/{{ row.progress_attachments }}</template>
                  </el-table-column>
                  <el-table-column label="耗时" width="100">
                    <template #default="{ row }">{{ row.elapsed_display || '-' }}</template>
                  </el-table-column>
                  <el-table-column label="状态" min-width="140">
                    <template #default="{ row }">{{ row.detail_status || row.status || '-' }}</template>
                  </el-table-column>
                </el-table>
              </div>
              <div v-if="runningCount === 0" class="help app-muted">当前无运行任务</div>
            </el-tab-pane>

            <el-tab-pane name="queuing">
              <template #label>
                <span class="tab-label">
                  排队中
                  <el-tag size="small" effect="light" type="warning">{{ queuingCount }}</el-tag>
                </span>
              </template>
              <div class="table-wrap">
                <el-table :data="queuingTaskList.slice(0, 10)" size="small" style="width: 100%">
                  <el-table-column label="用户" min-width="120">
                    <template #default="{ row }">{{ row.user_username || '-' }}</template>
                  </el-table-column>
                  <el-table-column label="账号" min-width="150">
                    <template #default="{ row }">{{ row.username || '-' }}</template>
                  </el-table-column>
                  <el-table-column label="来源" width="100">
                    <template #default="{ row }">{{ sourceLabel(row.source) }}</template>
                  </el-table-column>
                  <el-table-column label="类型" width="90">
                    <template #default="{ row }">{{ row.browse_type || '-' }}</template>
                  </el-table-column>
                  <el-table-column label="等待" width="100">
                    <template #default="{ row }">{{ row.elapsed_display || '-' }}</template>
                  </el-table-column>
                  <el-table-column label="状态" min-width="160">
                    <template #default="{ row }">{{ row.detail_status || row.status || '-' }}</template>
                  </el-table-column>
                </el-table>
              </div>
              <div v-if="queuingCount === 0" class="help app-muted">当前无排队任务</div>
            </el-tab-pane>
          </el-tabs>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="12">
      <el-col :xs="24" :lg="12">
        <el-card shadow="never" class="panel" :body-style="{ padding: '16px' }">
          <div class="panel-head">
            <div class="head-left">
              <div class="head-icon tone-cyan">
                <el-icon><Message /></el-icon>
              </div>
              <div class="head-text">
                <div class="panel-title">邮件报表</div>
                <div class="panel-sub app-muted">成功率 {{ emailSuccessRate }}%</div>
              </div>
            </div>
          </div>

          <MetricGrid :items="emailCards" :loading="loading" :min-width="132" />

          <div class="divider"></div>

          <div class="metrics-block">
            <div class="block-title">类型统计</div>
            <MetricGrid :items="emailTypeCards" :loading="loading" :min-width="132" />
          </div>
        </el-card>
      </el-col>

      <el-col :xs="24" :lg="12">
        <el-card shadow="never" class="panel" :body-style="{ padding: '16px' }">
          <div class="panel-head">
            <div class="head-left">
              <div class="head-icon tone-orange">
                <el-icon><ChatLineSquare /></el-icon>
              </div>
              <div class="head-text">
                <div class="panel-title">反馈概览</div>
                <div class="panel-sub app-muted">待处理 {{ normalizeCount(feedbackStats?.pending) }} 条</div>
              </div>
            </div>
          </div>

          <MetricGrid :items="feedbackCards" :loading="loading" :min-width="145" />

          <div class="help app-muted">提示：反馈处理越及时，用户留存与满意度越高。</div>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="12">
      <el-col :xs="24" :lg="12">
        <el-card shadow="never" class="panel" :body-style="{ padding: '16px' }">
          <div class="panel-head">
            <div class="head-left">
              <div class="head-icon tone-green">
                <el-icon><Cpu /></el-icon>
              </div>
              <div class="head-text">
                <div class="panel-title">系统资源</div>
                <div class="panel-sub app-muted">服务器与容器运行状态</div>
              </div>
            </div>
            <el-tag v-if="serverInfo?.uptime" effect="light" type="info">运行 {{ serverInfo.uptime }}</el-tag>
          </div>

          <div class="resource-grid">
            <div class="resource-item">
              <div class="resource-k app-muted">CPU</div>
              <el-progress
                :percentage="Math.round(parsePercent(serverInfo?.cpu_percent))"
                :status="parsePercent(serverInfo?.cpu_percent) >= 90 ? 'exception' : parsePercent(serverInfo?.cpu_percent) >= 75 ? 'warning' : 'success'"
              />
              <div class="resource-sub app-muted">{{ Math.round(parsePercent(serverInfo?.cpu_percent)) }}%</div>
            </div>
            <div class="resource-item">
              <div class="resource-k app-muted">内存</div>
              <el-progress
                :percentage="Math.round(parsePercent(serverInfo?.memory_percent))"
                :status="parsePercent(serverInfo?.memory_percent) >= 90 ? 'exception' : parsePercent(serverInfo?.memory_percent) >= 75 ? 'warning' : 'success'"
              />
              <div class="resource-sub app-muted">
                {{ serverInfo?.memory_used || '-' }} / {{ serverInfo?.memory_total || '-' }}（{{ Math.round(parsePercent(serverInfo?.memory_percent)) }}%）
              </div>
            </div>
            <div class="resource-item">
              <div class="resource-k app-muted">磁盘</div>
              <el-progress
                :percentage="Math.round(parsePercent(serverInfo?.disk_percent))"
                :status="parsePercent(serverInfo?.disk_percent) >= 90 ? 'exception' : parsePercent(serverInfo?.disk_percent) >= 75 ? 'warning' : 'success'"
              />
              <div class="resource-sub app-muted">
                {{ serverInfo?.disk_used || '-' }} / {{ serverInfo?.disk_total || '-' }}（{{ Math.round(parsePercent(serverInfo?.disk_percent)) }}%）
              </div>
            </div>
          </div>

          <div class="divider"></div>

          <div class="block-title">容器</div>
          <el-descriptions border :column="2" size="small">
            <el-descriptions-item label="状态">{{ dockerStats?.status || '-' }}</el-descriptions-item>
            <el-descriptions-item label="容器名">{{ dockerStats?.container_name || '-' }}</el-descriptions-item>
            <el-descriptions-item label="运行时长">{{ dockerStats?.uptime || '-' }}</el-descriptions-item>
            <el-descriptions-item label="CPU">{{ dockerStats?.cpu_percent || '-' }}</el-descriptions-item>
            <el-descriptions-item label="内存">{{ dockerStats?.memory_usage || '-' }}</el-descriptions-item>
            <el-descriptions-item label="内存占比">{{ dockerStats?.memory_percent || '-' }}</el-descriptions-item>
          </el-descriptions>

          <div class="divider"></div>

          <div class="panel-head">
            <div class="head-left">
              <div class="head-text">
                <div class="panel-title">截图线程池</div>
                <div class="panel-sub app-muted">
                  活跃（有执行环境）{{ browserPoolActiveWorkers }} · 忙碌 {{ browserPoolBusyWorkers }} · 队列 {{ browserPoolQueueSize }}
                </div>
              </div>
            </div>
            <el-tag v-if="browserPoolStats?.server_time_cst" effect="light" type="info">{{ browserPoolStats.server_time_cst }}</el-tag>
          </div>

          <MetricGrid :items="browserPoolCards" :loading="loading" :min-width="120" />

          <div class="divider"></div>

          <div class="table-wrap">
            <el-table :data="browserPoolWorkers" size="small" border>
              <el-table-column prop="worker_id" label="Worker" width="90" />
              <el-table-column label="状态" width="90">
                <template #default="{ row }">
                  <el-tag :type="workerPoolStatusType(row)" effect="light">{{ workerPoolStatusLabel(row) }}</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="执行" width="90">
                <template #default="{ row }">
                  <el-tag :type="workerRunTagType(row)" effect="light">{{ workerRunLabel(row) }}</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="任务" width="120">
                <template #default="{ row }">
                  <span>{{ normalizeCount(row?.total_tasks) }}</span>
                  <span class="app-muted"> / </span>
                  <span :class="normalizeCount(row?.failed_tasks) ? 'err' : 'app-muted'">{{ normalizeCount(row?.failed_tasks) }}</span>
                </template>
              </el-table-column>
              <el-table-column prop="browser_use_count" label="复用" width="90" />
              <el-table-column prop="last_active_at" label="最近活跃" min-width="160" />
              <el-table-column prop="browser_created_at" label="环境创建" min-width="160" />
            </el-table>
          </div>
        </el-card>
      </el-col>

      <el-col :xs="24" :lg="12">
        <el-card shadow="never" class="panel" :body-style="{ padding: '16px' }">
          <div class="panel-head">
            <div class="head-left">
              <div class="head-icon tone-red">
                <el-icon><Tools /></el-icon>
              </div>
              <div class="head-text">
                <div class="panel-title">配置概览</div>
                <div class="panel-sub app-muted">定时 / 代理 / 并发</div>
              </div>
            </div>
          </div>

          <div class="config-grid">
            <div class="config-item">
              <div class="config-k app-muted">定时任务</div>
              <div class="config-v">
                <el-tag v-if="scheduleEnabled" type="success" effect="light">启用</el-tag>
                <el-tag v-else type="info" effect="light">关闭</el-tag>
                <span class="config-inline app-muted"> {{ scheduleTime }} / {{ scheduleBrowseType }}</span>
              </div>
              <div class="config-sub app-muted">日期：{{ scheduleWeekdaysDisplay || scheduleWeekdays || '-' }}</div>
            </div>

            <div class="config-item">
              <div class="config-k app-muted">代理</div>
              <div class="config-v">
                <el-tag v-if="proxyEnabled" type="success" effect="light">启用</el-tag>
                <el-tag v-else type="info" effect="light">关闭</el-tag>
                <span v-if="proxyEnabled && proxyApiUrl" class="config-inline app-muted">{{ proxyApiUrl }}</span>
              </div>
              <div class="config-sub app-muted">有效期：{{ proxyExpireMinutes || '-' }} 分钟</div>
            </div>

            <div class="config-item">
              <div class="config-k app-muted">并发</div>
              <div class="config-v">
                <span>全局 {{ maxConcurrentGlobal || '-' }}</span>
                <span class="config-split app-muted">/</span>
                <span>单账号 {{ maxConcurrentPerAccount || '-' }}</span>
                <span class="config-split app-muted">/</span>
                <span>截图 {{ maxScreenshotConcurrent || '-' }}</span>
              </div>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>
    </div>
  </div>
</template>

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

.report-hero {
  position: relative;
  overflow: hidden;
  border-radius: 18px;
  border: 1px solid rgba(17, 24, 39, 0.1);
  background: radial-gradient(circle at 10% 10%, rgba(59, 130, 246, 0.18), transparent 48%),
    radial-gradient(circle at 80% 0%, rgba(236, 72, 153, 0.16), transparent 45%),
    radial-gradient(circle at 90% 90%, rgba(16, 185, 129, 0.14), transparent 42%),
    rgba(255, 255, 255, 0.72);
  box-shadow: 0 14px 40px rgba(15, 23, 42, 0.08);
  backdrop-filter: saturate(180%) blur(12px);
  padding: 16px;
}

.hero-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.hero-main h2 {
  margin: 0;
  font-size: 19px;
  font-weight: 900;
  letter-spacing: 0.2px;
}

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

.hero-dot {
  opacity: 0.65;
}

.hero-actions {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}

.mobile-report {
  display: none;
}

.mobile-module-card {
  position: relative;
  overflow: hidden;
  border-radius: 14px;
  border: 1px solid rgba(17, 24, 39, 0.12);
  background: rgba(255, 255, 255, 0.9);
  box-shadow: var(--app-shadow-soft);
}

.mobile-module-card::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  height: 3px;
  background: var(--mobile-accent, #3b82f6);
}

.mobile-tone-blue {
  --mobile-accent: linear-gradient(90deg, #3b82f6, #06b6d4);
}

.mobile-tone-cyan {
  --mobile-accent: linear-gradient(90deg, #06b6d4, #3b82f6);
}

.mobile-tone-purple {
  --mobile-accent: linear-gradient(90deg, #8b5cf6, #ec4899);
}

.mobile-tone-orange {
  --mobile-accent: linear-gradient(90deg, #f59e0b, #f97316);
}

.mobile-tone-green {
  --mobile-accent: linear-gradient(90deg, #10b981, #22c55e);
}

.mobile-tone-red {
  --mobile-accent: linear-gradient(90deg, #ef4444, #f43f5e);
}

.mobile-module-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}

.mobile-module-title {
  font-size: 13px;
  font-weight: 900;
  color: #0f172a;
}

.mobile-module-desc {
  min-width: 0;
  max-width: 68%;
  font-size: 11px;
  line-height: 1.4;
  text-align: right;
}

.mobile-metrics {
  margin-top: 10px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.mobile-metric-item {
  padding: 8px 10px;
  border-radius: 10px;
  border: 1px solid rgba(17, 24, 39, 0.08);
  background: rgba(248, 250, 252, 0.9);
}

.mobile-metric-label {
  font-size: 11px;
  line-height: 1.35;
}

.mobile-metric-value {
  margin-top: 4px;
  font-size: 14px;
  font-weight: 800;
  color: #0f172a;
  line-height: 1.3;
  word-break: break-word;
}

.panel {
  border-radius: 18px;
  border: 1px solid rgba(17, 24, 39, 0.1);
  background: rgba(255, 255, 255, 0.72);
  box-shadow: var(--app-shadow);
  backdrop-filter: saturate(180%) blur(10px);
}

.panel-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.head-left {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

.head-text {
  min-width: 0;
}

.head-icon {
  width: 40px;
  height: 40px;
  border-radius: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(17, 24, 39, 0.08);
  flex: 0 0 auto;
}

.tone-blue {
  background: rgba(59, 130, 246, 0.12);
  color: #1d4ed8;
}

.tone-cyan {
  background: rgba(34, 211, 238, 0.12);
  color: #0369a1;
}

.tone-purple {
  background: rgba(139, 92, 246, 0.12);
  color: #6d28d9;
}

.tone-orange {
  background: rgba(245, 158, 11, 0.12);
  color: #b45309;
}

.tone-green {
  background: rgba(16, 185, 129, 0.12);
  color: #047857;
}

.tone-red {
  background: rgba(239, 68, 68, 0.12);
  color: #b91c1c;
}

.panel-title {
  font-size: 14px;
  font-weight: 900;
}

.panel-sub {
  margin-top: 4px;
  font-size: 12px;
  color: var(--app-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.metrics-block {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.block-title {
  font-size: 13px;
  font-weight: 900;
  letter-spacing: 0.2px;
}

.divider {
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(17, 24, 39, 0.12), transparent);
  margin: 14px 0;
}

.queue-tabs :deep(.el-tabs__header) {
  margin: 0 0 10px;
}

.tab-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.table-wrap {
  overflow-x: auto;
  border-radius: 10px;
  border: 1px solid var(--app-border);
  background: #fff;
}

.help {
  margin-top: 10px;
  font-size: 12px;
}

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

.resource-item {
  border: 1px solid rgba(17, 24, 39, 0.08);
  border-radius: 16px;
  padding: 12px;
  background: rgba(255, 255, 255, 0.7);
}

.resource-k {
  font-size: 12px;
  margin-bottom: 8px;
}

.resource-sub {
  margin-top: 8px;
  font-size: 12px;
}

.config-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
}

.config-item {
  border: 1px solid rgba(17, 24, 39, 0.08);
  border-radius: 16px;
  padding: 12px;
  background: rgba(255, 255, 255, 0.7);
}

.config-k {
  font-size: 12px;
}

.config-v {
  margin-top: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.config-inline {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.config-split {
  opacity: 0.65;
}

.config-sub {
  margin-top: 8px;
  font-size: 12px;
}

.err {
  color: #b91c1c;
}

:deep(.el-table) {
  --el-table-border-color: rgba(17, 24, 39, 0.08);
  --el-table-header-bg-color: rgba(246, 247, 251, 0.8);
}

:deep(.el-table th.el-table__cell) {
  background: rgba(246, 247, 251, 0.8);
}

@media (max-width: 768px) {
  .desktop-report {
    display: none;
  }

  .mobile-report {
    display: grid;
    gap: 10px;
  }

  .report-hero {
    border-radius: 14px;
    padding: 12px;
  }

  .hero-main h2 {
    font-size: 17px;
  }

  .hero-meta {
    margin-top: 4px;
    gap: 6px;
    font-size: 11px;
  }

  .hero-overview-grid {
    display: none;
  }

  .resource-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 420px) {
  .mobile-metrics {
    grid-template-columns: 1fr;
  }

  .mobile-module-desc {
    max-width: 62%;
  }
}
</style>
