<template>
  <div class="app-container">
    <!-- 页面标题 -->
    <div class="page-header">
      <h2><i class="el-icon-data-analysis"></i> SKU生命周期整体看板</h2>
      <p class="page-desc">全局SKU生命周期分析概览，包含关键指标和趋势分析</p>
    </div>

    <div class="upload-toolbar">
      <div class="toolbar-left">
        <el-upload
          ref="upload"
          class="toolbar-upload"
          :limit="1"
          accept=".xlsx,.xls,.csv"
          :http-request="customUpload"
          :disabled="upload.isUploading"
          :on-change="handleFileChange"
          :before-upload="beforeUpload"
          :auto-upload="false"
          :show-file-list="false"
        >
          <el-button plain>上传文件</el-button>
        </el-upload>
        <el-button :loading="upload.isUploading" type="primary" @click="submitUpload">开始分析</el-button>
        <el-button type="success" :disabled="!hasResults" @click="exportResults">导出分析</el-button>
      </div>
      <div class="toolbar-status" v-if="upload.fileName">已上传：{{ upload.fileName }}</div>
      <div class="toolbar-status" v-else-if="upload.pendingFileName">已选择：{{ upload.pendingFileName }}</div>
      <div class="toolbar-status muted" v-else>未上传</div>
    </div>

    <!-- 关键指标卡片 -->
    <el-row :gutter="20" class="mb-20">
      <el-col :xs="24" :sm="12" :md="8" :lg="4">
        <el-card class="stat-card">
          <div class="stat-content">
            <div class="stat-info">
              <p class="stat-label">订单总数（估）</p>
              <p class="stat-value">{{ orderCount }}</p>
              <p class="stat-desc">按销量近似</p>
            </div>
            <div class="stat-icon stat-icon-purple">
              <i class="el-icon-s-order"></i>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :xs="24" :sm="12" :md="8" :lg="4">
        <el-card class="stat-card">
          <div class="stat-content">
            <div class="stat-info">
              <p class="stat-label">SKU总数</p>
              <p class="stat-value">{{ skuCount }}</p>
              <p class="stat-desc stat-desc-success">分析后</p>
            </div>
            <div class="stat-icon stat-icon-blue">
              <i class="el-icon-box"></i>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :xs="24" :sm="12" :md="8" :lg="4">
        <el-card class="stat-card">
          <div class="stat-content">
            <div class="stat-info">
              <p class="stat-label">商品总数</p>
              <p class="stat-value">{{ productCount }}</p>
              <p class="stat-desc">按详情名称去重</p>
            </div>
            <div class="stat-icon stat-icon-teal">
              <i class="el-icon-s-goods"></i>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :xs="24" :sm="12" :md="8" :lg="4">
        <el-card class="stat-card">
          <div class="stat-content">
            <div class="stat-info">
              <p class="stat-label">完整生命周期SKU</p>
              <p class="stat-value">{{ completeCount }}</p>
              <p class="stat-desc stat-desc-success">完整占比 {{ completeRatio }}%</p>
            </div>
            <div class="stat-icon stat-icon-green">
              <i class="el-icon-success"></i>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :xs="24" :sm="12" :md="8" :lg="4">
        <el-card class="stat-card">
          <div class="stat-content">
            <div class="stat-info">
              <p class="stat-label">平均生命周期时长（天）</p>
              <p class="stat-value">{{ avgLifecycleDays }}</p>
              <p class="stat-desc">仅计算完整SKU</p>
            </div>
            <div class="stat-icon stat-icon-yellow">
              <i class="el-icon-time"></i>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :xs="24" :sm="12" :md="8" :lg="4">
        <el-card class="stat-card">
          <div class="stat-content">
            <div class="stat-info">
              <p class="stat-label">数据不足SKU</p>
              <p class="stat-value">{{ insufficientCount }}</p>
              <p class="stat-desc">天数/字段不足</p>
            </div>
            <div class="stat-icon stat-icon-red">
              <i class="el-icon-warning"></i>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 阶段分布与关键指标图 -->
    <el-row :gutter="20" class="mb-20">
      <el-col :xs="24" :sm="24" :md="12" :lg="12">
        <el-card>
          <div slot="header">
            <span><i class="el-icon-pie-chart"></i> SKU生命周期阶段分布</span>
            <span class="header-desc">按数量占比</span>
          </div>
          <div ref="stageDistributionChart" style="height: 400px"></div>
        </el-card>
      </el-col>
      <el-col :xs="24" :sm="24" :md="12" :lg="12">
        <el-card>
          <div slot="header">
            <span><i class="el-icon-data-line"></i> 各阶段关键指标对比</span>
            <span class="header-desc">销售额/销量（估）</span>
          </div>
          <div ref="stageMetricsChart" style="height: 400px"></div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 阶段平均时长与转化漏斗 -->
    <el-row :gutter="20" class="mb-20">
      <el-col :xs="24" :sm="24" :md="12" :lg="12">
        <el-card>
          <div slot="header">
            <span><i class="el-icon-s-marketing"></i> 阶段平均时长（天）</span>
            <span class="header-desc">完整SKU统计</span>
          </div>
          <div ref="avgDurationChart" style="height: 400px"></div>
        </el-card>
      </el-col>
      <el-col :xs="24" :sm="24" :md="12" :lg="12">
        <el-card>
          <div slot="header">
            <span><i class="el-icon-s-data"></i> 阶段转化漏斗</span>
            <span class="header-desc">引入→成长→成熟→衰退</span>
          </div>
          <div ref="funnelChart" style="height: 400px"></div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import { analyzeFile, getResults } from '@/api/lifecycle'
