<template>
  <div class="shop-value-analysis-page order-dashboard-page">
    <header class="page-header">
      <div>
        <h1 class="main-title">店铺价值分析</h1>
        <p class="subtitle">实时监控关键指标与趋势</p>
      </div>
    </header>

    <OrderDateRangeFilter
      :max-date="maxDate"
      default-period="day"
      storage-key="dtm-shop-date-filter"
      @change="handleFilterChange"
    />

    <div class="chart-card">
      <OrderLoadingPanel
        v-if="topProductLoading"
        title="正在加载店铺价值指标"
        detail="正在读取 Top 5 商品销售额与贡献占比"
      />
      <div class="top-product-contribution-container">
        <div class="kpi-card-grid">
          <div class="kpi-card">
            <span class="kpi-title">总销售额</span>
            <span class="kpi-value">¥{{ formatNumber(topProductData.totalSales) }}</span>
          </div>
          <div class="kpi-card">
            <span class="kpi-title">Top 5 商品总销售额</span>
            <span class="kpi-value">¥{{ formatNumber(topProductData.top5TotalSales) }}</span>
          </div>
          <div class="kpi-card">
            <span class="kpi-title">Top 5 贡献占比</span>
            <span class="kpi-value">{{ (topProductData.contributionRatio * 100).toFixed(2) }}%</span>
          </div>
        </div>

        <div class="chart-card inner-chart-card">
          <h3 class="chart-title">Top 5 商品销售分布</h3>
          <div ref="donutChartRef" style="width: 100%; height: 400px;"></div>
        </div>
      </div>
    </div>

    <div class="charts-container">
      <div class="chart-card">
        <OrderLoadingPanel
          v-if="chartsLoading"
          title="正在加载部门业绩数据"
          detail="正在汇总各部门销量与销售额"
        />
        <div class="card-header">
          <h3 class="chart-title">各部门业绩分析（销量 / 销售额）</h3>
        </div>
        <div class="chart-wrapper">
          <div ref="unitContributionChart" class="chart-instance"></div>
        </div>
      </div>

      <div class="chart-card">
        <OrderLoadingPanel
          v-if="chartsLoading"
          title="正在加载渠道业绩数据"
          detail="正在汇总各渠道销量与销售额"
        />
        <div class="card-header">
          <h3 class="chart-title">各渠道业绩分析（销量 / 销售额）</h3>
        </div>
        <div class="chart-wrapper">
          <div ref="channelTotalChart" class="chart-instance"></div>
        </div>
      </div>

      <div class="chart-card">
        <OrderLoadingPanel
          v-if="chartsLoading"
          title="正在加载平台价值数据"
          detail="正在分析各平台销量与平均订单价值"
        />
        <div class="card-header">
          <h3 class="chart-title">各平台价值分析（销量 / 销售额）</h3>
        </div>
        <div class="chart-wrapper">
          <div ref="platformChart" class="chart-instance"></div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import * as echarts from 'echarts'
import OrderLoadingPanel from '../components/OrderLoadingPanel.vue'
import OrderDateRangeFilter from '../components/OrderDateRangeFilter.vue'
import {
  getShopChannelContribution,
  getShopChannelRoiValue,
  getShopChannelTotalContribution,
  getShopMaxDate,
  getShopTopProductContribution,
  getShopUnitContribution
} from '@/api/order'

