<template>
  <div class="app-container">
    <!-- 页面标题 -->
    <div class="page-header">
      <h2><i class="el-icon-s-data"></i> SKU爆品分析</h2>
      <p class="page-desc">基于五维指标体系的爆款系数分析,快速识别超级爆款、潜力爆款、常规款和清货款</p>
    </div>

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

    <!-- 错误提示 -->
    <div v-if="error" class="error-alert">
      <i class="el-icon-warning"></i>
      {{ error }}
    </div>

    <!-- 关键指标卡片 -->
    <div class="stats-grid mb-20">
      <div class="stat-card">
        <div class="stat-header">
          <div>
            <p class="stat-label">总SKU数</p>
            <p class="stat-value">{{ summary.total_sku_count || 0 }}</p>
          </div>
          <div class="stat-icon bg-blue">
            <i class="el-icon-files"></i>
          </div>
        </div>
        <div class="stat-footer">分析对象</div>
      </div>

      <div class="stat-card">
        <div class="stat-header">
          <div>
            <p class="stat-label">平均爆款系数</p>
            <p class="stat-value">{{ summary.avg_score || '-' }}</p>
          </div>
          <div class="stat-icon bg-green">
            <i class="el-icon-trend-charts"></i>
          </div>
        </div>
        <div class="stat-footer success">整体表现</div>
      </div>

      <div class="stat-card">
        <div class="stat-header">
          <div>
            <p class="stat-label">最高系数</p>
            <p class="stat-value">{{ summary.max_score || '-' }}</p>
          </div>
          <div class="stat-icon bg-yellow">
            <i class="el-icon-trophy"></i>
          </div>
        </div>
        <div class="stat-footer warning">顶尖表现</div>
      </div>

      <div class="stat-card">
        <div class="stat-header">
          <div>
            <p class="stat-label">超级爆款数</p>
            <p class="stat-value">{{ levelDistribution['超级爆款'] || 0 }}</p>
          </div>
          <div class="stat-icon bg-red">
            <i class="el-icon-star-on"></i>
          </div>
        </div>
        <div class="stat-footer danger">明星产品</div>
      </div>
    </div>

    <!-- 爆款等级分布与五维指标对比 -->
    <div class="charts-grid mb-20">
      <div class="chart-card">
        <div class="chart-header">
          <h3 class="chart-title">爆款等级分布</h3>
          <div class="chart-subtitle">按SKU数量统计</div>
        </div>
        <div class="chart-container h-80">
          <canvas ref="levelDistChartRef"></canvas>
        </div>
      </div>

      <div class="chart-card">
        <div class="chart-header">
          <h3 class="chart-title">五维指标平均对比</h3>
          <div class="chart-subtitle">各等级指标表现</div>
        </div>
        <div class="chart-container h-80">
          <canvas ref="metricsCompareChartRef"></canvas>
        </div>
      </div>
    </div>

    <!-- SKU详情表格 -->
    <div class="table-card mb-20">
      <div class="table-header">
        <h3 class="table-title">SKU详情列表</h3>
        <div class="table-filters">
          <el-select v-model="filterLevel" placeholder="全部等级" clearable size="small" class="filter-select">
            <el-option value="超级爆款" label="超级爆款"></el-option>
            <el-option value="潜力爆款" label="潜力爆款"></el-option>
            <el-option value="常规款" label="常规款"></el-option>
            <el-option value="清货款" label="清货款"></el-option>
          </el-select>
          <el-input 
            v-model="searchKeyword" 
            placeholder="搜索SKU或商品名称..." 
            size="small"
            prefix-icon="el-icon-search"
            class="filter-input"
            clearable
          />
        </div>
      </div>

      <div class="table-wrapper">
        <table class="data-table">
          <thead>
            <tr>
              <th @click="sortBy('hotproduct_score')" class="sortable">
                爆款系数
                <i :class="getSortIcon('hotproduct_score')"></i>
              </th>
              <th>等级</th>
              <th>SKU ID</th>
              <th>商品名称</th>
              <th @click="sortBy('total_quantity')" class="sortable">
                总销量
                <i :class="getSortIcon('total_quantity')"></i>
              </th>
              <th @click="sortBy('total_revenue')" class="sortable">
                总销售额
                <i :class="getSortIcon('total_revenue')"></i>
              </th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="item in filteredAndSortedSkus" :key="item.sku_id" class="data-row">
              <td>
                <div class="score-cell">
                  <div class="score-value">{{ item.hotproduct_score || '-' }}</div>
                  <div class="score-bar">
                    <div 
                      class="score-progress" 
                      :class="getScoreColorClass(item.hotproduct_score)"
                      :style="{ width: ((item.hotproduct_score || 0) * 100) + '%' }"
                    ></div>
                  </div>
                </div>
              </td>
              <td>
                <span class="level-badge" :class="getLevelBadgeClass(item.hotproduct_level)">
                  {{ item.hotproduct_level || '-' }}
                </span>
              </td>
              <td class="text-sm">{{ item.sku_id || '-' }}</td>
              <td class="text-sm product-title" :title="item.product_title">
                {{ item.product_title || '-' }}
              </td>
              <td class="text-sm">{{ (item.raw_data && item.raw_data.total_quantity) || '-' }}</td>
              <td class="text-sm">{{ formatCurrency((item.raw_data && item.raw_data.total_revenue) || 0) }}</td>
              <td>
                <el-button 
                  type="text" 
                  size="small"
                  @click="showDetail(item)"
                  class="action-btn"
                >
                  查看详情
                </el-button>
              </td>
            </tr>
            <tr v-if="filteredAndSortedSkus.length === 0">
              <td colspan="7" class="empty-state">
                <i class="el-icon-inbox"></i>
                <p>未找到符合条件的SKU</p>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>

    <!-- SKU详情弹窗 -->
    <el-dialog
      :visible.sync="detailVisible"
      :title="selectedSku ? selectedSku.product_title : ''"
      width="80%"
      top="5vh"
      custom-class="detail-dialog"
      :close-on-click-modal="false"
    >
      <div v-if="selectedSku" class="detail-content">
        <!-- SKU基本信息 -->
        <div class="detail-info mb-6">
          <p class="info-label">SKU ID: <span class="info-value">{{ selectedSku.sku_id }}</span></p>
        </div>

        <!-- 爆款系数和等级 -->
        <div class="detail-stats mb-6">
          <div class="detail-stat-card bg-blue-gradient">
            <p class="detail-stat-label">爆款系数</p>
            <p class="detail-stat-value">{{ selectedSku.hotproduct_score || '-' }}</p>
          </div>
          <div class="detail-stat-card bg-purple-gradient">
            <p class="detail-stat-label">爆款等级</p>
            <p class="detail-stat-value" :class="getLevelTextColor(selectedSku.hotproduct_level)">
              {{ selectedSku.hotproduct_level || '-' }}
            </p>
          </div>
        </div>

        <!-- 五维指标雷达图 -->
        <div class="detail-section mb-6">
          <h4 class="section-title">五维指标雷达图</h4>
          <div class="chart-container h-80">
            <canvas ref="radarChartRef"></canvas>
          </div>
        </div>

        <!-- 指标详情 -->
        <div class="detail-section mb-6">
          <h4 class="section-title">指标详情</h4>
          <div class="metrics-grid">
            <div class="metric-item">
              <div class="metric-header">
                <span class="metric-name">销售热度(单位时间销量)</span>
                <span class="metric-score">{{ getMetricValue(selectedSku, 'sales_heat') }}</span>
              </div>
              <div class="metric-bar">
                <div class="metric-progress bg-blue" :style="{ width: (getMetricValue(selectedSku, 'sales_heat') * 100) + '%' }"></div>
              </div>
              <p class="metric-weight">权重: 40%</p>
            </div>

            <div class="metric-item">
              <div class="metric-header">
                <span class="metric-name">价格接受度(实收率)</span>
                <span class="metric-score">{{ getMetricValue(selectedSku, 'price_acceptance') }}</span>
              </div>
              <div class="metric-bar">
                <div class="metric-progress bg-green" :style="{ width: (getMetricValue(selectedSku, 'price_acceptance') * 100) + '%' }"></div>
              </div>
              <p class="metric-weight">权重: 30%</p>
            </div>

            <div class="metric-item">
              <div class="metric-header">
                <span class="metric-name">退款稳定性(1-退款率)</span>
                <span class="metric-score">{{ getMetricValue(selectedSku, 'refund_stability') }}</span>
              </div>
              <div class="metric-bar">
                <div class="metric-progress bg-yellow" :style="{ width: (getMetricValue(selectedSku, 'refund_stability') * 100) + '%' }"></div>
              </div>
              <p class="metric-weight">权重: 10%</p>
            </div>

            <div class="metric-item">
              <div class="metric-header">
                <span class="metric-name">复购热度(复购率)</span>
                <span class="metric-score">{{ getMetricValue(selectedSku, 'repurchase_rate') }}</span>
              </div>
              <div class="metric-bar">
                <div class="metric-progress bg-purple" :style="{ width: (getMetricValue(selectedSku, 'repurchase_rate') * 100) + '%' }"></div>
              </div>
              <p class="metric-weight">权重: 10%</p>
            </div>

            <div class="metric-item">
              <div class="metric-header">
                <span class="metric-name">夜间爆发力(0-6点占比)</span>
                <span class="metric-score">{{ getMetricValue(selectedSku, 'night_burst') }}</span>
              </div>
              <div class="metric-bar">
                <div class="metric-progress bg-indigo" :style="{ width: (getMetricValue(selectedSku, 'night_burst') * 100) + '%' }"></div>
              </div>
              <p class="metric-weight">权重: 10%</p>
            </div>
          </div>
        </div>

        <!-- 原始数据 -->
        <div class="detail-section mb-6">
          <h4 class="section-title">原始数据</h4>
          <div class="raw-data-grid">
            <div class="raw-data-item">
              <p class="raw-data-label">总销量</p>
              <p class="raw-data-value">{{ getRawData(selectedSku, 'total_quantity') }}</p>
            </div>
            <div class="raw-data-item">
              <p class="raw-data-label">总销售额</p>
              <p class="raw-data-value">{{ formatCurrency(getRawData(selectedSku, 'total_revenue')) }}</p>
            </div>
            <div class="raw-data-item">
              <p class="raw-data-label">平均价格</p>
              <p class="raw-data-value">{{ formatCurrency(getRawData(selectedSku, 'avg_price')) }}</p>
            </div>
            <div class="raw-data-item">
              <p class="raw-data-label">天数跨度</p>
              <p class="raw-data-value">{{ getRawData(selectedSku, 'days_span') }}天</p>
            </div>
            <div class="raw-data-item">
              <p class="raw-data-label">日均销量</p>
              <p class="raw-data-value">{{ getRawData(selectedSku, 'daily_sales') }}</p>
            </div>
            <div class="raw-data-item">
              <p class="raw-data-label">独立买家数</p>
              <p class="raw-data-value">{{ getRawData(selectedSku, 'unique_buyers') }}</p>
            </div>
            <div class="raw-data-item">
              <p class="raw-data-label">复购买家数</p>
              <p class="raw-data-value">{{ getRawData(selectedSku, 'repurchase_buyers') }}</p>
            </div>
            <div class="raw-data-item">
              <p class="raw-data-label">退款率</p>
              <p class="raw-data-value">{{ formatPercent(getRawData(selectedSku, 'refund_rate') * 100) }}</p>
            </div>
          </div>
        </div>

        <!-- 运营建议 -->
        <div class="advice-box">
          <h4 class="advice-title">
            <i class="el-icon-light-rain"></i>
            运营建议
          </h4>
          <p class="advice-content">{{ getOperationAdvice(selectedSku.hotproduct_level) }}</p>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { Chart } from 'chart.js'
