<template>
  <div class="app-container">
    <div class="page-header">
      <div>
        <h2><i class="el-icon-data-analysis"></i> 生命周期分析</h2>
        <p class="page-desc">从订单表和产品表直接生成 SKU/SPU 生命周期分析结果</p>
      </div>
      <div class="analysis-switch">
        <button
          v-for="item in analysisTabs"
          :key="item.value"
          type="button"
          class="switch-btn"
          :class="{ active: activeView === item.value }"
          @click="switchAnalysis(item.value)"
        >
          {{ item.label }}
        </button>
      </div>
    </div>

    <div class="query-toolbar">
      <div class="query-left">
        <el-date-picker
          v-model="dateRange"
          type="daterange"
          value-format="yyyy-MM-dd"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          size="small"
          clearable
        />
        <el-button type="primary" size="small" :loading="loading" @click="getList">刷新分析</el-button>
        <el-button type="success" size="small" :disabled="!hasRawResults" @click="exportResults">导出分析</el-button>
      </div>
      <div class="toolbar-status" v-if="generatedAt">数据更新时间：{{ generatedAt }}</div>
      <div class="toolbar-status muted" v-else>数据库实时统计</div>
    </div>

    <el-alert v-if="error" :title="error" type="error" show-icon class="mb-20" />

    <template v-if="hasResults && detail">
      <div class="panel mb-20">
        <div class="panel-header">
          <div class="selector-row">
            <label>选择{{ currentConfig.entityName }}:</label>
            <el-select v-model="selectedValue" filterable size="small" class="entity-select">
              <el-option v-for="item in entityOptions" :key="item" :label="item" :value="item" />
            </el-select>
            <el-select v-model="lifecycleStatusFilter" size="small" class="status-select">
              <el-option label="全部生命周期" value="all" />
              <el-option label="完整生命周期" value="complete" />
              <el-option label="不完整生命周期" value="incomplete" />
            </el-select>
          </div>
          <el-tag :type="stageTagType(currentStage)" effect="plain">{{ currentStage }}</el-tag>
        </div>

        <div class="stats-grid">
          <div class="stat-box">
            <p class="stat-label">{{ currentConfig.entityDisplayLabel }}</p>
            <p class="stat-value truncate">{{ selectedValue }}</p>
          </div>
          <div class="stat-box">
            <p class="stat-label">生命周期完整性</p>
            <p class="stat-value" :class="detail.is_complete ? 'success-text' : 'warning-text'">
              {{ detail.is_complete ? '完整' : '不完整' }}
              <span class="sub-value">({{ detail.completeness_score || 0 }}/100)</span>
            </p>
          </div>
          <div class="stat-box">
            <p class="stat-label">总销售额</p>
            <p class="stat-value">{{ formatCurrency(totalRevenue) }}</p>
          </div>
          <div class="stat-box">
            <p class="stat-label">总销量</p>
            <p class="stat-value">{{ totalQty }}</p>
          </div>
        </div>
      </div>

      <div class="panel mb-20">
        <div class="chart-header">
          <h3>{{ currentConfig.entityName }}生命周期趋势图</h3>
          <div class="legend">
            <span><i class="dot blue"></i>销售额</span>
            <span><i class="dot gray"></i>销量</span>
          </div>
        </div>
        <div class="chart-container">
          <canvas ref="lifeCycleTrendRef"></canvas>
        </div>
      </div>

      <div class="content-grid mb-20">
        <div class="panel">
          <h3>基本指标</h3>
          <div class="metric-list">
            <div class="metric-row">
              <span>峰值销售额</span>
              <strong>{{ formatCurrency(detail.peak_revenue) }}</strong>
            </div>
            <div class="metric-row muted">
              <span>峰值日期</span>
              <strong>{{ formatDate(detail.peak_revenue_date) }}</strong>
            </div>
            <div class="metric-row">
              <span>峰值销量</span>
              <strong>{{ detail.peak_quantity != null ? detail.peak_quantity : '-' }}</strong>
            </div>
            <div class="metric-row muted">
              <span>峰值日期</span>
              <strong>{{ formatDate(detail.peak_quantity_date) }}</strong>
            </div>
            <div class="metric-row">
              <span>当前阶段持续天数</span>
              <strong>{{ currentStageDurationDays }}</strong>
            </div>
            <div class="metric-row">
              <span>商品名称</span>
              <strong class="text-right">{{ detail.details || '-' }}</strong>
            </div>
          </div>
        </div>

        <div class="panel wide">
          <h3>阶段分析</h3>
          <div class="table-wrapper">
            <table class="data-table">
              <thead>
                <tr>
                  <th>阶段</th>
                  <th>总销售额</th>
                  <th>销售额占比</th>
                  <th>总销量</th>
                  <th>销量占比</th>
                  <th>日均销售额</th>
                  <th>日均销量</th>
                  <th>持续天数</th>
                  <th>起止日期</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(stats, stage) in displayStageStats" :key="stage">
                  <td><span class="lifecycle-stage" :class="stageClass(stage)">{{ stage }}</span></td>
                  <td>{{ formatCurrency(stats.totalRevenue) }}</td>
                  <td>{{ formatPercent(stats.revenuePercentage) }}</td>
                  <td>{{ stats.totalQuantity != null ? stats.totalQuantity : '-' }}</td>
                  <td>{{ formatPercent(stats.quantityPercentage) }}</td>
                  <td>{{ formatCurrency(stats.avgDailyRevenue) }}</td>
                  <td>{{ stats.avgDailyQuantity != null ? stats.avgDailyQuantity : '-' }}</td>
                  <td>{{ stats.durationDays }}</td>
                  <td>{{ formatDate(stats.startDate) }} ~ {{ formatDate(stats.endDate) }}</td>
                </tr>
              </tbody>
            </table>
          </div>
          <div class="chart-container small">
            <canvas ref="stageCompareRef"></canvas>
          </div>
        </div>
      </div>

      <div class="panel mb-20">
        <div class="panel-header">
          <div>
            <h3>阶段建议</h3>
            <p class="panel-subtitle">按当前{{ currentConfig.entityName }}的生命周期阶段生成运营动作，后续可接入 AI 输出个性化建议。</p>
          </div>
          <el-tag type="info" effect="plain">当前阶段：{{ currentStage }}</el-tag>
        </div>
        <div class="advice-grid">
          <div
            v-for="card in stageAdviceCards"
            :key="card.stage"
            class="advice-card"
            :class="[card.className, { active: card.isCurrent }]"
          >
            <div class="advice-card-header">
              <span class="advice-icon"><i :class="card.icon"></i></span>
              <div>
                <h4>{{ card.stage }}</h4>
                <p>{{ card.summary }}</p>
              </div>
            </div>
            <div class="advice-metrics">
              <span>销售额占比 {{ card.revenuePercentage }}</span>
              <span>持续 {{ card.durationDays }} 天</span>
            </div>
            <ul>
              <li v-for="item in card.suggestions" :key="item">{{ item }}</li>
            </ul>
          </div>
        </div>
      </div>

      <div class="panel">
        <div class="panel-header">
          <h3>完整性评估细项</h3>
          <div :class="detail.is_complete ? 'success-text' : 'warning-text'">
            总分 {{ detail.completeness_score || 0 }}/100
          </div>
        </div>
        <div class="breakdown-grid">
          <div v-for="item in breakdownItems" :key="item.key" class="breakdown-item">
            <el-tag :type="item.hit ? 'success' : 'danger'" size="mini">{{ item.hit ? '命中' : '未命中' }}</el-tag>
            <span>{{ item.label }}</span>
            <strong>权重 {{ item.weight }}</strong>
          </div>
        </div>
      </div>
    </template>

    <div v-else class="empty-state">
      <i class="el-icon-data-analysis"></i>
      <p>{{ emptyMessage }}</p>
    </div>
  </div>