export default {
  name: 'ShopValue',
  components: {
    OrderLoadingPanel,
    OrderDateRangeFilter
  },
  data() {
    return {
      topProductData: {
        totalSales: 0,
        top5TotalSales: 0,
        contributionRatio: 0,
        top5Products: []
      },
      topProductLoading: true,
      chartsLoading: true,
      selectedDate: '',
      maxDate: '',
      activeTab: '7d',
      currentDateRange: { start: '', end: '' },
      pickerOptions: {
        disabledDate: time => {
          if (!this.maxDate) return false
          return time.getTime() > new Date(`${this.maxDate}T23:59:59`).getTime()
        }
      }
    }
  },
  mounted() {
    this.initDashboard()
    window.addEventListener('resize', this.handleResize)
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.handleResize)
  },
  methods: {
    handleFilterChange(params) {
      this.activeTab = params.periodType || 'day'
      this.currentDateRange = {
        start: params.startDate || this.maxDate,
        end: params.endDate || this.maxDate
      }
      this.fetchData()
    },
    getQueryParams() {
      return {
        startDate: this.currentDateRange.start,
        endDate: this.currentDateRange.end
      }
    },
    handleDateChange() {
      if (!this.selectedDate) {
        this.selectedDate = this.maxDate
      }
      this.applyDateFilter(this.activeTab)
    },
    pad2(value) {
      return String(value).padStart(2, '0')
    },
    toDate(value) {
      if (value instanceof Date) return new Date(value.getTime())
      if (!value) return new Date()
      return new Date(`${value}T00:00:00`)
    },
    formatYmd(value) {
      const date = this.toDate(value)
      return `${date.getFullYear()}-${this.pad2(date.getMonth() + 1)}-${this.pad2(date.getDate())}`
    },
    addDays(value, days) {
      const date = this.toDate(value)
      date.setDate(date.getDate() + days)
      return date
    },
    addMonths(value, months) {
      const date = this.toDate(value)
      date.setMonth(date.getMonth() + months)
      return date
    },
    startOfMonth(value) {
      const date = this.toDate(value)
      return new Date(date.getFullYear(), date.getMonth(), 1)
    },
    endOfMonth(value) {
      const date = this.toDate(value)
      return new Date(date.getFullYear(), date.getMonth() + 1, 0)
    },
    buildRange(type = this.activeTab) {
      const baseDate = this.toDate(this.selectedDate || this.maxDate || new Date())
      if (type === 'day') {
        const day = this.formatYmd(baseDate)
        return { start: day, end: day }
      }
      if (type === '7d') {
        return {
          start: this.formatYmd(this.addDays(baseDate, -6)),
          end: this.formatYmd(baseDate)
        }
      }
      if (type === 'tm') {
        return {
          start: this.formatYmd(this.startOfMonth(baseDate)),
          end: this.formatYmd(this.endOfMonth(baseDate))
        }
      }
      if (type === 'lm') {
        const lastMonth = this.addMonths(baseDate, -1)
        return {
          start: this.formatYmd(this.startOfMonth(lastMonth)),
          end: this.formatYmd(this.endOfMonth(lastMonth))
        }
      }
      return {
        start: '2022-01-01',
        end: this.maxDate || this.formatYmd(baseDate)
      }
    },
    async initDashboard() {
      try {
        const maxDate = await getShopMaxDate()
        this.maxDate = maxDate
      } catch (error) {
        console.error('获取店铺最大日期失败:', error)
        const today = this.formatYmd(new Date())
        this.maxDate = today
      }
    },
    async applyDateFilter(type) {
      this.activeTab = type
      this.currentDateRange = this.buildRange(type)
      await this.fetchData()
    },
    formatNumber(num) {
      if (!num) return '0'
      return new Intl.NumberFormat().format(Number(num).toFixed(0))
    },
    handleResize() {
      const refs = this.$refs
      if (refs.unitContributionChart) echarts.getInstanceByDom(refs.unitContributionChart)?.resize()
      if (refs.channelTotalChart) echarts.getInstanceByDom(refs.channelTotalChart)?.resize()
      if (refs.platformChart) echarts.getInstanceByDom(refs.platformChart)?.resize()
      if (refs.donutChartRef) echarts.getInstanceByDom(refs.donutChartRef)?.resize()
    },
    initDonutChart(chartData) {
      const chartEl = this.$refs.donutChartRef
      if (!chartEl) return
      const myChart = echarts.getInstanceByDom(chartEl) || echarts.init(chartEl)
      myChart.setOption({
        tooltip: {
          trigger: 'item',
          formatter: '{a}<br/>{b}: ¥{c} ({d}%)'
        },
        legend: {
          orient: 'horizontal',
          bottom: '0%',
          left: 'center'
        },
        series: [{
          name: '销售额',
          type: 'pie',
          radius: ['60%', '80%'],
          avoidLabelOverlap: false,
          label: {
            show: true,
            position: 'outside',
            formatter: '{b}: {d}%'
          },
          labelLine: {
            show: true,
            length: 15,
            length2: 10
          },
          emphasis: {
            label: {
              show: true,
              fontSize: 14,
              fontWeight: 'bold'
            }
          },
          data: chartData
        }]
      }, true)
    },
    async fetchTopProductData() {
      this.topProductLoading = true
      try {
        const response = await getShopTopProductContribution(this.getQueryParams())
        if (!response?.success) return
        const data = response.data || {}
        this.topProductData.totalSales = data.totalSales || 0
        this.topProductData.top5TotalSales = data.top5TotalSales || 0
        this.topProductData.contributionRatio = data.contributionRatio || 0
        this.topProductData.top5Products = data.top5Products || []

        const chartData = this.topProductData.top5Products.map(item => ({
          name: item.productCode,
          value: item.salesAmount
        }))
        this.initDonutChart(chartData)
      } catch (error) {
        console.error('获取 Top 5 商品贡献失败:', error)
      }
    },
    finishTopProductLoading() {
      this.topProductLoading = false
    },
    initDualIndicatorBarChart(chartEl, data, categoryKey, seriesConfig) {
      if (!chartEl) return
      const spacePerBar = 120
      chartEl.style.width = `${Math.max(800, spacePerBar * data.length)}px`

      const myChart = echarts.getInstanceByDom(chartEl) || echarts.init(chartEl)
      const categories = data.map(item => item[categoryKey])
      const series = seriesConfig.map(({ key, name, color }) => ({
        name,
        type: 'bar',
        data: data.map(item => item[key]),
        barMaxWidth: '40px',
        itemStyle: { color, borderRadius: [4, 4, 0, 0] },
        yAxisIndex: seriesConfig.findIndex(config => config.key === key)
      }))

      myChart.setOption({
        tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
        legend: { data: seriesConfig.map(item => item.name), top: 0 },
        grid: { left: '80px', right: '80px', top: '40px', bottom: '60px' },
        xAxis: {
          type: 'category',
          data: categories,
          axisLabel: { interval: 0, rotate: 45, color: '#666', margin: 20 },
          axisTick: { alignWithLabel: true }
        },
        yAxis: seriesConfig.map(({ name, formatter }, index) => ({
          type: 'value',
          name,
          nameTextStyle: { color: '#666' },
          axisLabel: {
            color: '#666',
            formatter: formatter || (value => {
              if (value >= 1000000) return `${value / 1000000}M`
              if (value >= 1000) return `${value / 1000}K`
              return value
            })
          },
          position: index === 0 ? 'left' : 'right',
          offset: index === 1 ? 40 : 0
        })),
        series
      }, true)
    },
    initPlatformValueChart(chartEl, data) {
      if (!chartEl) return
      const spacePerBar = 140
      chartEl.style.width = `${Math.max(800, spacePerBar * data.length)}px`

      const myChart = echarts.getInstanceByDom(chartEl) || echarts.init(chartEl)
      const categories = data.map(item => item.name)

      myChart.setOption({
        tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
        legend: { data: ['销量', '销售额'], top: 0 },
        grid: { left: '80px', right: '80px', top: '40px', bottom: '60px' },
        xAxis: {
          type: 'category',
          data: categories,
          axisLabel: { interval: 0, rotate: 45, color: '#666', margin: 20 },
          axisTick: { alignWithLabel: true }
        },
        yAxis: [
          {
            type: 'value',
            name: '销量',
            nameTextStyle: { color: '#666' },
            axisLabel: {
              color: '#5470c6',
              formatter: value => {
                if (value >= 1000000) return `${value / 1000000}M`
                if (value >= 1000) return `${value / 1000}K`
                return value
              }
            }
          },
          {
            type: 'value',
            name: '销售额(元)',
            nameTextStyle: { color: '#e9c46a' },
            axisLabel: {
              color: '#e9c46a',
              formatter: value => `¥${Number(value).toFixed(2)}`
            },
            position: 'right',
            offset: 40
          }
        ],
        series: [
          {
            name: '销量',
            type: 'bar',
            data: data.map(item => item.totalVolume),
            barMaxWidth: '40px',
            itemStyle: { color: '#5470c6', borderRadius: [4, 4, 0, 0] },
            yAxisIndex: 0
          },
          {
            name: '销售额',
            type: 'bar',
            data: data.map(item => item.avgOrderValue),
            barMaxWidth: '40px',
            itemStyle: { color: '#e9c46a', borderRadius: [4, 4, 0, 0] },
            yAxisIndex: 1
          }
        ]
      }, true)
    },
    async fetchData() {
      this.chartsLoading = true
      try {
        const params = this.getQueryParams()
        const [unitRes, channelTotalRes, channelContributionRes, channelRoiValueRes] = await Promise.all([
          getShopUnitContribution(params),
          getShopChannelTotalContribution(params),
          getShopChannelContribution(params),
          getShopChannelRoiValue(params)
        ])

        if (unitRes?.success && unitRes.data) {
          this.initDualIndicatorBarChart(this.$refs.unitContributionChart, unitRes.data, 'name', [
            { key: 'totalVolume', name: '销量', color: '#5470c6' },
            {
              key: 'totalAmount',
              name: '销售额(元)',
              color: '#91cc75',
              formatter: value => `¥${value >= 10000 ? `${value / 10000}w` : value}`
            }
          ])
        }

        if (channelTotalRes?.success && channelTotalRes.data) {
          this.initDualIndicatorBarChart(this.$refs.channelTotalChart, channelTotalRes.data, 'name', [
            { key: 'totalVolume', name: '销量', color: '#5470c6' },
            {
              key: 'totalAmount',
              name: '销售额(元)',
              color: '#e9c46a',
              formatter: value => `¥${value >= 10000 ? `${value / 10000}w` : value}`
            }
          ])
        }

        if (channelContributionRes?.success && channelRoiValueRes?.success && channelContributionRes.data && channelRoiValueRes.data) {
          const platformSales = Object.entries(channelContributionRes.data).map(([name, value]) => ({
            name,
            totalVolume: Number(value)
          }))
          const platformAvgOrder = Object.entries(channelRoiValueRes.data).map(([name, value]) => ({
            name,
            avgOrderValue: Number(value)
          }))
          const mergedData = platformSales
            .map(item => ({
              ...item,
              avgOrderValue: platformAvgOrder.find(avg => avg.name === item.name)?.avgOrderValue || 0
            }))
            .sort((a, b) => b.totalVolume - a.totalVolume)

          this.initPlatformValueChart(this.$refs.platformChart, mergedData)
        }

        await this.fetchTopProductData()
        this.finishTopProductLoading()
        this.chartsLoading = false
      } catch (error) {
        console.error('获取店铺价值数据失败:', error)
      }
      this.chartsLoading = false
      this.finishTopProductLoading()
    }
  }
}
</script>