import { analyzeHotProductWithFile } from '@/api/client'

export default {
  name: 'SkuHotProductAnalysis',
  data() {
    return {
      loading: false,
      error: '',
      results: null,
      selectedSku: null,
      detailVisible: false,

      filterLevel: '',
      searchKeyword: '',
      sortColumn: 'hotproduct_score',
      sortOrder: 'desc',

      fileName: '',
      pendingFileName: '',
      ignoreFileChange: false,

      // Chart 实例
      levelDistChart: null,
      metricsCompareChart: null,
      radarChart: null
    }
  },

  computed: {
    hasResults() {
      return this.results !== null && Object.keys(this.results).length > 0
    },
    summary() {
      return (this.results && this.results.summary) || {}
    },
    levelDistribution() {
      return (this.results && this.results.summary && this.results.summary.level_distribution) || {}
    },
    skuList() {
      if (!this.results || !this.results.sku_results) return []
      return Object.values(this.results.sku_results)
    },
    filteredAndSortedSkus() {
      let list = this.skuList.slice()

      // 过滤等级
      if (this.filterLevel) {
        list = list.filter(item => item.hotproduct_level === this.filterLevel)
      }

      // 搜索关键词
      if (this.searchKeyword) {
        const keyword = String(this.searchKeyword).toLowerCase()
        list = list.filter(item => {
          const skuId = String(item.sku_id || '').toLowerCase()
          const title = String(item.product_title || '').toLowerCase()
          return skuId.includes(keyword) || title.includes(keyword)
        })
      }

      // 排序
      const col = this.sortColumn
      const order = this.sortOrder
      list.sort((a, b) => {
        let aVal = 0
        let bVal = 0

        if (col === 'hotproduct_score') {
          aVal = Number(a.hotproduct_score) || 0
          bVal = Number(b.hotproduct_score) || 0
        } else if (col === 'total_quantity') {
          aVal = Number(a.raw_data && a.raw_data.total_quantity) || 0
          bVal = Number(b.raw_data && b.raw_data.total_quantity) || 0
        } else if (col === 'total_revenue') {
          aVal = Number(a.raw_data && a.raw_data.total_revenue) || 0
          bVal = Number(b.raw_data && b.raw_data.total_revenue) || 0
        }

        return order === 'asc' ? (aVal - bVal) : (bVal - aVal)
      })

      return list
    }
  },

  watch: {
    results() {
      this.$nextTick(() => {
        this.renderCharts()
      })
    },
    detailVisible(val) {
      if (!val && this.radarChart) {
        this.radarChart.destroy()
        this.radarChart = null
      } else if (val && this.selectedSku) {
        this.$nextTick(() => {
          this.renderRadarChart()
        })
      }
    }
  },

  mounted() {
    this.renderCharts()
  },

  beforeDestroy() {
    if (this.levelDistChart) this.levelDistChart.destroy()
    if (this.metricsCompareChart) this.metricsCompareChart.destroy()
    if (this.radarChart) this.radarChart.destroy()
  },

  methods: {
    handleFileChange(file, fileList) {
      if (this.ignoreFileChange) return
      if (!fileList || fileList.length === 0) return
      if (!file || !file.raw) return

      this.pendingFileName = file.name
      this.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.$message.error('上传文件只能是 xlsx/xls/csv 格式!')
        return false
      }
      if (!isLt500M) {
        this.$message.error('上传文件大小不能超过 500MB!')
        return false
      }
      return true
    },

    customUpload(options) {
      const file = options.file
      this.loading = true
      this.error = ''

      analyzeHotProductWithFile(file).then(response => {
        this.loading = false
        if (response && response.success) {
          this.results = response.data || {}
          this.$message.success('文件上传并分析成功')
          this.fileName = this.pendingFileName || file.name
          this.pendingFileName = ''
          this.$nextTick(() => {
            this.renderCharts()
          })
          options.onSuccess(response)
        } else {
          const msg = (response && response.message) || '分析失败'
          this.error = msg
          this.$message.error(msg)
          options.onError(new Error(msg))
        }
      }).catch(error => {
        this.loading = false
        const msg = (error && error.response && error.response.data && error.response.data.message) ||
          (error && error.message) || '文件上传失败,请重试'
        this.error = msg
        this.$message.error(msg)
        options.onError(error)
      }).finally(() => {
        if (this.$refs.toolbarUpload) {
          this.ignoreFileChange = true
          this.$refs.toolbarUpload.clearFiles()
          this.$nextTick(() => {
            this.ignoreFileChange = false
          })
        }
      })
    },

    submitUpload() {
      const target = this.$refs.toolbarUpload
      const fileList = target && target.uploadFiles ? target.uploadFiles : []
      if (!fileList || fileList.length === 0) {
        this.$message.error('请选择要上传的文件')
        return
      }
      target.submit()
    },

    renderCharts() {
      this.renderLevelDistChart()
      this.renderMetricsCompareChart()
    },

    renderLevelDistChart() {
      if (this.levelDistChart) this.levelDistChart.destroy()

      const canvas = this.$refs.levelDistChartRef
      if (!canvas) return

      const levels = ['超级爆款', '潜力爆款', '常规款', '清货款']
      const data = levels.map(level => this.levelDistribution[level] || 0)
      const colors = ['#ef4444', '#f59e0b', '#10b981', '#6b7280']

      this.levelDistChart = new Chart(canvas, {
        type: 'doughnut',
        data: {
          labels: levels,
          datasets: [{
            data,
            backgroundColor: colors,
            borderWidth: 2,
            borderColor: '#fff'
          }]
        },
        options: {
          responsive: true,
          maintainAspectRatio: false,
          plugins: {
            legend: {
              position: 'right',
              labels: {
                padding: 15,
                font: { size: 12 }
              }
            },
            tooltip: {
              callbacks: {
                label: (context) => {
                  const label = context.label || ''
                  const value = context.parsed || 0
                  const total = (context.dataset.data || []).reduce((a, b) => a + b, 0)
                  const percentage = total ? ((value / total) * 100).toFixed(1) : '0.0'
                  return `${label}: ${value} (${percentage}%)`
                }
              }
            }
          }
        }
      })
    },

    renderMetricsCompareChart() {
      if (this.metricsCompareChart) this.metricsCompareChart.destroy()

      const canvas = this.$refs.metricsCompareChartRef
      if (!canvas) return

      const levels = ['超级爆款', '潜力爆款', '常规款', '清货款']
      const metricNames = ['销售热度', '价格接受度', '退款稳定性', '复购热度', '夜间爆发力']
      const metricKeys = ['sales_heat', 'price_acceptance', 'refund_stability', 'repurchase_rate', 'night_burst']

      // 计算各等级平均指标
      const levelMetrics = {}
      levels.forEach(level => {
        const skus = this.skuList.filter(s => s.hotproduct_level === level)
        if (skus.length > 0) {
          levelMetrics[level] = metricKeys.map(key => {
            const sum = skus.reduce((acc, sku) => acc + (Number(sku.metrics && sku.metrics[key]) || 0), 0)
            return sum / skus.length
          })
        } else {
          levelMetrics[level] = metricKeys.map(() => 0)
        }
      })

      const baseColors = ['#ef4444', '#f59e0b', '#10b981', '#6b7280']
      const datasets = levels.map((level, idx) => ({
        label: level,
        data: levelMetrics[level] || [],
        backgroundColor: baseColors[idx] + '33',
        borderColor: baseColors[idx],
        borderWidth: 2
      }))

      this.metricsCompareChart = new Chart(canvas, {
        type: 'radar',
        data: {
          labels: metricNames,
          datasets
        },
        options: {
          responsive: true,
          maintainAspectRatio: false,
          scales: {
            r: {
              beginAtZero: true,
              max: 1,
              ticks: { stepSize: 0.2 }
            }
          },
          plugins: {
            legend: { position: 'bottom' }
          }
        }
      })
    },

    renderRadarChart() {
      if (!this.selectedSku) return
      if (this.radarChart) this.radarChart.destroy()

      const canvas = this.$refs.radarChartRef
      if (!canvas) return

      const metricNames = ['销售热度', '价格接受度', '退款稳定性', '复购热度', '夜间爆发力']
      const metricKeys = ['sales_heat', 'price_acceptance', 'refund_stability', 'repurchase_rate', 'night_burst']
      const data = metricKeys.map(key => Number(this.selectedSku.metrics && this.selectedSku.metrics[key]) || 0)

      this.radarChart = new Chart(canvas, {
        type: 'radar',
        data: {
          labels: metricNames,
          datasets: [{
            label: '指标得分',
            data,
            backgroundColor: 'rgba(59, 130, 246, 0.2)',
            borderColor: 'rgb(59, 130, 246)',
            borderWidth: 2,
            pointBackgroundColor: 'rgb(59, 130, 246)',
            pointBorderColor: '#fff',
            pointHoverBackgroundColor: '#fff',
            pointHoverBorderColor: 'rgb(59, 130, 246)'
          }]
        },
        options: {
          responsive: true,
          maintainAspectRatio: false,
          scales: {
            r: {
              beginAtZero: true,
              max: 1,
              ticks: { stepSize: 0.2 }
            }
          },
          plugins: {
            legend: { display: false }
          }
        }
      })
    },

    showDetail(sku) {
      this.selectedSku = sku
      this.detailVisible = true
    },

    closeDetail() {
      this.detailVisible = false
      this.selectedSku = null
    },

    sortBy(column) {
      if (this.sortColumn === column) {
        this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc'
      } else {
        this.sortColumn = column
        this.sortOrder = 'desc'
      }
    },

    getSortIcon(column) {
      if (this.sortColumn !== column) return 'el-icon-d-caret'
      return this.sortOrder === 'asc' ? 'el-icon-caret-top' : 'el-icon-caret-bottom'
    },

    getScoreColorClass(score) {
      const s = Number(score) || 0
      if (s >= 0.8) return 'score-red'
      if (s >= 0.6) return 'score-yellow'
      if (s >= 0.4) return 'score-green'
      return 'score-gray'
    },

    getLevelBadgeClass(level) {
      const classes = {
        '超级爆款': 'badge-red',
        '潜力爆款': 'badge-yellow',
        '常规款': 'badge-green',
        '清货款': 'badge-gray'
      }
      return classes[level] || 'badge-gray'
    },

    getLevelTextColor(level) {
      const colors = {
        '超级爆款': 'text-red',
        '潜力爆款': 'text-yellow',
        '常规款': 'text-green',
        '清货款': 'text-gray'
      }
      return colors[level] || 'text-gray'
    },

    getOperationAdvice(level) {
      const advice = {
        '超级爆款': '建议:立即加大库存备货,增加投流预算,抢占市场份额。这是明星产品,需要重点维护和推广。',
        '潜力爆款': '建议:优化转化链路,提升用户体验,加强营销推广。这类产品有成为爆款的潜力,需要精心培育。',
        '常规款': '建议:维持现状,持续观察市场反馈。可以尝试小规模优化,但不需要大量投入资源。',
        '清货款': '建议:考虑清仓促销或直接下架,避免占用库存和运营资源。将精力投入到更有潜力的产品上。'
      }
      return advice[level] || '暂无建议'
    },

    getMetricValue(sku, key) {
      if (!sku || !sku.metrics) return '-'
      const val = sku.metrics[key]
      return val != null ? String(val) : '-'
    },

    getRawData(sku, key) {
      if (!sku || !sku.raw_data) return '-'
      const val = sku.raw_data[key]
      return val != null ? val : '-'
    },

    formatCurrency(val) {
      if (val == null || val === '-') return '-'
      const num = Number(val)
      if (Number.isNaN(num)) return '-'
      return '¥' + num.toFixed(2)
    },

    formatPercent(val) {
      if (val == null || val === '-') return '-'
      const num = Number(val)
      if (Number.isNaN(num)) return '-'
      return num.toFixed(2) + '%'
    },

    exportResults() {
      if (!this.hasResults) {
        this.$message.error('暂无可导出的分析结果')
        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_hotproduct_results_${new Date().toISOString().slice(0, 10)}.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; }
.mb-6 { margin-bottom: 24px; }

.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;
}

.error-alert {
  background: #fef2f2;
  border: 1px solid #fecaca;
  border-radius: 8px;
  padding: 12px 16px;
  color: #dc2626;
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  gap: 8px;

  i {
    font-size: 18px;
  }
}

/* 统计卡片 */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
}