</template>

<script>
import { Chart } from 'chart.js'
import { formatCurrency, formatDate } from '../../../utils/format'
import {
  getLifecycleDatabaseSkuResults,
  getLifecycleDatabaseSpuResults
} from '@/api/lifecycleDatabase'

const STORAGE_KEY = 'lifecycle_database_analysis_active_view'
const CACHE_CONFIG = {
  sku: {
    resultsKey: 'lifecycle_database_analysis_sku_results',
    selectedKey: 'lifecycle_database_analysis_selected_sku'
  },
  spu: {
    resultsKey: 'lifecycle_database_analysis_spu_results',
    selectedKey: 'lifecycle_database_analysis_selected_spu'
  }
}
const DATE_RANGE_KEY = 'lifecycle_database_analysis_date_range'
const stageOrder = ['引入期', '成长期', '成熟期', '衰退期']
const lifecycleStatusOptions = {
  all: '全部生命周期',
  complete: '完整生命周期',
  incomplete: '不完整生命周期'
}
const breakdownMapping = [
  { key: 'sufficient_time', label: '时间长度≥120天' },
  { key: 'reasonable_peak_position', label: '峰值位置25%-75%' },
  { key: 'significant_growth', label: '显著增长' },
  { key: 'noticeable_decline', label: '明显衰退' },
  { key: 'has_lifecycle_shape', label: '生命周期形状' },
  { key: 'peak_significance', label: '峰值显著性' },
  { key: 'data_quality_check', label: '数据质量' },
  { key: 'cycle_completeness', label: '周期完整性' },
  { key: 'trend_consistency', label: '趋势一致性' }
]
const stageAdviceMapping = {
  引入期: {
    icon: 'el-icon-s-promotion',
    className: 'intro',
    summary: '验证市场接受度和基础转化效率。',
    suggestions: ['聚焦首批核心渠道，避免过早铺量。', '跟踪点击、加购和退款反馈，快速修正标题、价格与主图。', '准备小批量补货阈值，防止试销转好后断货。']
  },
  成长期: {
    icon: 'el-icon-top-right',
    className: 'growth',
    summary: '放大有效流量并保障供给稳定。',
    suggestions: ['提升投放和活动资源，优先放大高转化渠道。', '按销量增速校准安全库存和补货周期。', '监控毛利、评价和履约稳定性，避免增长质量下滑。']
  },
  成熟期: {
    icon: 'el-icon-medal',
    className: 'maturity',
    summary: '稳定利润表现并延长高质量销售窗口。',
    suggestions: ['保持主推资源，控制折扣频率，守住毛利。', '通过组合、赠品或会员权益提升复购和客单价。', '观察竞品价格和搜索热度，提前准备迭代款。']
  },
  衰退期: {
    icon: 'el-icon-bottom-right',
    className: 'decline',
    summary: '控制投入，降低库存和资源占用。',
    suggestions: ['减少低效投放，将预算迁移到成长或潜力商品。', '结合库存水位设置清仓、套装或尾货策略。', '复盘衰退原因，沉淀到下一代商品选品和定价。']
  }
}