import { getToken } from '@/utils/auth'
import * as echarts from 'echarts'
require('echarts/theme/macarons')

const CACHE_KEY_RESULTS = 'analysis_results'

function loadCachedResults() {
  try {
    const rawResults = localStorage.getItem(CACHE_KEY_RESULTS)
    return rawResults ? JSON.parse(rawResults) : {}
  } catch (e) {
    return {}
  }
}

export default {
  name: 'LifecycleOverview',
  data() {
    return {
      // 图表实例
      stageDistributionChart: null,
      stageMetricsChart: null,
      avgDurationChart: null,
      funnelChart: null,
      // 数据
      results: loadCachedResults(),
      // 计算属性数据
      orderCount: 0,
      skuCount: 0,
      productCount: 0,
      completeCount: 0,
      completeRatio: 0,
      avgLifecycleDays: 0,
      insufficientCount: 0,
      // 文件上传相关
      upload: {
        // 是否显示弹出层
        open: false,
        // 弹出层标题
        title: '',
        // 是否禁用上传
        isUploading: false,
        // 是否更新已经存在的文件
        updateSupport: 0,
        // 设置上传的请求头部
        headers: { Authorization: 'Bearer ' + getToken() },
        // 上传的地址
        url: process.env.VUE_APP_PYTHON_API + '/api/sku-lifecycle/upload',
        // 文件名称
        fileName: '',
        // 已选择文件名称
        pendingFileName: '',
        // 是否忽略文件选择改变
        ignoreFileChange: false,
      }
    }
  },
  computed: {
    hasResults() {
      return Object.keys(this.results || {}).length > 0
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.initCharts()
      if (this.hasResults) {
        this.calculateMetrics()
        this.renderCharts()
      } else {
        this.getList()
      }
    })
    // 监听窗口大小变化
    window.addEventListener('resize', this.handleResize)
  },
  beforeDestroy() {
    // 销毁图表实例
    if (this.stageDistributionChart) {
      this.stageDistributionChart.dispose()
    }
    if (this.stageMetricsChart) {
      this.stageMetricsChart.dispose()
    }
    if (this.avgDurationChart) {
      this.avgDurationChart.dispose()
    }
    if (this.funnelChart) {
      this.funnelChart.dispose()
    }
    window.removeEventListener('resize', this.handleResize)
  },
  methods: {
    /** 文件选择改变处理 */
    handleFileChange(file, fileList) {
      if (this.upload.ignoreFileChange) return
      if (!fileList || fileList.length === 0) return
      if (!file || !file.raw) return

      this.upload.pendingFileName = file.name
      this.upload.fileName = ''
    },
    /** 文件上传前的校验 */
    beforeUpload(file) {
      const isExcel = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
                      file.type === 'application/vnd.ms-excel' ||
                      file.type === 'text/csv' ||
                      file.name.endsWith('.xlsx') ||
                      file.name.endsWith('.xls') ||
                      file.name.endsWith('.csv')
      const isLt500M = file.size / 1024 / 1024 < 500

      if (!isExcel) {
        this.$modal.msgError('上传文件只能是 xlsx/xls/csv 格式!')
        return false
      }
      if (!isLt500M) {
        this.$modal.msgError('上传文件大小不能超过 500MB!')
        return false
      }
      return true
    },
    /** 文件上传中处理 */
    handleFileUploadProgress(event, file, fileList) {
      this.upload.isUploading = true
    },
    /** 自定义上传方法 */
    customUpload(options) {
      const file = options.file
      this.upload.isUploading = true
      analyzeFile(file).then(response => {
        this.upload.isUploading = false
        if (response && response.success) {
          this.$modal.msgSuccess('文件上传并分析成功')
          this.upload.fileName = this.upload.pendingFileName || file.name
          this.upload.pendingFileName = ''
          this.setResults(response.data || {})
          options.onSuccess(response)
        } else {
          const message = (response && response.message) || '分析失败'
          this.$modal.msgError(message)
          options.onError(new Error(message))
        }
      }).catch(error => {
        this.upload.isUploading = false
        const errorMsg = (error && error.response && error.response.data && error.response.data.message) || error.message || '文件上传失败，请重试'
        this.$modal.msgError(errorMsg)
        options.onError(error)
      }).finally(() => {
        this.resetUploaderSelection()
      })
    },
    /** 提交上传文件 */
    submitUpload() {
      const fileList = this.$refs.upload.uploadFiles
      if (!fileList || fileList.length === 0) {
        this.$modal.msgError('请选择要上传的文件')
        return
      }
      this.$refs.upload.submit()
    },
    /** 重置上传 */
    resetUpload() {
      if (this.$refs.upload) this.$refs.upload.clearFiles()
      if (this.$refs.toolbarUpload) this.$refs.toolbarUpload.clearFiles()
    },
    resetUploaderSelection() {
      if (!this.$refs.upload) return
      this.upload.ignoreFileChange = true
      this.$refs.upload.clearFiles()
      this.$nextTick(() => {
        this.upload.ignoreFileChange = false
      })
    },
    persistResults() {
      try {
        localStorage.setItem(CACHE_KEY_RESULTS, JSON.stringify(this.results || {}))
      } catch (e) {}
    },
    setResults(results) {
      this.results = results || {}
      this.persistResults()
      this.calculateMetrics()
      this.$nextTick(() => {
        this.renderCharts()
      })
    },
    /** 获取生命周期分析结果 */
    getList() {
      getResults().then(response => {
        if (response && response.success && response.data) {
          this.setResults(response.data || {})
        }
      }).catch(() => {
        if (!this.hasResults) {
          this.setResults({})
        }
      })
    },
    /** 计算关键指标 */
    calculateMetrics() {
      // 仅取真实SKU结果，排除聚合概要 _analysis_summary_
      const entries = Object.entries(this.results || {})
      const resultsArr = entries.filter(([k]) => k !== '_analysis_summary_').map(([, v]) => v)

      this.skuCount = resultsArr.length

      // 商品总数（按详情名称去重）
      const names = new Set()
      resultsArr.forEach(r => {
        if (r?.details) names.add(r.details)
      })
      this.productCount = names.size

      // 完整生命周期SKU
      this.completeCount = resultsArr.filter(r => !!r?.is_complete).length
      this.completeRatio = this.skuCount ? ((this.completeCount / this.skuCount) * 100).toFixed(1) : 0

      // 平均生命周期时长（仅计算完整SKU）
      const completeList = resultsArr.filter(r => !!r?.is_complete)
      if (completeList.length > 0) {
        const total = completeList.reduce((s, r) => s + this.getLifecycleDays(r), 0)
        this.avgLifecycleDays = Math.round(total / completeList.length)
      } else {
        this.avgLifecycleDays = 0
      }

      // 数据不足SKU
      this.insufficientCount = resultsArr.filter(r => this.isInsufficient(r)).length

      // 订单总数（按销量近似）
      this.orderCount = resultsArr.reduce((s, r) => s + this.sumArray(r?.quantity_series || []), 0)
    },
    /** 初始化图表 */
    initCharts() {
      if (this.$refs.stageDistributionChart) {
        this.stageDistributionChart = echarts.init(this.$refs.stageDistributionChart, 'macarons')
      }
      if (this.$refs.stageMetricsChart) {
        this.stageMetricsChart = echarts.init(this.$refs.stageMetricsChart, 'macarons')
      }
      if (this.$refs.avgDurationChart) {
        this.avgDurationChart = echarts.init(this.$refs.avgDurationChart, 'macarons')
      }
      if (this.$refs.funnelChart) {
        this.funnelChart = echarts.init(this.$refs.funnelChart, 'macarons')
      }
    },
    /** 渲染所有图表 */
    renderCharts() {
      const entries = Object.entries(this.results || {})
      const resultsArr = entries.filter(([k]) => k !== '_analysis_summary_').map(([, v]) => v)

      // 1. SKU生命周期阶段分布（饼图）
      this.renderStageDistribution(resultsArr)

      // 2. 各阶段关键指标对比（柱状图）
      this.renderStageMetrics(resultsArr)

      // 3. 阶段平均时长（柱状图）
      this.renderAvgDuration(resultsArr)

      // 4. 阶段转化漏斗（横向条形图）
      this.renderFunnel(resultsArr)
    },
    /** 渲染阶段分布饼图 */
    renderStageDistribution(list) {
      const dist = { 引入期: 0, 成长期: 0, 成熟期: 0, 衰退期: 0 }
      list.forEach(r => {
        const cur = this.normalizeStage(r?.current_stage)
        if (cur && dist[cur] != null) dist[cur]++
      })

      const data = Object.keys(dist).map(key => ({
        value: dist[key],
        name: key
      }))

      const option = {
        tooltip: {
          trigger: 'item',
          formatter: '{a} <br/>{b}: {c} ({d}%)'
        },
        legend: {
          orient: 'vertical',
          left: 'left',
          data: Object.keys(dist)
        },
        series: [
          {
            name: '阶段分布',
            type: 'pie',
            radius: ['40%', '70%'],
            avoidLabelOverlap: false,
            itemStyle: {
              borderRadius: 10,
              borderColor: '#fff',
              borderWidth: 2
            },
            label: {
              show: true,
              formatter: '{b}: {c}\n({d}%)'
            },
            emphasis: {
              label: {
                show: true,
                fontSize: 16,
                fontWeight: 'bold'
              }
            },
            data: data,
            color: ['#3b82f6', '#10b981', '#f59e0b', '#ef4444']
          }
        ]
      }

      if (this.stageDistributionChart) {
        this.stageDistributionChart.setOption(option)
      }
    },
    /** 渲染各阶段关键指标对比 */
    renderStageMetrics(list) {
      const agg = this.aggregateStageMetrics(list)
      const metricLabels = Object.keys(agg)
      const revenueAgg = metricLabels.map(k => agg[k].totalRevenue)
      const qtyAgg = metricLabels.map(k => agg[k].totalQuantity)

      const option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        legend: {
          data: ['销售额(总计)', '销量(总计)']
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: metricLabels
        },
        yAxis: [
          {
            type: 'value',
            name: '销售额',
            position: 'left'
          },
          {
            type: 'value',
            name: '销量',
            position: 'right'
          }
        ],
        series: [
          {
            name: '销售额(总计)',
            type: 'bar',
            data: revenueAgg,
            itemStyle: {
              color: 'rgba(59,130,246,0.7)'
            }
          },
          {
            name: '销量(总计)',
            type: 'bar',
            yAxisIndex: 1,
            data: qtyAgg,
            itemStyle: {
              color: 'rgba(100,116,139,0.7)'
            }
          }
        ]
      }

      if (this.stageMetricsChart) {
        this.stageMetricsChart.setOption(option)
      }
    },
    /** 渲染阶段平均时长 */
    renderAvgDuration(list) {
      const avgDur = this.averageStageDuration(list)
      const durLabels = Object.keys(avgDur)
      const durValues = Object.values(avgDur)

      const option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: durLabels
        },
        yAxis: {
          type: 'value',
          name: '天数'
        },
        series: [
          {
            name: '平均持续天数',
            type: 'bar',
            data: durValues,
            itemStyle: {
              color: 'rgba(245,158,11,0.7)'
            },
            label: {
              show: true,
              position: 'top'
            }
          }
        ]
      }

      if (this.avgDurationChart) {
        this.avgDurationChart.setOption(option)
      }
    },
    /** 渲染阶段转化漏斗 */
    renderFunnel(list) {
      const funnelData = this.stageFunnel(list)
      const funnelLabels = funnelData.labels
      const funnelValues = funnelData.values

      const option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'value',
          name: '转化率(%)'
        },
        yAxis: {
          type: 'category',
          data: funnelLabels
        },
        series: [
          {
            name: '转化率',
            type: 'bar',
            data: funnelValues,
            itemStyle: {
              color: 'rgba(59,130,246,0.7)'
            },
            label: {
              show: true,
              position: 'right',
              formatter: '{c}%'
            }
          }
        ]
      }

      if (this.funnelChart) {
        this.funnelChart.setOption(option)
      }
    },
    /** 窗口大小变化处理 */
    handleResize() {
      if (this.stageDistributionChart) {
        this.stageDistributionChart.resize()
      }
      if (this.stageMetricsChart) {
        this.stageMetricsChart.resize()
      }
      if (this.avgDurationChart) {
        this.avgDurationChart.resize()
      }
      if (this.funnelChart) {
        this.funnelChart.resize()
      }
    },
    /** 工具函数 */
    sumArray(arr) {
      return (arr || []).reduce((s, v) => s + (Number(v) || 0), 0)
    },
    getLifecycleDays(r) {
      const stats = r?.stage_statistics || {}
      return Object.values(stats).reduce((s, v) => s + (v.durationDays || 0), 0)
    },
    isInsufficient(r) {
      const days = (r?.date_series || []).length
      const stats = r?.stage_statistics || {}
      return days < 120 || Object.keys(stats).length === 0
    },
    normalizeStage(s) {
      if (!s) return ''
      if (s.includes('导入') || s.includes('引入')) return '引入期'
      if (s.includes('成长')) return '成长期'
      if (s.includes('成熟')) return '成熟期'
      if (s.includes('衰退')) return '衰退期'
      return s
    },
    averageStageDuration(list) {
      // 仅统计完整生命周期SKU
      const filtered = list.filter(r => !!r?.is_complete)
      const agg = { 引入期: [], 成长期: [], 成熟期: [], 衰退期: [] }
      filtered.forEach(r => {
        const stats = r?.stage_statistics || {}
        Object.entries(stats).forEach(([stage, v]) => {
          const key = this.normalizeStage(stage)
          if (agg[key]) agg[key].push(v?.durationDays || 0)
        })
      })
      const res = {}
      Object.entries(agg).forEach(([k, arr]) => {
        res[k] = arr.length ? Math.round(arr.reduce((s, x) => s + (Number(x) || 0), 0) / arr.length) : 0
      })
      return res
    },
    aggregateStageMetrics(list) {
      const agg = {
        引入期: { totalRevenue: 0, totalQuantity: 0 },
        成长期: { totalRevenue: 0, totalQuantity: 0 },
        成熟期: { totalRevenue: 0, totalQuantity: 0 },
        衰退期: { totalRevenue: 0, totalQuantity: 0 }
      }
      list.forEach(r => {
        const stats = r?.stage_statistics || {}
        Object.entries(stats).forEach(([stage, v]) => {
          const key = this.normalizeStage(stage)
          if (agg[key]) {
            agg[key].totalRevenue += Number(v?.totalRevenue || 0)
            agg[key].totalQuantity += Number(v?.totalQuantity || 0)
          }
        })
      })
      return agg
    },
    stageFunnel(list) {
      // 顺序转化：引入→成长→成熟→衰退
      let intro = 0, growth = 0, maturity = 0, decline = 0
      list.forEach(r => {
        const stats = r?.stage_statistics || {}
        const names = Object.keys(stats).map(this.normalizeStage)
        const hasIntro = names.includes('引入期')
        const hasGrowth = names.includes('成长期')
        const hasMaturity = names.includes('成熟期')
        const hasDecline = names.includes('衰退期')
        if (hasIntro) intro++
        if (hasIntro && hasGrowth) growth++
        if (hasIntro && hasGrowth && hasMaturity) maturity++
        if (hasIntro && hasGrowth && hasMaturity && hasDecline) decline++
      })
      const labels = ['引入期', '成长期', '成熟期', '衰退期']
      const counts = [intro, growth, maturity, decline]
      const values = counts.map((c, i) => {
        if (i === 0) return intro ? 100 : 0
        const prev = counts[i - 1]
        return prev ? Number(((c / prev) * 100).toFixed(1)) : 0
      })
      return { labels, values }
    },
    formatUploadDate(date) {
      const d = date instanceof Date ? date : new Date(date)
      if (Number.isNaN(d.getTime())) return ''
      const y = d.getFullYear()
      const m = String(d.getMonth() + 1).padStart(2, '0')
      const day = String(d.getDate()).padStart(2, '0')
      return `${y}-${m}-${day}`
    },
    exportResults() {
      if (!this.hasResults) {
        this.$modal.msgError('暂无可导出的分析结果')
        return
      }
      const payload = JSON.stringify(this.results || {}, null, 2)
      const blob = new Blob([payload], { type: 'application/json;charset=utf-8' })
      const url = URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = url
      a.download = `sku_lifecycle_results_${this.formatUploadDate(new Date())}.json`
      document.body.appendChild(a)
      a.click()
      document.body.removeChild(a)
      URL.revokeObjectURL(url)
    }
  }
}
</script>