.stat-card {
  background: #ffffff;
  border: 1px solid #e6eaf2;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06);
  transition: transform 0.2s ease, box-shadow 0.2s ease;

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(15, 23, 42, 0.1);
  }
}

.stat-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 12px;
}

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

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

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

  &.bg-blue {
    background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
    color: #2563eb;
  }

  &.bg-green {
    background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);
    color: #059669;
  }

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

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

.stat-footer {
  font-size: 13px;
  color: #606266;

  &.success { color: #16a34a; }
  &.warning { color: #d97706; }
  &.danger { color: #dc2626; }
}

/* 图表卡片 */
.charts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  gap: 20px;
}

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

.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
}

.chart-title {
  font-size: 18px;
  font-weight: 600;
  color: #303133;
  margin: 0;
}

.chart-subtitle {
  font-size: 13px;
  color: #909399;
}

.chart-container {
  position: relative;

  &.h-80 {
    height: 320px;
  }
}

/* 表格卡片 */
.table-card {
  background: #ffffff;
  border: 1px solid #e6eaf2;
  border-radius: 8px;
  padding: 24px;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06);
}

.table-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
  flex-wrap: wrap;
  gap: 16px;
}

.table-title {
  font-size: 18px;
  font-weight: 600;
  color: #303133;
  margin: 0;
}

