<template>
  <div class="dashboard-page">
    <!-- 统计卡片 第1行 -->
    <el-row :gutter="16" class="stat-row">
      <el-col :span="6">
        <el-card shadow="hover">
          <div class="stat-card">
            <div class="stat-label">
              在线机床数
              <el-tooltip content="当前网络连通的机床数量占所有已启用机床总数的比例。系统通过Ping检测机床网络，连通即为在线。" placement="top">
                <span class="info-icon">ⓘ</span>
              </el-tooltip>
            </div>
            <div class="stat-value">{{ summary.onlineCount }}<span class="stat-unit"> / {{ summary.totalMachines }}</span></div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover">
          <div class="stat-card">
            <div class="stat-label">
              今日总产量
              <el-tooltip content="今日所有机床加工完成的零件总数，包含手工修正后的数值。系统以NC程序名区分零件，切换程序时自动结算上一段产量。" placement="top">
                <span class="info-icon">ⓘ</span>
              </el-tooltip>
            </div>
            <div class="stat-value">{{ summary.todayProduction?.toLocaleString() }}</div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover">
          <div class="stat-card">
            <div class="stat-label">
              采集服务
              <el-tooltip content="数据采集服务的运行状态。服务每30秒向系统上报一次心跳，超过90秒未上报则判定为停止。" placement="top">
                <span class="info-icon">ⓘ</span>
              </el-tooltip>
            </div>
            <div class="stat-value">
              <el-tag :type="collectorStatus.status === 'running' ? 'success' : 'danger'" size="small">
                {{ collectorStatus.status === 'running' ? '运行中' : '已停止' }}
              </el-tag>
            </div>
            <div class="stat-sub" v-if="collectorStatus.status === 'running'">运行 {{ formatUptime(collectorStatus.uptimeSeconds) }}</div>
          </div>
          <div class="collector-actions">
            <el-button v-if="collectorStatus.status !== 'running'" size="small" type="success" :loading="startLoading" @click="startCollector">启动采集</el-button>
            <el-button v-if="collectorStatus.status === 'running'" size="small" type="danger" :loading="stopLoading" @click="stopCollector">停止采集</el-button>
            <el-button size="small" type="warning" :loading="refreshLoading" @click="refreshCollectorConfig">刷新配置</el-button>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover">
          <div class="stat-card">
            <div class="stat-label">
              活跃告警
              <el-tooltip content="当前未处理的告警总数。包括：采集失败、数据缺失、设备离线、发现未注册设备。" placement="top">
                <span class="info-icon">ⓘ</span>
              </el-tooltip>
            </div>
            <div class="stat-value alert-value" @click="$router.push(isMock ? '/mock/alert' : '/alert')">
              {{ summary.activeAlerts }}
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 统计卡片 第2行 -->
    <el-row :gutter="16" class="stat-row">
      <el-col :span="6">
        <el-card shadow="hover">
          <div class="stat-card">
            <div class="stat-label">
              采集成功率
              <el-tooltip content="今日采集成功的次数占总采集次数的百分比。每次采集一个地址算一次，一个地址可能包含多台机床的数据。" placement="top">
                <span class="info-icon">ⓘ</span>
              </el-tooltip>
            </div>
            <div class="stat-value">{{ summary.collectSuccessRate }}<span class="stat-unit">%</span></div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover">
          <div class="stat-card">
            <div class="stat-label">
              今日切削总时
              <el-tooltip content="今日所有机床实际切削加工的时间总和（单位：小时）。仅统计刀具接触工件的切削时间，不含空转和待机时间。" placement="top">
                <span class="info-icon">ⓘ</span>
              </el-tooltip>
            </div>
            <div class="stat-value">{{ summary.todayCuttingTime }}<span class="stat-unit"> h</span></div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover">
          <div class="stat-card">
            <div class="stat-label">
              运行机床
              <el-tooltip content="当前正在执行加工程序的机床数量。与「在线」的区别：在线表示网络连通，运行表示正在加工零件。" placement="top">
                <span class="info-icon">ⓘ</span>
              </el-tooltip>
            </div>
            <div class="stat-value">{{ summary.runningMachines }}<span class="stat-unit"> 台</span></div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover">
          <div class="stat-card">
            <div class="stat-label">
              数据缺失
              <el-tooltip content="网络连通但未能成功采集到数据的机床数量。这些机床的产量在报表中显示为「-」而不是0，不计入日产量汇总。" placement="top">
                <span class="info-icon">ⓘ</span>
              </el-tooltip>
            </div>
            <div class="stat-value" :class="{ 'alert-value': summary.dataMissingMachines > 0 }">{{ summary.dataMissingMachines }}<span class="stat-unit"> 台</span></div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 图表区：产量趋势 + 车间对比 -->
    <el-row :gutter="16" class="chart-row">
      <el-col :span="12">
        <el-card shadow="hover">
          <template #header><span class="card-title">产量趋势（近7天）<el-tooltip content="最近7天每天的零件总产量变化趋势。" placement="top"><span class="info-icon">ⓘ</span></el-tooltip></span></template>
          <div ref="trendChartRef" style="height: 260px"></div>
        </el-card>
      </el-col>
      <el-col :span="12">
        <el-card shadow="hover">
          <template #header>
            <div class="card-header">
              <span class="card-title">车间平均单机产量（{{ workshopDateLabel }}）<el-tooltip placement="top">
                <template #content>
                  <div style="max-width: 360px; line-height: 1.6">
                    <b>统计规则：</b>车间总产量 ÷ 车间机床数 ÷ 天数<br/><br/>
                    <b>数据来源：</b>系统每日凌晨1:00自动执行日终汇总，将每台机床当天所有产量分段按程序名合并计算，生成日产量记录。多天范围取日均单机产量。<br/><br/>
                    <b>产量计算：</b>以NC程序名标识零件，程序切换时自动结算上一段产量。同程序多次出现时分段记录、日汇总合并。含手工修正值。
                  </div>
                </template>
                <span class="info-icon">ⓘ</span>
              </el-tooltip></span>
              <div class="date-filter">
                <el-radio-group v-model="workshopDateType" size="small" @change="onWorkshopDateChange">
                  <el-radio-button value="today">今日</el-radio-button>
                  <el-radio-button value="yesterday">昨日</el-radio-button>
                  <el-radio-button value="last3">近3天</el-radio-button>
                  <el-radio-button value="last7">近7天</el-radio-button>
                  <el-radio-button value="custom">自定义</el-radio-button>
                </el-radio-group>
                <el-date-picker v-if="workshopDateType === 'custom'" v-model="workshopDateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" size="small" value-format="YYYY-MM-DD" :disabled-date="(d: Date) => d > new Date()" style="margin-left: 8px" @change="loadWorkshopData" />
              </div>
            </div>
          </template>
          <div ref="workshopChartRef" style="height: 260px"></div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 信息区：机床状态分布 + 最新告警 -->
    <el-row :gutter="16" class="info-row">
      <el-col :span="8">
        <el-card shadow="hover">
          <template #header><span class="card-title">机床状态分布<el-tooltip content="在线：网络Ping检测通过；离线：网络Ping检测不通；停用：已手动关闭的机床。" placement="top"><span class="info-icon">ⓘ</span></el-tooltip></span></template>
          <div ref="statusPieRef" style="height: 260px"></div>
        </el-card>
      </el-col>
      <el-col :span="16">
        <el-card shadow="hover">
          <template #header>
            <div class="card-header">
              <span class="card-title">最新告警<el-tooltip content="最近5条未处理的告警记录，按时间倒序排列。类型包括：采集失败、数据缺失、设备离线、发现未注册设备。" placement="top"><span class="info-icon">ⓘ</span></el-tooltip></span>
              <el-button link type="primary" @click="$router.push(isMock ? '/mock/alert' : '/alert')">查看全部</el-button>
            </div>
          </template>
          <el-table :data="recentAlerts" stripe size="small" style="width: 100%">
            <el-table-column prop="createdAt" label="时间" width="160" />
            <el-table-column label="类型" width="100" align="center">
              <template #default="{ row }">
                <el-tag :type="alertTypeTag(row.alertType)" size="small">{{ alertTypeLabel(row.alertType) }}</el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="machineName" label="机床" width="100" />
            <el-table-column prop="title" label="告警内容" show-overflow-tooltip />
            <el-table-column label="状态" width="80" align="center">
              <template #default="{ row }">
                <el-tag :type="row.isResolved ? 'success' : 'danger'" size="small">{{ row.isResolved ? '已处理' : '未处理' }}</el-tag>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>
    </el-row>

    <!-- 排行表格 -->
    <el-row :gutter="16" class="rank-row">
      <el-col :span="12">
        <el-card shadow="hover">
          <template #header>
            <div class="card-header">
              <span class="card-title">机床产量排行 TOP10<el-tooltip content="单台机床加工零件数由高到低排列，同时显示当前正在执行的程序名。" placement="top"><span class="info-icon">ⓘ</span></el-tooltip></span>
              <div class="date-filter">
                <el-radio-group v-model="machineDateType" size="small" @change="onMachineDateChange">
                  <el-radio-button value="today">今日</el-radio-button>
                  <el-radio-button value="yesterday">昨日</el-radio-button>
                  <el-radio-button value="last3">近3天</el-radio-button>
                  <el-radio-button value="last7">近7天</el-radio-button>
                  <el-radio-button value="custom">自定义</el-radio-button>
                </el-radio-group>
                <el-date-picker v-if="machineDateType === 'custom'" v-model="machineDateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" size="small" value-format="YYYY-MM-DD" :disabled-date="(d: Date) => d > new Date()" style="margin-left: 8px" @change="loadMachineRankData" />
              </div>
            </div>
          </template>
          <el-table :data="machineRank" stripe size="small" style="width: 100%">
            <el-table-column prop="rank" label="排名" width="60" align="center" />
            <el-table-column label="机床名称" width="120">
              <template #default="{ row }">
                <router-link :to="isMock ? '/mock/machine/' + row.machineId : '/machine/' + row.machineId" class="machine-link">{{ row.machineName }}</router-link>
              </template>
            </el-table-column>
            <el-table-column prop="program" label="当前程序" show-overflow-tooltip />
            <el-table-column prop="quantity" label="产量" width="80" align="center" />
            <el-table-column label="状态" width="70" align="center">
              <template #default="{ row }">
                <el-tag :type="row.status === 1 ? 'success' : 'danger'" size="small">{{ row.status === 1 ? '在线' : '离线' }}</el-tag>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>
      <el-col :span="12">
        <el-card shadow="hover">
          <template #header>
            <div class="card-header">
              <span class="card-title">工人产量排行 TOP10<el-tooltip content="工人所绑定的所有机床产量合计，由高到低排列。" placement="top"><span class="info-icon">ⓘ</span></el-tooltip></span>
              <div class="date-filter">
                <el-radio-group v-model="workerDateType" size="small" @change="onWorkerDateChange">
                  <el-radio-button value="today">今日</el-radio-button>
                  <el-radio-button value="yesterday">昨日</el-radio-button>
                  <el-radio-button value="last3">近3天</el-radio-button>
                  <el-radio-button value="last7">近7天</el-radio-button>
                  <el-radio-button value="custom">自定义</el-radio-button>
                </el-radio-group>
                <el-date-picker v-if="workerDateType === 'custom'" v-model="workerDateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" size="small" value-format="YYYY-MM-DD" :disabled-date="(d: Date) => d > new Date()" style="margin-left: 8px" @change="loadWorkerRankData" />
              </div>
            </div>
          </template>
          <el-table :data="workerRank" stripe size="small" style="width: 100%">
            <el-table-column prop="rank" label="排名" width="60" align="center" />
            <el-table-column prop="workerName" label="工人姓名" />
            <el-table-column prop="machineCount" label="绑定机床" width="100" align="center" />
            <el-table-column prop="totalQuantity" label="总产量" width="100" align="center" />
          </el-table>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import request from '@/utils/request'