<style scoped lang="scss">
.app-container {
  padding: 20px;
}

.page-header {
  margin-bottom: 20px;

  h2 {
    font-size: 24px;
    font-weight: 600;
    color: #303133;
    margin-bottom: 8px;

    i {
      margin-right: 8px;
      color: #409EFF;
    }
  }

  .page-desc {
    color: #909399;
    font-size: 14px;
    margin: 0;
  }
}

.mb-20 {
  margin-bottom: 20px;
}

.upload-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: #ffffff;
  border: 1px solid #e6eaf2;
  border-radius: 8px;
  padding: 12px 16px;
  margin-bottom: 16px;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06);
}

.toolbar-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.toolbar-upload ::v-deep .el-upload {
  display: inline-flex;
}

.toolbar-status {
  font-size: 13px;
  color: #16a34a;
  background: #f0fdf4;
  border: 1px solid #dcfce7;
  border-radius: 6px;
  padding: 6px 10px;
}

.toolbar-status.muted {
  color: #6b7280;
  background: #f8fafc;
  border-color: #e2e8f0;
}

.upload-card {
  border-radius: 8px;
  border: 1px solid #e6eaf2;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06);
}

.upload-card .el-card__header {
  padding: 12px 16px;
  border-bottom: 1px solid #eef2f7;
}