.table-filters {
  display: flex;
  gap: 12px;
  align-items: center;
}

.filter-select {
  width: 140px;
}

.filter-input {
  width: 260px;
}

.table-wrapper {
  overflow-x: auto;
}

.data-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;

  thead {
    background: #f8fafc;

    th {
      padding: 12px 16px;
      text-align: left;
      font-size: 12px;
      font-weight: 600;
      color: #606266;
      text-transform: uppercase;
      letter-spacing: 0.05em;
      border-bottom: 1px solid #e5e7eb;

      &:first-child {
        border-top-left-radius: 8px;
      }

      &:last-child {
        border-top-right-radius: 8px;
      }

      &.sortable {
        cursor: pointer;
        user-select: none;

        &:hover {
          background: #f1f5f9;
        }

        i {
          margin-left: 4px;
          font-size: 14px;
        }
      }
    }
  }

  tbody {
    tr.data-row {
      transition: background-color 0.2s;

      &:hover {
        background: #f9fafb;
      }

      td {
        padding: 16px;
        border-bottom: 1px solid #e5e7eb;
        font-size: 14px;
        color: #303133;

        &.text-sm {
          font-size: 13px;
        }

        &.product-title {
          max-width: 300px;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
      }
    }

    tr:last-child td {
      border-bottom: none;
    }
  }
}

