<template>
  <div class="app-container" v-loading="loading">
    <!-- 查询条件（始终展示，避免找不到京粉账号筛选） -->
    <el-card class="filter-card">
      <div slot="header" class="filter-card-header">
        <span class="filter-card-title">筛选条件</span>
        <right-toolbar :search="false" @queryTable="getStatistics" />
      </div>
      <el-alert
        v-if="adminUnionNotice"
        :title="adminUnionNotice"
        type="warning"
        :closable="false"
        show-icon
        class="admin-alert"
      />
      <el-form :model="queryParams" ref="queryForm" :inline="true" size="small" label-width="88px">
        <el-form-item label="京粉账号" prop="unionId" class="union-form-item">
          <el-select
            v-model="queryParams.unionId"
            placeholder="选择京粉 / 联盟账号（与「订单列表」页同一数据源）"
            clearable
            filterable
            style="width: 280px"
          >
            <el-option
              v-for="admin in adminList"
              :key="String(admin.value || admin.id)"
              :label="admin.label || (admin.name + ' (' + admin.wxid + ')')"
              :value="admin.value != null ? admin.value : admin.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="时间范围">
          <el-date-picker
            v-model="dateRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            value-format="yyyy-MM-dd"
            style="width: 260px"
            @change="handleDateRangeChange"
          />
        </el-form-item>
        <el-form-item label="订单状态" prop="validCode">
          <el-select v-model="queryParams.validCode" placeholder="全部状态" clearable style="width: 160px">
            <el-option
              v-for="dict in validCodeOptions"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="商品SKU" prop="skuId">
          <el-input
            v-model="queryParams.skuId"
            placeholder="SKU ID"
            clearable
            style="width: 160px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="el-icon-search" @click="handleQuery">查询</el-button>
          <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <!-- 统计卡片：与列表页口径对齐，总佣金=后端 totalCommission（预估佣金口径） -->
    <el-row :gutter="16" class="summary-row">
      <el-col v-for="item in summaryItems" :key="item.key" :xs="24" :sm="12" :md="8" :lg="4">
        <el-card class="summary-card" shadow="hover">
          <div class="summary-card-inner">
            <div class="summary-title">{{ item.title }}</div>
            <div class="summary-value">
              <template v-if="item.money">¥{{ item.display }}</template>
              <template v-else>{{ item.display }}</template>
            </div>
            <div class="summary-hint">{{ item.hint }}</div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 图表区域 -->
    <el-row :gutter="16" class="charts-row">
      <el-col :xs="24" :lg="12">
        <el-card shadow="hover">
          <div slot="header" class="card-header-plain">
            <span>订单状态分布</span>
          </div>
          <div class="chart-container">
            <div ref="statusChart" class="chart-el" />
          </div>
        </el-card>
      </el-col>
      <el-col :xs="24" :lg="12">
        <el-card shadow="hover">
          <div slot="header" class="card-header-plain">
            <span>佣金分布（预估，按状态分组）</span>
          </div>
          <div class="chart-container">
            <div ref="commissionChart" class="chart-el" />
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 状态详情表格（分组顺序与列表页一致） -->
    <el-row :gutter="16" class="table-row">
      <el-col :span="24">
        <el-card shadow="hover">
          <div slot="header" class="card-header-plain">
            <span>订单状态详情</span>
          </div>
          <el-table :data="statusDetails" stripe style="width: 100%">
            <el-table-column prop="label" label="状态" min-width="100" />
            <el-table-column prop="count" label="订单数" width="100" align="center" />
            <el-table-column prop="skuNum" label="商品件数" width="100" align="center" />
            <el-table-column prop="commission" label="预估佣金" min-width="110" align="right">
              <template slot-scope="scope">¥{{ formatMoney(scope.row.commission) }}</template>
            </el-table-column>
            <el-table-column prop="actualFee" label="实际(分组)" min-width="110" align="right">
              <template slot-scope="scope">¥{{ formatMoney(scope.row.actualFee) }}</template>
            </el-table-column>
            <el-table-column prop="percentage" label="占比" width="88" align="center">
              <template slot-scope="scope">{{ scope.row.percentage }}%</template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import * as echarts from 'echarts'
import { debounce } from '@/utils'
import { getOrderStatistics, getValidCodeSelectData } from '@/api/system/orderrows'
import { getAdminSelectData } from '@/api/system/superadmin'

/** 与列表页、后端 groupStats 逻辑顺序一致 */
const GROUP_STAT_ORDER = ['pending', 'paid', 'deposit', 'finished', 'cancel', 'invalid', 'illegal']

const PIE_COLORS = ['#e6a23c', '#409eff', '#909399', '#67c23a', '#f56c6c', '#c0c4cc', '#f78989']