<style scoped>
.shop-value-analysis-page {
  padding: 24px;
  background-color: #f4f7f9;
  font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;
}

.page-header {
  margin-bottom: 20px;
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.main-title {
  font-size: 24px;
  font-weight: 600;
  color: #1d2129;
}

.subtitle {
  font-size: 14px;
  color: #86909c;
  margin-top: 4px;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.control-label {
  font-size: 14px;
  color: #666;
}

.date-picker {
  width: 150px;
}

.tab-group {
  display: flex;
  gap: 8px;
}

.time-tab {
  padding: 6px 14px;
  border: 1px solid #ddd;
  background: #fff;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s;
}

.time-tab.active {
  background-color: #188df0;
  color: #fff;
  border-color: #188df0;
}

.charts-container {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.chart-card {
  position: relative;
  background: #fff;
  padding: 24px;
  border-radius: 4px;
  border: 1px solid #e5e6eb;
  display: grid;
  grid-template-rows: auto 1fr;
  overflow: hidden;
}

.inner-chart-card {
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
}

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

.chart-title {
  font-size: 16px;
  font-weight: 600;
  color: #1d2129;
}

.chart-wrapper {
  overflow-x: auto;
  overflow-y: hidden;
  min-width: 0;
}

.chart-instance {
  height: 400px;
}

.chart-wrapper::-webkit-scrollbar {
  height: 8px;
}

.chart-wrapper::-webkit-scrollbar-track {
  background: #f1f1f1;
}

.chart-wrapper::-webkit-scrollbar-thumb {
  background: #c9cdd4;
  border-radius: 4px;
}

.top-product-contribution-container {
  display: flex;
  flex-direction: column;
  gap: 20px;
  width: 100%;
}

.kpi-card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

.kpi-card {
  background-color: #fff;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
}

.kpi-title {
  font-size: 14px;
  color: #666;
  margin-bottom: 10px;
}

.kpi-value {
  font-size: 28px;
  font-weight: bold;
  color: #333;
}
</style>