import { useMockMode } from '@/composables/useMockMode'
import echarts from '@/utils/echarts'
import type { ECharts } from 'echarts/core'
import type { ApiResponse, DashboardSummary, CollectorStatus, MachineRankRow, WorkerRankRow, DashboardTrendItem, WorkshopProduction, MachineStatusDistribution, RecentAlert } from '@/types'

const { isMock } = useMockMode()

const summary = ref<DashboardSummary>({ onlineCount: 0, totalMachines: 0, todayProduction: 0, activeAlerts: 0, collectSuccessRate: 0, todayCuttingTime: 0, runningMachines: 0, dataMissingMachines: 0 })
const collectorStatus = ref<CollectorStatus>({ status: 'stopped', uptimeSeconds: 0 })
const machineRank = ref<MachineRankRow[]>([])
const workerRank = ref<WorkerRankRow[]>([])
const trendData = ref<DashboardTrendItem[]>([])
const workshopData = ref<WorkshopProduction[]>([])
const statusDist = ref<MachineStatusDistribution>({ online: 0, offline: 0, disabled: 0 })
const recentAlerts = ref<RecentAlert[]>([])

const startLoading = ref(false)
const stopLoading = ref(false)
const refreshLoading = ref(false)

// 日期筛选状态
type DateType = 'today' | 'yesterday' | 'last3' | 'last7' | 'custom'
const workshopDateType = ref<DateType>('today')
const workshopDateRange = ref<[string, string]>()
const machineDateType = ref<DateType>('today')
const machineDateRange = ref<[string, string]>()
const workerDateType = ref<DateType>('today')
const workerDateRange = ref<[string, string]>()

