<template>
  <el-card shadow="never">
    <template #header>
      <!-- 标题 -->
      <div class="flex flex-row items-center justify-between">
        <CardTitle title="商品概况" />
        <!-- 查询条件 -->
        <ShortcutDateRangePicker ref="shortcutDateRangePicker" @change="getProductTrendData">
          <el-button
            class="ml-4"
            @click="handleExport"
            :loading="exportLoading"
            v-hasPermi="['statistics:product:export']"
          >
            <Icon icon="ep:download" class="mr-1" />导出
          </el-button>
        </ShortcutDateRangePicker>
      </div>
    </template>
    <!-- 统计值 -->
    <el-row :gutter="16">
      <el-col :xl="4" :md="8" :sm="24">
        <SummaryCard
          title="商品浏览量"
          tooltip="在选定条件下，所有商品详情页被访问的次数，一个人在统计时间内访问多次记为多次"
          icon="ep:view"
          icon-color="bg-blue-100"
          icon-bg-color="text-blue-500"
          prefix=""
          :decimals="0"
          :value="trendSummary?.value?.browseCount || 0"
          :percent="
            calculateRelativeRate(
              trendSummary?.value?.browseCount,
              trendSummary?.reference?.browseCount
            )
          "
        />
      </el-col>
      <el-col :xl="4" :md="8" :sm="24">
        <SummaryCard
          title="商品访客数"
          tooltip="在选定条件下，访问任何商品详情页的人数，一个人在统计时间范围内访问多次只记为一个"
          icon="ep:user-filled"
          icon-color="bg-purple-100"
          icon-bg-color="text-purple-500"
          prefix=""
          :decimals="0"
          :value="trendSummary?.value?.browseUserCount || 0"
          :percent="
            calculateRelativeRate(
              trendSummary?.value?.browseUserCount,
              trendSummary?.reference?.browseUserCount
            )
          "
        />
      </el-col>
      <el-col :xl="4" :md="8" :sm="24">
        <SummaryCard
          title="支付件数"
          tooltip="在选定条件下，成功付款订单的商品件数之和"
          icon="fa-solid:money-check-alt"
          icon-color="bg-yellow-100"
          icon-bg-color="text-yellow-500"
          prefix=""
          :decimals="0"
          :value="trendSummary?.value?.orderPayCount || 0"
          :percent="
            calculateRelativeRate(
              trendSummary?.value?.orderPayCount,
              trendSummary?.reference?.orderPayCount
            )
          "
        />
      </el-col>
      <el-col :xl="4" :md="8" :sm="24">
        <SummaryCard
          title="支付金额"
          tooltip="在选定条件下，成功付款订单的商品金额之和"
          icon="ep:warning-filled"
          icon-color="bg-green-100"
          icon-bg-color="text-green-500"
          prefix="￥"
          :decimals="2"
          :value="fenToYuan(trendSummary?.value?.orderPayPrice || 0)"
          :percent="
            calculateRelativeRate(
              trendSummary?.value?.orderPayPrice,
              trendSummary?.reference?.orderPayPrice
            )
          "
        />
      </el-col>
      <el-col :xl="4" :md="8" :sm="24">
        <SummaryCard
          title="退款件数"
          tooltip="在选定条件下，成功退款的商品件数之和"
          icon="fa-solid:wallet"
          icon-color="bg-cyan-100"
          icon-bg-color="text-cyan-500"
          prefix=""
          :decimals="0"
          :value="trendSummary?.value?.afterSaleCount || 0"
          :percent="
            calculateRelativeRate(
              trendSummary?.value?.afterSaleCount,
              trendSummary?.reference?.afterSaleCount
            )
          "
        />
      </el-col>
      <el-col :xl="4" :md="8" :sm="24">
        <SummaryCard
          title="退款金额"
          tooltip="在选定条件下，成功退款的商品金额之和"
          icon="fa-solid:award"
          icon-color="bg-yellow-100"
          icon-bg-color="text-yellow-500"
          prefix="￥"
          :decimals="2"
          :value="fenToYuan(trendSummary?.value?.afterSaleRefundPrice || 0)"
          :percent="
            calculateRelativeRate(
              trendSummary?.value?.afterSaleRefundPrice,
              trendSummary?.reference?.afterSaleRefundPrice
            )
          "
        />
      </el-col>
    </el-row>
    <!-- 折线图 -->
    <el-skeleton :loading="trendLoading" animated>
      <Echart :height="500" :options="lineChartOptions" />
    </el-skeleton>
  </el-card>