.score-cell {
  display: flex;
  align-items: center;
  gap: 8px;
}

.score-value {
  font-weight: 700;
  min-width: 40px;
}

.score-bar {
  flex: 1;
  height: 8px;
  background: #f3f4f6;
  border-radius: 999px;
  overflow: hidden;
  max-width: 80px;
}

.score-progress {
  height: 100%;
  border-radius: 999px;
  transition: width 0.3s;

  &.score-red { background: #ef4444; }
  &.score-yellow { background: #f59e0b; }
  &.score-green { background: #10b981; }
  &.score-gray { background: #6b7280; }
}

.level-badge {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;

  &.badge-red {
    background: #fee2e2;
    color: #991b1b;
  }

  &.badge-yellow {
    background: #fef3c7;
    color: #92400e;
  }

  &.badge-green {
    background: #d1fae5;
    color: #065f46;
  }

  &.badge-gray {
    background: #f3f4f6;
    color: #374151;
  }
}

.action-btn {
  color: #409EFF;
  font-weight: 500;

  &:hover {
    color: #66b1ff;
  }
}

.empty-state {
  padding: 60px 20px !important;
  text-align: center;
  color: #909399;

  i {
    font-size: 48px;
    display: block;
    margin-bottom: 12px;
  }

  p {
    margin: 0;
    font-size: 14px;
  }
}

/* 详情弹窗 */
.detail-dialog ::v-deep .el-dialog__header {
  border-bottom: 1px solid #e5e7eb;
  padding: 20px 24px;
}

.detail-dialog ::v-deep .el-dialog__body {
  padding: 24px;
}

.detail-content {
  max-height: 70vh;
  overflow-y: auto;
}

.detail-info {
  .info-label {
    font-size: 14px;
    color: #606266;
    margin: 0;
  }

  .info-value {
    font-weight: 600;
    color: #303133;
  }
}

.detail-stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}

.detail-stat-card {
  padding: 20px;
  border-radius: 8px;

  &.bg-blue-gradient {
    background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
  }

  &.bg-purple-gradient {
    background: linear-gradient(135deg, #f3e8ff 0%, #e9d5ff 100%);
  }
}

.detail-stat-label {
  font-size: 13px;
  color: #606266;
  margin-bottom: 8px;
}

.detail-stat-value {
  font-size: 32px;
  font-weight: 700;
  color: #303133;
  margin: 0;

  &.text-red { color: #dc2626; }
  &.text-yellow { color: #d97706; }
  &.text-green { color: #059669; }
  &.text-gray { color: #6b7280; }
}

.detail-section {
  .section-title {
    font-size: 16px;
    font-weight: 600;
    color: #303133;
    margin-bottom: 16px;
  }
}

.metrics-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 16px;
}

.metric-item {
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 16px;
  background: #f9fafb;
}

.metric-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.metric-name {
  font-size: 13px;
  color: #606266;
}

.metric-score {
  font-size: 16px;
  font-weight: 700;
  color: #303133;
}

.metric-bar {
  height: 8px;
  background: #e5e7eb;
  border-radius: 999px;
  overflow: hidden;
  margin-bottom: 8px;
}

.metric-progress {
  height: 100%;
  border-radius: 999px;

  &.bg-blue { background: #3b82f6; }
  &.bg-green { background: #10b981; }
  &.bg-yellow { background: #f59e0b; }
  &.bg-purple { background: #8b5cf6; }
  &.bg-indigo { background: #6366f1; }
}

.metric-weight {
  font-size: 12px;
  color: #909399;
  margin: 0;
}

.raw-data-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 16px;
}

.raw-data-item {
  background: #f9fafb;
  border-radius: 8px;
  padding: 16px;
}

.raw-data-label {
  font-size: 12px;
  color: #909399;
  margin-bottom: 4px;
}

.raw-data-value {
  font-size: 18px;
  font-weight: 700;
  color: #303133;
  margin: 0;
}

.advice-box {
  background: #eff6ff;
  border: 1px solid #bfdbfe;
  border-radius: 8px;
  padding: 16px;
}

.advice-title {
  font-size: 16px;
  font-weight: 600;
  color: #1e40af;
  margin-bottom: 8px;

  i {
    margin-right: 8px;
  }
}

.advice-content {
  font-size: 14px;
  color: #1e3a8a;
  margin: 0;
  line-height: 1.6;
}
</style>