const dateLabels: Record<DateType, string> = { today: '今日', yesterday: '昨日', last3: '近3天', last7: '近7天', custom: '自定义' }
const workshopDateLabel = computed(() => dateLabels[workshopDateType.value])
const machineDateLabel = computed(() => dateLabels[machineDateType.value])
const workerDateLabel = computed(() => dateLabels[workerDateType.value])

// 车间平均单机产量的日均单位
const workshopDays = computed(() => {
  const { startDate, endDate } = getDateRange(workshopDateType.value, workshopDateRange.value)
  return Math.max(1, Math.round((new Date(endDate).getTime() - new Date(startDate).getTime()) / 86400000) + 1)
})
const workshopUnit = computed(() => workshopDays.value > 1 ? '件/台/天' : '件/台')
const workshopUnitLabel = computed(() => workshopDays.value > 1 ? '日均' : '平均')

function getDateRange(type: DateType, customRange?: [string, string]): { startDate: string; endDate: string } {
  const today = new Date()
  const fmt = (d: Date) => d.toISOString().slice(0, 10)
  const endDate = fmt(today)
  switch (type) {
    case 'today': return { startDate: endDate, endDate }
    case 'yesterday': { const y = new Date(today); y.setDate(y.getDate() - 1); const ys = fmt(y); return { startDate: ys, endDate: ys } }
    case 'last3': { const d = new Date(today); d.setDate(d.getDate() - 2); return { startDate: fmt(d), endDate } }
    case 'last7': { const d = new Date(today); d.setDate(d.getDate() - 6); return { startDate: fmt(d), endDate } }
    case 'custom': return { startDate: customRange?.[0] || endDate, endDate: customRange?.[1] || endDate }
  }
}