export default {
  name: 'OrderStatistics',
  data() {
    return {
      loading: false,
      /** 京粉下拉的独立加载状态（避免 validCode 接口失败拖垮 admin 列表） */
      _adminListLoaded: false,
      _adminListError: false,
      queryParams: {
        beginTime: null,
        endTime: null,
        validCode: null,
        skuId: null,
        unionId: null
      },
      dateRange: [],
      validCodeOptions: [],
      adminList: [],
      statistics: {
        totalOrders: 0,
        totalCosPrice: 0,
        totalCommission: 0,
        estimatePaidPending: 0,
        totalSkuNum: 0,
        totalActualFee: 0,
        groupStats: {}
      },
      statusDetails: [],
      _statusChart: null,
      _commissionChart: null,
      _chartResize: null
    }
  },
  computed: {
    summaryItems() {
      const s = this.statistics
      return [
        {
          key: 'orders',
          title: '总订单数',
          money: false,
          display: s.totalOrders || 0,
          hint: '符合当前筛选'
        },
        {
          key: 'cos',
          title: '总计佣金额',
          money: true,
          display: this.formatMoney(s.totalCosPrice),
          hint: 'estimateCosPrice 汇总'
        },
        {
          key: 'commission',
          title: '预估佣金',
          money: true,
          display: this.formatMoney(s.totalCommission),
          hint: '排除取消单(3)，其余状态预估佣金累加'
        },
        {
          key: 'paidPending',
          title: '已付款（待结算）',
          money: true,
          display: this.formatMoney(s.estimatePaidPending),
          hint: 'validCode=16 的预估佣金（未完结收货）'
        },
        {
          key: 'sku',
          title: '总商品件数',
          money: false,
          display: s.totalSkuNum || 0,
          hint: 'skuNum 汇总'
        },
        {
          key: 'actual',
          title: '实际佣金',
          money: true,
          display: this.formatMoney(s.totalActualFee),
          hint: '仅已完成(17) 的实际佣金'
        }
      ]
    },
    /** 下拉无数据或加载失败时的说明（用户误以为「没有京粉筛选」） */
    adminUnionNotice() {
      if (this._adminListError) {
        return '京粉账号列表接口异常，下拉暂无选项。请刷新或检查接口 /jarvis/superadmin/select/adminUnionId 与权限。'
      }
      if (this._adminListLoaded && (!this.adminList || this.adminList.length === 0)) {
        return '未配置任何京粉账号选项：请先到「超级管理员」维护 unionId，或确认当前账号有拉取下拉数据的权限。'
      }
      return ''
    }
  },
  created() {
    this.bootstrap()
  },
  mounted() {
    this._chartResize = debounce(() => {
      this._statusChart && this._statusChart.resize()
      this._commissionChart && this._commissionChart.resize()
    }, 120)
    window.addEventListener('resize', this._chartResize)
  },
  beforeDestroy() {
    window.removeEventListener('resize', this._chartResize)
    this._disposeCharts()
  },
  methods: {
    async bootstrap() {
      this._adminListError = false
      try {
        const res = await getValidCodeSelectData()
        this.validCodeOptions = (res && res.data) ? res.data : []
      } catch (e) {
        this.validCodeOptions = []
        this.$message.error('订单状态下拉加载失败')
      }
      try {
        const res = await getAdminSelectData()
        this.adminList = (res && (res.data || res.rows)) ? (res.data || res.rows) : (res || [])
        if (!Array.isArray(this.adminList)) {
          this.adminList = []
        }
      } catch (e) {
        this._adminListError = true
        this.adminList = []
        this.$message.error('京粉账号下拉加载失败')
      } finally {
        this._adminListLoaded = true
      }
      this.getStatistics()
    },
    _disposeCharts() {
      if (this._statusChart) {
        this._statusChart.dispose()
        this._statusChart = null
      }
      if (this._commissionChart) {
        this._commissionChart.dispose()
        this._commissionChart = null
      }
    },
    getStatistics() {
      this.loading = true
      const params = { ...this.queryParams }
      if (params.skuId === '' || params.skuId === undefined) {
        params.skuId = null
      }
      if (params.unionId === '' || params.unionId === undefined) {
        params.unionId = null
      }
      getOrderStatistics(params)
        .then(response => {
          this.statistics = Object.assign(
            {
              totalOrders: 0,
              totalCosPrice: 0,
              totalCommission: 0,
              estimatePaidPending: 0,
              totalSkuNum: 0,
              totalActualFee: 0,
              groupStats: {}
            },
            response.data || {}
          )
          this.processStatusDetails()
          this.$nextTick(() => this.updateCharts())
        })
        .catch(() => {
          this.$message.error('加载统计数据失败')
        })
        .finally(() => {
          this.loading = false
        })
    },
    processStatusDetails() {
      const groupStats = this.statistics.groupStats || {}
      const total = this.statistics.totalOrders || 0
      this.statusDetails = GROUP_STAT_ORDER.map(key => groupStats[key])
        .filter(Boolean)
        .map(item => ({
          ...item,
          skuNum: item.skuNum != null ? item.skuNum : 0,
          percentage: total > 0 ? ((item.count / total) * 100).toFixed(2) : '0.00'
        }))
    },
    formatMoney(amount) {
      if (amount == null || amount === '') return '0.00'
      const n = parseFloat(amount)
      return Number.isFinite(n) ? n.toFixed(2) : '0.00'
    },
    handleDateRangeChange(dates) {
      if (dates && dates.length === 2) {
        this.queryParams.beginTime = dates[0]
        this.queryParams.endTime = dates[1]
      } else {
        this.queryParams.beginTime = null
        this.queryParams.endTime = null
      }
    },
    handleQuery() {
      this.getStatistics()
    },
    resetQuery() {
      this.dateRange = []
      this.resetForm('queryForm')
      this.queryParams = {
        beginTime: null,
        endTime: null,
        validCode: null,
        skuId: null,
        unionId: null
      }
      this.getStatistics()
    },
    updateCharts() {
      this._renderPie(this.$refs.statusChart, '_statusChart', (groupStats) => {
        const data = GROUP_STAT_ORDER.map(k => groupStats[k]).filter(Boolean).map(item => ({
          value: item.count,
          name: item.label
        }))
        return {
          name: '订单状态',
          data,
          isAmount: false
        }
      })
      this._renderPie(this.$refs.commissionChart, '_commissionChart', (groupStats) => {
        const data = GROUP_STAT_ORDER.map(k => groupStats[k])
          .filter(Boolean)
          .filter(item => Number(item.commission) > 0)
          .map(item => ({
            value: item.commission,
            name: item.label
          }))
        return {
          name: '佣金分布',
          data,
          isAmount: true
        }
      })
      this._chartResize && this._chartResize()
    },
    _renderPie(domRef, instKey, build) {
      if (!domRef) return
      const groupStats = this.statistics.groupStats || {}
      const built = build(groupStats)
      let chart = this[instKey]
      if (!chart) {
        chart = echarts.init(domRef)
        this[instKey] = chart
      }
      if (!built.data.length) {
        chart.setOption(
          {
            tooltip: { show: false },
            color: PIE_COLORS,
            graphic: [
              {
                type: 'text',
                left: 'center',
                top: 'middle',
                style: { text: '暂无数据', fill: '#909399', fontSize: 14 }
              }
            ],
            series: []
          },
          true
        )
        return
      }
      chart.setOption(
        {
          tooltip: {
            trigger: 'item',
            formatter: built.isAmount
              ? (p) => `${p.seriesName}<br/>${p.name}: ¥${this.formatMoney(p.value)} (${p.percent}%)`
              : '{a} <br/>{b}: {c} ({d}%)'
          },
          color: PIE_COLORS,
          graphic: [],
          legend: { orient: 'vertical', left: 'left', type: 'scroll' },
          series: [
            {
              name: built.name,
              type: 'pie',
              radius: ['42%', '72%'],
              center: ['56%', '52%'],
              avoidLabelOverlap: true,
              itemStyle: { borderRadius: 4, borderColor: '#fff', borderWidth: 1 },
              label: { show: true, formatter: '{b}\n{d}%' },
              emphasis: {
                label: { show: true, fontSize: 16, fontWeight: 'bold' }
              },
              data: built.data
            }
          ]
        },
        true
      )
    }
  }
}
</script>