</template>
<script lang="ts" setup>
import { ProductStatisticsApi, ProductStatisticsVO } from '@/api/mall/statistics/product'
import SummaryCard from '@/components/SummaryCard/index.vue'
import { EChartsOption } from 'echarts'
import { DataComparisonRespVO } from '@/api/mall/statistics/common'
import { calculateRelativeRate, fenToYuan } from '@/utils'
import download from '@/utils/download'
import { CardTitle } from '@/components/Card'
import * as DateUtil from '@/utils/formatTime'
import dayjs from 'dayjs'

/** 商品概况 */
defineOptions({ name: 'ProductSummary' })

const message = useMessage() // 消息弹窗

const trendLoading = ref(true) // 商品状态加载中
const exportLoading = ref(false) // 导出的加载中
const trendSummary = ref<DataComparisonRespVO<ProductStatisticsVO>>() // 商品状况统计数据
const shortcutDateRangePicker = ref()

/** 折线图配置 */
const lineChartOptions = reactive<EChartsOption>({
  dataset: {
    dimensions: ['time', 'browseCount', 'browseUserCount', 'orderPayPrice', 'afterSaleRefundPrice'],
    source: []
  },
  grid: {
    left: 20,
    right: 20,
    bottom: 20,
    top: 80,
    containLabel: true
  },
  legend: {
    top: 50
  },
  series: [
    { name: '商品浏览量', type: 'line', smooth: true, itemStyle: { color: '#B37FEB' } },
    { name: '商品访客数', type: 'line', smooth: true, itemStyle: { color: '#FFAB2B' } },
    { name: '支付金额', type: 'bar', smooth: true, yAxisIndex: 1, itemStyle: { color: '#1890FF' } },
    { name: '退款金额', type: 'bar', smooth: true, yAxisIndex: 1, itemStyle: { color: '#00C050' } }
  ],
  toolbox: {
    feature: {
      // 数据区域缩放
      dataZoom: {
        yAxisIndex: false // Y轴不缩放
      },
      brush: {
        type: ['lineX', 'clear'] // 区域缩放按钮、还原按钮
      },
      saveAsImage: { show: true, name: '商品状况' } // 保存为图片
    }
  },
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'cross'
    },
    padding: [5, 10]
  },
  xAxis: {
    type: 'category',
    boundaryGap: true,
    axisTick: {
      show: false
    }
  },
  yAxis: [
    {
      type: 'value',
      name: '金额',
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        textStyle: {
          color: '#7F8B9C'
        }
      },
      splitLine: {
        show: true,
        lineStyle: {
          color: '#F5F7F9'
        }
      }
    },
    {
      type: 'value',
      name: '数量',
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        textStyle: {
          color: '#7F8B9C'
        }
      },
      splitLine: {
        show: true,
        lineStyle: {
          color: '#F5F7F9'
        }
      }
    }
  ]
}) as EChartsOption

/** 处理商品状况查询 */
const getProductTrendData = async () => {
  trendLoading.value = true
  // 1. 处理时间: 开始与截止在同一天的, 折线图出不来, 需要延长一天
  const times = shortcutDateRangePicker.value.times
  if (DateUtil.isSameDay(times[0], times[1])) {
    // 前天
    times[0] = DateUtil.formatDate(dayjs(times[0]).subtract(1, 'd'))
  }
  // 查询数据
  await Promise.all([getProductTrendSummary(), getProductStatisticsList()])
  trendLoading.value = false
}

/** 查询商品状况数据统计 */
const getProductTrendSummary = async () => {
  const times = shortcutDateRangePicker.value.times
  trendSummary.value = await ProductStatisticsApi.getProductStatisticsAnalyse({ times })
}

/** 查询商品状况数据列表 */
const getProductStatisticsList = async () => {
  // 查询数据
  const times = shortcutDateRangePicker.value.times
  const list: ProductStatisticsVO[] = await ProductStatisticsApi.getProductStatisticsList({ times })
  // 处理数据
  for (let item of list) {
    item.orderPayPrice = fenToYuan(item.orderPayPrice)
    item.afterSaleRefundPrice = fenToYuan(item.afterSaleRefundPrice)
  }
  // 更新 Echarts 数据
  if (lineChartOptions.dataset && lineChartOptions.dataset['source']) {
    lineChartOptions.dataset['source'] = list
  }
}

/** 导出按钮操作 */
const handleExport = async () => {
  try {
    // 导出的二次确认
    await message.exportConfirm()
    // 发起导出
    exportLoading.value = true
    const times = shortcutDateRangePicker.value.times
    const data = await ProductStatisticsApi.exportProductStatisticsExcel({ times })
    download.excel(data, '商品状况.xls')
  } catch {
  } finally {
    exportLoading.value = false
  }
}
</script>
<style lang="scss" scoped></style>