function onWorkshopDateChange() { workshopDateType.value !== 'custom' ? loadWorkshopData() : undefined }
function onMachineDateChange() { machineDateType.value !== 'custom' ? loadMachineRankData() : undefined }
function onWorkerDateChange() { workerDateType.value !== 'custom' ? loadWorkerRankData() : undefined }


// ECharts refs
const trendChartRef = ref<HTMLElement>()
const workshopChartRef = ref<HTMLElement>()
const statusPieRef = ref<HTMLElement>()
let trendChart: ECharts | null = null
let workshopChart: ECharts | null = null
let statusPie: ECharts | null = null

async function startCollector() {
  if (startLoading.value) return
  startLoading.value = true
  try { await request.post('/admin/collector/start'); ElMessage.success('采集服务已启动'); await loadData() } catch { /* request拦截器已显示错误 */ } finally { startLoading.value = false }
}

async function stopCollector() {
  if (stopLoading.value) return
  stopLoading.value = true
  try { await request.post('/admin/collector/stop'); ElMessage.success('采集服务已停止'); await loadData() } catch { /* request拦截器已显示错误 */ } finally { stopLoading.value = false }
}

async function refreshCollectorConfig() {
  if (refreshLoading.value) return
  refreshLoading.value = true
  try { await request.post('/admin/collector/refresh'); ElMessage.success('配置已刷新'); await loadData() } catch { /* request拦截器已显示错误 */ } finally { refreshLoading.value = false }
}