.upload-row {
  display: flex;
  align-items: center;
  gap: 16px;
}

.upload-compact {
  flex: 1;
  max-width: 260px;
}

.upload-compact ::v-deep .el-upload-dragger {
  width: 100%;
  height: 140px;
  padding: 10px 12px;
  border-radius: 8px;
}

.upload-compact ::v-deep .el-icon-upload {
  font-size: 26px;
  margin-bottom: 4px;
}

.upload-compact ::v-deep .el-upload__text {
  font-size: 13px;
}

.upload-compact ::v-deep .el-upload__tip {
  margin-top: 6px;
  font-size: 12px;
  color: #909399;
}

.upload-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 120px;
}

::v-deep .el-card {
  border-radius: 8px;
  border: 1px solid #e6eaf2;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06);
}

::v-deep .el-card__header {
  border-bottom: 1px solid #eef2f7;
}

.stat-card {
  .stat-content {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;

    .stat-info {
      flex: 1;

      .stat-label {
        font-size: 12px;
        color: #909399;
        margin: 0 0 8px 0;
        text-transform: uppercase;
        letter-spacing: 0.5px;
      }

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

      .stat-desc {
        font-size: 12px;
        color: #909399;
        margin: 0;

        &.stat-desc-success {
          color: #67C23A;
        }
      }
    }

    .stat-icon {
      width: 48px;
      height: 48px;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 20px;

      &.stat-icon-purple {
        background: linear-gradient(135deg, #e0e7ff 0%, #c7d2fe 100%);
        color: #6366f1;
      }

      &.stat-icon-blue {
        background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
        color: #3b82f6;
      }

      &.stat-icon-teal {
        background: linear-gradient(135deg, #ccfbf1 0%, #99f6e4 100%);
        color: #14b8a6;
      }

      &.stat-icon-green {
        background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);
        color: #10b981;
      }

      &.stat-icon-yellow {
        background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
        color: #f59e0b;
      }

      &.stat-icon-red {
        background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);
        color: #ef4444;
      }
    }
  }
}

::v-deep .el-card__header {
  display: flex;
  justify-content: space-between;
  align-items: center;

  .header-desc {
    font-size: 12px;
    color: #909399;
    font-weight: normal;
  }
}
</style>