const ANALYSIS_CONFIG = {
  sku: {
    label: 'SKU分析',
    entityName: 'SKU',
    entityDisplayLabel: 'SKU编码',
    exportPrefix: 'sku_lifecycle_database_results',
    fetchResults: getLifecycleDatabaseSkuResults
  },
  spu: {
    label: 'SPU分析',
    entityName: 'SPU',
    entityDisplayLabel: 'SPU编码',
    exportPrefix: 'spu_lifecycle_database_results',
    fetchResults: getLifecycleDatabaseSpuResults
  }
}

function loadCachedAnalysis(view) {
  const config = CACHE_CONFIG[view]
  try {
    const rawResults = localStorage.getItem(config.resultsKey)
    return {
      results: rawResults ? JSON.parse(rawResults) : {},
      selected: localStorage.getItem(config.selectedKey) || ''
    }
  } catch (e) {
    return { results: {}, selected: '' }
  }
}

function loadDateRange() {
  try {
    const raw = localStorage.getItem(DATE_RANGE_KEY)
    return raw ? JSON.parse(raw) : []
  } catch (e) {
    return []
  }
}

export default {
  name: 'LifecycleAnalysisDatabase',
  data() {
    return {
      activeView: localStorage.getItem(STORAGE_KEY) === 'spu' ? 'spu' : 'sku',
      dateRange: loadDateRange(),
      loading: false,
      error: '',
      lifecycleStatusFilter: 'all',
      trendChart: null,
      stageCompareChart: null,
      cache: {
        sku: loadCachedAnalysis('sku'),
        spu: loadCachedAnalysis('spu')
      }
    }
  },
  computed: {
    analysisTabs() {
      return [
        { label: 'SKU分析', value: 'sku' },
        { label: 'SPU分析', value: 'spu' }
      ]
    },
    currentConfig() {
      return ANALYSIS_CONFIG[this.activeView]
    },
    currentCache() {
      return this.cache[this.activeView] || { results: {}, selected: '' }
    },
    results() {
      return this.currentCache.results || {}
    },
    hasRawResults() {
      return this.allEntityOptions.length > 0
    },
    hasResults() {
      return this.entityOptions.length > 0
    },
    selectedValue: {
      get() {
        return this.currentCache.selected || ''
      },
      set(value) {
        this.setSelectedValue(value)
      }
    },
    allEntityOptions() {
      return Object.keys(this.results || {}).filter(key => key !== '_analysis_summary_')
    },
    entityOptions() {
      return this.allEntityOptions.filter(key => {
        if (this.lifecycleStatusFilter === 'all') return true
        const item = this.results[key]
        const isComplete = !!(item && item.is_complete)
        return this.lifecycleStatusFilter === 'complete' ? isComplete : !isComplete
      })
    },
    detail() {
      return (this.results && this.selectedValue && this.results[this.selectedValue]) || null
    },
    generatedAt() {
      return this.results && this.results._analysis_summary_ && this.results._analysis_summary_.generated_at
    },
    currentStage() {
      return (this.detail && this.detail.current_stage) || '-'
    },
    currentStageDurationDays() {
      const stats = (this.detail && this.detail.stage_statistics) || {}
      const currentStage = this.detail && this.detail.current_stage
      if (currentStage && stats[currentStage] && stats[currentStage].durationDays != null) {
        return stats[currentStage].durationDays
      }
      return '-'
    },
    displayStageStats() {
      const stats = (this.detail && this.detail.stage_statistics) || {}
      const ordered = {}
      stageOrder.forEach(stage => {
        if (stats[stage]) ordered[stage] = stats[stage]
      })
      Object.keys(stats).forEach(stage => {
        if (stageOrder.indexOf(stage) === -1) ordered[stage] = stats[stage]
      })
      return ordered
    },
    breakdownItems() {
      const details = (this.detail && this.detail.completion_details) || {}
      return breakdownMapping.map(item => {
        const current = details[item.key] || {}
        return {
          key: item.key,
          label: item.label,
          hit: !!current.hit,
          weight: current.weight != null ? current.weight : '-'
        }
      })
    },
    stageAdviceCards() {
      return stageOrder.map(stage => {
        const config = stageAdviceMapping[stage]
        const stats = (this.displayStageStats && this.displayStageStats[stage]) || {}
        return {
          stage,
          icon: config.icon,
          className: config.className,
          summary: config.summary,
          suggestions: config.suggestions,
          isCurrent: this.currentStage === stage,
          revenuePercentage: this.formatPercent(stats.revenuePercentage),
          durationDays: stats.durationDays != null ? stats.durationDays : 0
        }
      })
    },
    emptyMessage() {
      if (this.loading) return '正在加载数据库生命周期分析结果...'
      if (this.hasRawResults && !this.hasResults) {
        return `暂无${lifecycleStatusOptions[this.lifecycleStatusFilter]}的${this.currentConfig.entityName}分析结果`
      }
      return `暂无${this.currentConfig.entityName}生命周期分析结果`
    },
    totalRevenue() {
      if (this.detail && this.detail.total_revenue != null) return this.detail.total_revenue
      return 0
    },
    totalQty() {
      if (this.detail && this.detail.total_quantity != null) return this.detail.total_quantity
      return 0
    }
  },
  watch: {
    activeView() {
      localStorage.setItem(STORAGE_KEY, this.activeView)
      this.initCurrentView()
    },
    dateRange() {
      try {
        localStorage.setItem(DATE_RANGE_KEY, JSON.stringify(this.dateRange || []))
      } catch (e) {}
    },
    lifecycleStatusFilter() {
      this.ensureCurrentSelection()
    },
    detail() {
      this.$nextTick(() => {
        this.renderTrend()
        this.renderStageCompare()
      })
    },
    results() {
      this.ensureCurrentSelection()
    }
  },
  mounted() {
    this.initCurrentView()
  },
  beforeDestroy() {
    this.destroyCharts()
  },
  methods: {
    formatCurrency,
    formatDate,
    switchAnalysis(view) {
      if (view === this.activeView) return
      this.activeView = view
    },
    initCurrentView() {
      if (!this.hasRawResults) {
        this.getList()
        return
      }
      this.ensureCurrentSelection()
      this.$nextTick(() => {
        this.renderTrend()
        this.renderStageCompare()
      })
    },
    getParams() {
      const params = {}
      if (this.dateRange && this.dateRange.length === 2) {
        params.startDate = this.dateRange[0]
        params.endDate = this.dateRange[1]
      }
      return params
    },
    persistCurrentCache() {
      const config = CACHE_CONFIG[this.activeView]
      const cache = this.currentCache
      try {
        localStorage.setItem(config.resultsKey, JSON.stringify(cache.results || {}))
        localStorage.setItem(config.selectedKey, cache.selected || '')
      } catch (e) {}
    },
    setCurrentResults(results) {
      this.$set(this.cache, this.activeView, Object.assign({}, this.currentCache, {
        results: results || {}
      }))
      this.persistCurrentCache()
    },
    setSelectedValue(value) {
      this.$set(this.cache, this.activeView, Object.assign({}, this.currentCache, {
        selected: value || ''
      }))
      this.persistCurrentCache()
    },
    ensureCurrentSelection() {
      if (!this.hasRawResults) {
        this.selectedValue = ''
        this.destroyCharts()
        return
      }
      if (!this.hasResults) {
        this.selectedValue = ''
        this.destroyCharts()
        return
      }
      if (!this.selectedValue || this.entityOptions.indexOf(this.selectedValue) === -1) {
        this.selectedValue = this.pickFirstValue(this.results)
      }
    },
    getList() {
      this.loading = true
      this.error = ''
      this.currentConfig.fetchResults(this.getParams()).then(response => {
        const results = response && response.data ? response.data : {}
        this.setCurrentResults(results)
        this.setSelectedValue(this.pickFirstValue(results))
        this.$nextTick(() => {
          this.renderTrend()
          this.renderStageCompare()
        })
      }).catch(error => {
        this.error = (error && error.message) || '获取数据库生命周期分析结果失败'
        if (!this.hasResults) {
          this.setCurrentResults({})
        }
      }).finally(() => {
        this.loading = false
      })
    },
    formatPercent(value) {
      if (value == null || Number.isNaN(Number(value))) return '-'
      return `${Number(value).toFixed(1)}%`
    },
    stageClass(stage) {
      if (!stage) return ''
      if (stage.indexOf('引入') >= 0 || stage.indexOf('导入') >= 0) return 'intro'
      if (stage.indexOf('成长') >= 0) return 'growth'
      if (stage.indexOf('成熟') >= 0) return 'maturity'
      if (stage.indexOf('衰退') >= 0) return 'decline'
      return ''
    },
    stageTagType(stage) {
      if (stage.indexOf('成长') >= 0) return 'success'
      if (stage.indexOf('成熟') >= 0) return 'warning'
      if (stage.indexOf('衰退') >= 0) return 'danger'
      return 'info'
    },
    normalizeDate(dateStr) {
      if (!dateStr) return ''
      const match = String(dateStr).match(/(\d{4}-\d{2}-\d{2})/)
      if (match) return match[1]
      const parts = String(dateStr).split('T')
      return parts[0].split(' ')[0]
    },
    destroyCharts() {
      if (this.trendChart) {
        this.trendChart.destroy()
        this.trendChart = null
      }
      if (this.stageCompareChart) {
        this.stageCompareChart.destroy()
        this.stageCompareChart = null
      }
    },
    renderTrend() {
      const canvas = this.$refs.lifeCycleTrendRef
      if (!canvas || !this.detail) {
        if (this.trendChart) {
          this.trendChart.destroy()
          this.trendChart = null
        }
        return
      }

      const detail = this.detail || {}
      const revenue = detail.smoothed_revenue || detail.revenue_series || []
      const qty = detail.smoothed_quantity || detail.quantity_series || []
      const rawDates = detail.date_series || []
      const labels = rawDates.map(date => formatDate(date))
      const stagesMap = detail.stages_map || []
      const stageColors = {
        引入期: 'rgba(59,130,246,0.08)',
        成长期: 'rgba(16,185,129,0.10)',
        成熟期: 'rgba(245,158,11,0.10)',
        衰退期: 'rgba(239,68,68,0.08)'
      }
      const segments = this.buildStageSegments(stagesMap, labels)
      const peakRevenueIndex = this.resolvePeakIndex(detail.peak_revenue_date, detail.revenue_peak_idx, rawDates)
      const peakQtyIndex = this.resolvePeakIndex(detail.peak_quantity_date, detail.quantity_peak_idx, rawDates)

      if (this.trendChart) this.trendChart.destroy()
      this.trendChart = new Chart(canvas, {
        type: 'line',
        data: {
          labels,
          datasets: [
            { label: '销售额', data: revenue, borderColor: '#3b82f6', backgroundColor: 'rgba(59,130,246,0.15)', lineTension: 0.25, pointRadius: 0 },
            { label: '销量', data: qty, borderColor: '#64748b', backgroundColor: 'rgba(100,116,139,0.15)', lineTension: 0.25, pointRadius: 0 }
          ]
        },
        options: {
          responsive: true,
          maintainAspectRatio: false,
          hover: { mode: 'index', intersect: false },
          tooltips: {
            callbacks: {
              title(context) {
                return `日期: ${context[0].label}`
              },
              label(context, data) {
                return `${data.datasets[context.datasetIndex].label}: ${Number(context.value).toLocaleString()}`
              }
            }
          },
          scales: {
            xAxes: [{ ticks: { maxRotation: 0, autoSkip: true, maxTicksLimit: 12 } }],
            yAxes: [{ ticks: { beginAtZero: true } }]
          }
        },
        plugins: [{
          beforeDatasetsDraw(chart) {
            const ctx = chart.ctx
            const chartArea = chart.chartArea
            const xScale = chart.scales['x-axis-0']
            if (!segments.length) return
            ctx.save()
            segments.forEach(segment => {
              const startX = xScale.getPixelForValue(segment.start)
              const endX = xScale.getPixelForValue(segment.end)
              ctx.fillStyle = stageColors[segment.stage] || 'rgba(0,0,0,0.04)'
              ctx.fillRect(startX, chartArea.top, endX - startX, chartArea.bottom - chartArea.top)
              ctx.fillStyle = '#374151'
              ctx.font = 'bold 12px sans-serif'
              ctx.fillText(segment.stage, startX + 4, chartArea.top + 14)
            })
            ctx.restore()
          }
        }, {
          afterDatasetsDraw(chart) {
            const ctx = chart.ctx
            const xScale = chart.scales['x-axis-0']
            const yScale = chart.scales['y-axis-0']
            ctx.save()
            drawPeak(ctx, xScale, yScale, revenue, peakRevenueIndex, '#dc2626', '销售额峰值')
            drawPeak(ctx, xScale, yScale, qty, peakQtyIndex, '#2563eb', '销量峰值')
            ctx.restore()
          }
        }]
      })

      function drawPeak(ctx, xScale, yScale, data, index, color, label) {
        if (index < 0 || index >= data.length || data[index] == null) return
        const x = xScale.getPixelForValue(index)
        const y = yScale.getPixelForValue(data[index])
        ctx.fillStyle = color
        ctx.beginPath()
        ctx.arc(x, y, 5, 0, Math.PI * 2)
        ctx.fill()
        ctx.fillStyle = color
        ctx.font = 'bold 12px sans-serif'
        ctx.fillText(label, x + 10, y - 10)
      }
    },
    buildStageSegments(stagesMap, labels) {
      const segments = []
      if (!stagesMap.length || stagesMap.length !== labels.length) return segments
      let currentStage = stagesMap[0]
      let segmentStart = 0
      for (let i = 1; i < stagesMap.length; i++) {
        if (stagesMap[i] !== currentStage) {
          segments.push({ start: segmentStart, end: i - 1, stage: currentStage })
          currentStage = stagesMap[i]
          segmentStart = i
        }
      }
      segments.push({ start: segmentStart, end: stagesMap.length - 1, stage: currentStage })
      return segments
    },
    resolvePeakIndex(date, fallback, rawDates) {
      if (date && rawDates.length > 0) {
        const target = this.normalizeDate(date)
        const index = rawDates.findIndex(item => this.normalizeDate(item) === target)
        if (index >= 0) return index
      }
      return fallback != null ? fallback : -1
    },
    renderStageCompare() {
      const canvas = this.$refs.stageCompareRef
      if (!canvas || !this.detail) {
        if (this.stageCompareChart) {
          this.stageCompareChart.destroy()
          this.stageCompareChart = null
        }
        return
      }

      const stats = this.displayStageStats || {}
      const labels = stageOrder.filter(stage => stats[stage]).concat(Object.keys(stats).filter(stage => stageOrder.indexOf(stage) === -1))
      const revenueData = labels.map(stage => (stats[stage] && stats[stage].totalRevenue) || 0)
      const qtyData = labels.map(stage => (stats[stage] && stats[stage].totalQuantity) || 0)
      const durationData = labels.map(stage => (stats[stage] && stats[stage].durationDays) || 0)

      if (this.stageCompareChart) this.stageCompareChart.destroy()
      this.stageCompareChart = new Chart(canvas, {
        type: 'bar',
        data: {
          labels,
          datasets: [
            { label: '销售额', data: revenueData, backgroundColor: 'rgba(59,130,246,0.7)' },
            { label: '销量', data: qtyData, backgroundColor: 'rgba(16,185,129,0.7)' },
            { label: '持续天数', data: durationData, backgroundColor: 'rgba(245,158,11,0.7)' }
          ]
        },
        options: {
          responsive: true,
          maintainAspectRatio: false,
          scales: {
            xAxes: [{ stacked: false }],
            yAxes: [{ ticks: { beginAtZero: true } }]
          }
        }
      })
    },
    formatUploadDate(date) {
      const target = date instanceof Date ? date : new Date(date)
      if (Number.isNaN(target.getTime())) return ''
      const year = target.getFullYear()
      const month = String(target.getMonth() + 1).padStart(2, '0')
      const day = String(target.getDate()).padStart(2, '0')
      return `${year}-${month}-${day}`
    },
    exportResults() {
      if (!this.hasRawResults) {
        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 link = document.createElement('a')
      link.href = url
      link.download = `${this.currentConfig.exportPrefix}_${this.formatUploadDate(new Date())}.json`
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      URL.revokeObjectURL(url)
    },
    pickFirstValue(results) {
      const keys = Object.keys(results || {})
      return keys.find(key => {
        if (key === '_analysis_summary_') return false
        if (this.lifecycleStatusFilter === 'all') return true
        const item = results[key]
        const isComplete = !!(item && item.is_complete)
        return this.lifecycleStatusFilter === 'complete' ? isComplete : !isComplete
      }) || ''
    }
  }
}
</script>

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

.page-header,
.query-toolbar,
.panel-header,
.chart-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

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

.analysis-switch {
  display: inline-flex;
  padding: 4px;
  border-radius: 10px;
  background: #f3f6fb;
  border: 1px solid #dce6f2;
}

.switch-btn {
  border: none;
  background: transparent;
  color: #606266;
  padding: 8px 16px;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
}

.switch-btn.active {
  background: #ffffff;
  color: #2563eb;
  box-shadow: 0 2px 8px rgba(37, 99, 235, 0.12);
}

.query-toolbar {
  align-items: center;
  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);
}

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

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

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

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

  h3 {
    margin: 0 0 18px;
    font-size: 18px;
    color: #303133;
  }
}