function formatUptime(seconds: number): string {
  if (!seconds) return '-'
  const days = Math.floor(seconds / 86400)
  const hours = Math.floor((seconds % 86400) / 3600)
  if (days > 0) return `${days}天${hours}时`
  return `${hours}时`
}

function alertTypeTag(type: string): string {
  const map: Record<string, string> = { collect_fail: 'danger', data_missing: 'warning', device_offline: 'danger', new_device: 'info' }
  return map[type] || 'warning'
}

function alertTypeLabel(type: string): string {
  const map: Record<string, string> = { collect_fail: '采集失败', data_missing: '数据缺失', device_offline: '设备离线', new_device: '新设备' }
  return map[type] || type
}

function initWorkshopChart() {
  if (workshopChartRef.value && workshopData.value.length) {
    const unit = workshopUnit.value
    const unitLabel = workshopUnitLabel.value
    workshopChart = echarts.init(workshopChartRef.value)
    workshopChart.setOption({
      tooltip: {
        trigger: 'axis',
        formatter: (params: any) => {
          const d = workshopData.value[params[0].dataIndex]
          return `${d.workshopName}<br/>${unitLabel}产量: ${params[0].value} ${unit}<br/>总产量: ${d.quantity} 件<br/>机床数: ${d.machineCount} 台`
        },
      },
      grid: { left: 60, right: 20, top: 20, bottom: 30 },
      xAxis: { type: 'category', data: workshopData.value.map(i => i.workshopName), axisLabel: { fontSize: 12 } },
      yAxis: { type: 'value', name: unit, axisLabel: { fontSize: 12 } },
      series: [{
        type: 'bar', data: workshopData.value.map(i => i.avgQuantity),
        itemStyle: { color: '#67C23A', borderRadius: [4, 4, 0, 0] }, barWidth: '40%',
        label: { show: true, position: 'top', formatter: `{c} ${unit}`, fontSize: 12 },
      }],
    })
  }
}

function initCharts() {
  // 产量趋势折线图
  if (trendChartRef.value && trendData.value.length) {
    trendChart = echarts.init(trendChartRef.value)
    trendChart.setOption({
      tooltip: { trigger: 'axis' },
      grid: { left: 50, right: 20, top: 20, bottom: 30 },
      xAxis: { type: 'category', data: trendData.value.map(i => i.date.slice(5)), axisLabel: { fontSize: 12 } },
      yAxis: { type: 'value', axisLabel: { fontSize: 12 } },
      series: [{
        type: 'line', data: trendData.value.map(i => i.quantity), smooth: true,
        areaStyle: { opacity: 0.15 }, itemStyle: { color: '#409EFF' },
      }],
    })
  }

  // 车间平均单机产量柱状图
  initWorkshopChart()

  // 机床状态饼图
  if (statusPieRef.value) {
    const d = statusDist.value
    statusPie = echarts.init(statusPieRef.value)
    statusPie.setOption({
      tooltip: { trigger: 'item', formatter: '{b}: {c}台 ({d}%)' },
      legend: { bottom: 0, itemWidth: 12, itemHeight: 12, textStyle: { fontSize: 12 } },
      series: [{
        type: 'pie', radius: ['40%', '65%'], center: ['50%', '45%'],
        label: { show: true, formatter: '{b}\n{c}台', fontSize: 12 },
        data: [
          { value: d.online, name: '在线', itemStyle: { color: '#67C23A' } },
          { value: d.offline, name: '离线', itemStyle: { color: '#909399' } },
          { value: d.disabled, name: '停用', itemStyle: { color: '#F56C6C' } },
        ],
      }],
    })
  }
}

function disposeCharts() {
  trendChart?.dispose()
  workshopChart?.dispose()
  statusPie?.dispose()
  trendChart = null
  workshopChart = null
  statusPie = null
}