<style scoped>
.filter-card {
  margin-bottom: 16px;
}

.filter-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.filter-card-title {
  font-weight: 600;
  font-size: 15px;
  color: #303133;
}

.admin-alert {
  margin-bottom: 12px;
}

.union-form-item {
  margin-bottom: 12px;
}

.summary-row {
  margin-bottom: 8px;
}

.summary-card {
  margin-bottom: 16px;
  border-radius: 8px;
}

.summary-card-inner {
  text-align: center;
  padding: 6px 4px 4px;
}

.summary-title {
  font-size: 13px;
  color: #606266;
  margin-bottom: 6px;
}

.summary-value {
  font-size: 22px;
  font-weight: 600;
  color: #409eff;
  line-height: 1.3;
}

.summary-hint {
  font-size: 12px;
  color: #909399;
  margin-top: 6px;
}

.charts-row {
  margin-bottom: 8px;
}

.table-row {
  margin-bottom: 24px;
}

.card-header-plain {
  font-weight: 600;
  color: #303133;
}

.chart-container {
  padding: 8px 8px 4px;
}

.chart-el {
  width: 100%;
  height: 300px;
}

@media (max-width: 768px) {
  .filter-card ::v-deep .el-form--inline .el-form-item {
    display: block;
    margin-right: 0;
  }
}
</style>