.panel-subtitle {
  margin: -10px 0 0;
  color: #909399;
  font-size: 13px;
  line-height: 1.6;
}

.selector-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.entity-select {
  width: 260px;
}

.status-select {
  width: 150px;
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 16px;
  margin-top: 20px;
}

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

.stat-label {
  font-size: 12px;
  color: #909399;
  margin: 0 0 8px;
}

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

.sub-value {
  font-size: 13px;
  color: #6b7280;
}

.success-text {
  color: #16a34a;
}

.warning-text {
  color: #d97706;
}

.chart-container {
  height: 360px;
}

.chart-container.small {
  height: 240px;
  margin-top: 24px;
}

.legend {
  display: flex;
  align-items: center;
  gap: 14px;
  color: #606266;
  font-size: 13px;
}

.dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-right: 6px;
}

.dot.blue {
  background: #3b82f6;
}

.dot.gray {
  background: #64748b;
}

.content-grid {
  display: grid;
  grid-template-columns: minmax(280px, 1fr) minmax(0, 2fr);
  gap: 20px;
}

.metric-list {
  display: grid;
  gap: 12px;
}

.metric-row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  color: #606266;
  font-size: 14px;

  strong {
    color: #303133;
  }
}

.metric-row.muted {
  font-size: 13px;
  color: #909399;
}