async function loadWorkshopData() {
  try {
    const { startDate, endDate } = getDateRange(workshopDateType.value, workshopDateRange.value)
    const res = await request.get<{ items: WorkshopProduction[] }>('/admin/dashboard/workshop-production', { params: { startDate, endDate } })
    workshopData.value = res.data?.items || []
    workshopChart?.dispose(); workshopChart = null
    await nextTick(); initWorkshopChart()
  } catch { /* */ }
}

async function loadMachineRankData() {
  try {
    const { startDate, endDate } = getDateRange(machineDateType.value, machineDateRange.value)
    const res: ApiResponse<{ items: MachineRankRow[] }> = await request.get('/admin/dashboard/machine-rank', { params: { startDate, endDate } })
    machineRank.value = res.data?.items || []
  } catch { /* */ }
}

async function loadWorkerRankData() {
  try {
    const { startDate, endDate } = getDateRange(workerDateType.value, workerDateRange.value)
    const res: ApiResponse<{ items: WorkerRankRow[] }> = await request.get('/admin/dashboard/worker-rank', { params: { startDate, endDate } })
    workerRank.value = res.data?.items || []
  } catch { /* */ }
}

async function loadData() {
  try {
    const [summaryRes, collectorRes, trendRes, statusRes, alertsRes] = await Promise.all([
      request.get<DashboardSummary>('/admin/dashboard/summary'),
      request.get<CollectorStatus>('/admin/collector/status'),
      request.get<{ items: DashboardTrendItem[] }>('/admin/dashboard/trend'),
      request.get<MachineStatusDistribution>('/admin/dashboard/machine-status-distribution'),
      request.get<{ items: RecentAlert[] }>('/admin/dashboard/recent-alerts'),
    ])
    summary.value = summaryRes.data || summary.value
    collectorStatus.value = collectorRes.data || collectorStatus.value
    trendData.value = trendRes.data?.items || []
    statusDist.value = statusRes.data || statusDist.value
    recentAlerts.value = alertsRes.data?.items || []

    disposeCharts()
    await nextTick()
    initCharts()

    // 日期筛选的三个区域独立加载
    await Promise.all([loadWorkshopData(), loadMachineRankData(), loadWorkerRankData()])
  } catch {
    // 保持容错
  }
}

onMounted(() => {
  loadData()
})

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

<style scoped lang="scss">
.dashboard-page {
  .stat-row {
    margin-bottom: 16px;

    .el-card { height: 100%; }

    .stat-card {
      text-align: center;
      padding: 10px 0;

      .stat-label {
        font-size: 14px;
        color: #909399;
        margin-bottom: 8px;

        .info-icon {
          margin-left: 2px;
          font-size: 13px;
          color: #c0c4cc;
          cursor: help;
          vertical-align: middle;

          &:hover {
            color: #409EFF;
          }
        }
      }

      .stat-value {
        font-size: 28px;
        font-weight: bold;
        color: #303133;

        .stat-unit {
          font-size: 14px;
          font-weight: normal;
          color: #909399;
        }
      }

      .stat-sub {
        font-size: 12px;
        color: #909399;
        margin-top: 4px;
      }

      .alert-value {
        color: #e6a23c;
        cursor: pointer;
      }
    }

    .collector-actions {
      margin-top: 12px;
      display: flex;
      gap: 8px;
      justify-content: flex-start;
      flex-wrap: wrap;
    }
  }

  .chart-row,
  .info-row,
  .rank-row {
    margin-bottom: 16px;
  }

  .card-title {
    font-size: 15px;
    font-weight: 500;

    .info-icon {
      margin-left: 4px;
      font-size: 14px;
      color: #b0b5bd;
      cursor: help;

      &:hover {
        color: #409EFF;
      }
    }
  }

  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;

    .card-sub {
      font-size: 12px;
      color: #909399;
    }

    .date-filter {
      display: flex;
      align-items: center;
      flex-wrap: wrap;
    }
  }

  .machine-link {
    color: var(--el-color-primary);
    cursor: pointer;
    text-decoration: none;
  }
}
</style>