.text-right {
  text-align: right;
}

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

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

  th,
  td {
    padding: 10px 12px;
    border-bottom: 1px solid #e5e7eb;
    text-align: left;
    font-size: 13px;
    white-space: nowrap;
  }

  th {
    color: #606266;
    background: #f8fafc;
  }
}

.lifecycle-stage {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
}

.lifecycle-stage.intro {
  background: #dbeafe;
  color: #1d4ed8;
}

.lifecycle-stage.growth {
  background: #d1fae5;
  color: #047857;
}

.lifecycle-stage.maturity {
  background: #fef3c7;
  color: #b45309;
}

.lifecycle-stage.decline {
  background: #fee2e2;
  color: #b91c1c;
}

.advice-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
  margin-top: 18px;
}

.advice-card {
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  background: #ffffff;
  padding: 16px;
  min-height: 260px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  position: relative;
}

.advice-card.active {
  border-color: #409eff;
  box-shadow: 0 6px 16px rgba(64, 158, 255, 0.12);
}

.advice-card::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  border-radius: 8px 0 0 8px;
  background: #94a3b8;
}

.advice-card.intro::before {
  background: #3b82f6;
}

.advice-card.growth::before {
  background: #10b981;
}

.advice-card.maturity::before {
  background: #f59e0b;
}

.advice-card.decline::before {
  background: #ef4444;
}

.advice-card-header {
  display: flex;
  gap: 12px;
  align-items: flex-start;

  h4 {
    margin: 0 0 6px;
    font-size: 16px;
    color: #303133;
  }

  p {
    margin: 0;
    color: #606266;
    font-size: 13px;
    line-height: 1.5;
  }
}

.advice-icon {
  width: 34px;
  height: 34px;
  border-radius: 8px;
  background: #f1f5f9;
  color: #2563eb;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  font-size: 18px;
}

.advice-metrics {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;

  span {
    font-size: 12px;
    color: #475569;
    background: #f8fafc;
    border: 1px solid #e2e8f0;
    border-radius: 6px;
    padding: 5px 8px;
  }
}

.advice-card ul {
  margin: 0;
  padding-left: 18px;
  color: #475569;
  font-size: 13px;
  line-height: 1.7;
}

.advice-card li + li {
  margin-top: 6px;
}

.breakdown-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 12px;
}

.breakdown-item {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 12px;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  background: #f9fafb;
  font-size: 13px;
}

.empty-state {
  background: #ffffff;
  border: 1px dashed #d1d5db;
  border-radius: 12px;
  padding: 72px 20px;
  text-align: center;
  color: #909399;

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

.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 900px) {
  .page-header,
  .query-toolbar,
  .panel-header,
  .chart-header {
    flex-direction: column;
    align-items: stretch;
  }

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

  .entity-select {
    width: 100%;
  }

  .status-select {
    width: 100%;
  }
}
</style>
