<template>
  <div class="dashboard-wrapper">
    <div class="card-wrapper">
      <div class="dashboard-title">核心数据看板</div>
      <div class="card-container-wrapper">
        <div class="card-container">
          <div class="card-item">
            <div class="card-item-header">
              <div class="card-title">今日新单（件/订单）</div>
              <el-tooltip
                class="item"
                effect="light"
                :content="`今日新增订单的订单数量（${today}北京时间 0-24点数据）`"
                placement="bottom"
              >
                <div class="card-icon"></div>
              </el-tooltip>
            </div>
            <div class="card-item-content-box">
              <div v-auto-fit-text class="card-item-content text-blue">
                {{
                  (statisticData?.todayNewProductNum ?? '-') +
                  '/' +
                  (statisticData?.todayNewOrderNum ?? '-')
                }}
              </div>
            </div>
          </div>
          <div class="card-item">
            <div class="card-item-header">
              <div class="card-title">今日接单（件/订单）</div>
              <el-tooltip
                class="item"
                effect="light"
                :content="`今日新增确认生产的订单数量（${today}北京时间 0-24点数据）`"
                placement="bottom"
              >
                <div class="card-icon"></div>
              </el-tooltip>
            </div>
            <div class="card-item-content-box">
              <div v-auto-fit-text class="card-item-content text-blue">
                {{
                  (statisticData?.todayConfirmProductNum ?? '-') +
                  '/' +
                  (statisticData?.todayConfirmOrderNum ?? '-')
                }}
              </div>
            </div>
          </div>
          <div class="card-item">
            <div class="card-item-header">
              <div class="card-title">未发货订单（订单）</div>
              <el-tooltip
                class="item"
                effect="light"
                content="目前确认生产后还未转为已发货状态的总订单数"
                placement="bottom"
              >
                <div class="card-icon"></div>
              </el-tooltip>
            </div>
            <div class="card-item-content-box">
              <div v-auto-fit-text class="card-item-content text-blue">
                {{ statisticData?.notShipmentOrderNum ?? '-' }}
              </div>
            </div>
          </div>
          <div class="card-item">
            <div class="card-item-header">
              <div class="card-title">超时未发订单（订单）</div>
              <el-tooltip
                class="item"
                effect="light"
                content="目前确认生产后超过48H还未转为已发货状态的总订单数"
                placement="bottom"
              >
                <div class="card-icon"></div>
              </el-tooltip>
            </div>
            <div class="card-item-content-box">
              <div v-auto-fit-text class="card-item-content text-red">
                {{ statisticData?.overTimeNotShipmentOrderNum ?? '-' }}
              </div>
            </div>
          </div>
        </div>
        <div class="card-container" :gutter="20">
          <el-tooltip class="item" effect="light" placement="bottom-end">
            <template #content>
              <div style="display: flex; align-items: center; gap: 4px">
                <div class="up-icon-green"></div>
                <div>为正向趋势，</div>
                <div class="down-icon-red"></div>
                <div>为负向趋势</div>
              </div>
            </template>
            <div class="card-item">
              <div class="card-item-header">
                <div class="card-title">昨日发货数（订单）</div>
                <el-tooltip
                  class="item"
                  effect="light"
                  :content="`昨日转为已发货状态的总订单数（${yesterday}北京时间 0-24点数据）`"
                  placement="bottom"
                >
                  <div class="card-icon"></div>
                </el-tooltip>
              </div>
              <div class="card-item-content-box">
                <div v-auto-fit-text class="card-item-content text-blue">
                  {{ statisticData?.yesterdayShipmentOrderNum ?? '-' }}
                </div>
                <div class="card-item-content-text">
                  较前天
                  <div
                    v-if="
                      statisticData &&
                      statisticData.compareYesterdayShipmentOrderNum >= 0
                    "
                    style="display: flex; margin-left: 10px"
                  >
                    <div class="text-green">
                      {{
                        statisticData?.compareYesterdayShipmentOrderNum.toFixed(
                          2,
                        )
                      }}
                    </div>
                    <div class="up-icon-green"></div>
                  </div>
                  <div v-else style="display: flex; margin-left: 10px">
                    <div class="text-red">
                      {{
                        Math.abs(
                          statisticData?.compareYesterdayShipmentOrderNum || 0,
                        ).toFixed(2)
                      }}
                    </div>
                    <div class="down-icon-red"></div>
                  </div>
                </div>
              </div>
            </div>
          </el-tooltip>
          <el-tooltip class="item" effect="light" placement="bottom-end">
            <template #content>
              <div style="display: flex; align-items: center; gap: 4px">
                <div class="up-icon-green"></div>
                <div>为正向趋势，</div>
                <div class="down-icon-red"></div>
                <div>为负向趋势</div>
              </div>
            </template>
            <div class="card-item">
              <div class="card-item-header">
                <div class="card-title">24h发货率</div>
                <el-tooltip
                  class="item"
                  effect="light"
                  :content="`昨日已发货订单中从接单转为已发货状态在24小时内的比例（${yesterday}北京时间 0-24点数据）`"
                  placement="bottom"
                >
                  <div class="card-icon"></div>
                </el-tooltip>
              </div>
              <div class="card-item-content-box">
                <div v-auto-fit-text class="card-item-content text-blue">
                  {{ (statisticData?.shipmentRateOf24Hour ?? '-') + '%' }}
                </div>
                <div class="card-item-content-text">
                  较前天
                  <div
                    v-if="
                      statisticData &&
                      statisticData.compareLastDayShipmentRateOf24Hour >= 0
                    "
                    style="display: flex; margin-left: 10px"
                  >
                    <div class="text-green">
                      {{
                        (statisticData?.compareLastDayShipmentRateOf24Hour.toFixed(
                          2,
                        ) ?? '-') + '%'
                      }}
                    </div>
                    <div class="up-icon-green"></div>
                  </div>
                  <div v-else style="display: flex; margin-left: 10px">
                    <div class="text-red">
                      {{
                        Math.abs(
                          statisticData?.compareLastDayShipmentRateOf24Hour ||
                            0,
                        ).toFixed(2) + '%'
                      }}
                    </div>
                    <div class="down-icon-red"></div>
                  </div>
                </div>
              </div>
            </div>
          </el-tooltip>
          <el-tooltip class="item" effect="light" placement="bottom-end">
            <template #content>
              <div style="display: flex; align-items: center; gap: 4px">
                <div class="up-icon-green"></div>
                <div>为正向趋势，</div>
                <div class="down-icon-red"></div>
                <div>为负向趋势</div>
              </div>
            </template>
            <div class="card-item">
              <div class="card-item-header">
                <div class="card-title">48h发货率</div>
                <el-tooltip
                  class="item"
                  effect="light"
                  :content="`昨日已发货订单中从接单转为已发货状态在48小时内的比例（${yesterday}北京时间 0-24点数据）`"
                  placement="bottom"
                >
                  <div class="card-icon"></div>
                </el-tooltip>
              </div>
              <div class="card-item-content-box">
                <div v-auto-fit-text class="card-item-content text-blue">
                  {{ (statisticData?.shipmentRateOf48Hour ?? '-') + '%' }}
                </div>
                <div class="card-item-content-text">
                  较前天
                  <div
                    v-if="
                      statisticData &&
                      statisticData.compareLastDayShipmentRateOf48Hour >= 0
                    "
                    style="display: flex; margin-left: 10px"
                  >
                    <div class="text-green">
                      {{
                        (statisticData?.compareLastDayShipmentRateOf48Hour.toFixed(
                          2,
                        ) ?? '-') + '%'
                      }}
                    </div>
                    <div class="up-icon-green"></div>
                  </div>
                  <div v-else style="display: flex; margin-left: 10px">
                    <div class="text-red">
                      {{
                        Math.abs(
                          statisticData?.compareLastDayShipmentRateOf48Hour ||
                            0,
                        ).toFixed(2) + '%'
                      }}
                    </div>
                    <div class="down-icon-red"></div>
                  </div>
                </div>
              </div>
            </div>
          </el-tooltip>
          <el-tooltip class="item" effect="light" placement="bottom-end">
            <template #content>
              <div style="display: flex; align-items: center; gap: 4px">
                <div class="down-icon-green"></div>
                <div>为正向趋势，</div>
                <div class="up-icon-red"></div>
                <div>为负向趋势</div>
              </div>
            </template>
            <div class="card-item">
              <div class="card-item-header">
                <div class="card-title">发货超时率</div>
                <el-tooltip
                  class="item"
                  effect="light"
                  :content="`昨日已发货订单中从接单转为已发货状态大于48小时的比例（${yesterday}北京时间 0-24点数据）`"
                  placement="bottom"
                >
                  <div class="card-icon"></div>
                </el-tooltip>
              </div>
              <div class="card-item-content-box">
                <div v-auto-fit-text class="card-item-content text-red">
                  {{
                    (statisticData?.overTimeShipmentRate ?? '-') +
                    '%(' +
                    (statisticData?.yesterdayOverTimeShipmentOrderNum ?? '-') +
                    ')'
                  }}
                </div>
                <div class="card-item-content-text">
                  较前天
                  <div
                    v-if="
                      statisticData &&
                      statisticData.compareLastDayOverTimeShipmentRate >= 0
                    "
                    style="display: flex; margin-left: 10px"
                  >
                    <div class="text-red">
                      {{
                        (statisticData?.compareLastDayOverTimeShipmentRate.toFixed(
                          2,
                        ) ?? '-') + '%'
                      }}
                    </div>
                    <div class="up-icon-red"></div>
                  </div>
                  <div v-else style="display: flex; margin-left: 10px">
                    <div class="text-green">
                      {{
                        Math.abs(
                          statisticData?.compareLastDayOverTimeShipmentRate ||
                            0,
                        ).toFixed(2) + '%'
                      }}
                    </div>
                    <div class="down-icon-green"></div>
                  </div>
                </div>
              </div>
            </div>
          </el-tooltip>
        </div>
        <div class="card-container">
          <div class="card-item">
            <div class="card-item-header">
              <div class="card-title">待创建物流（订单）</div>
              <el-tooltip
                class="item"
                effect="light"
                content="目前订单中待创建物流的总订单数"
                placement="bottom"
              >
                <div class="card-icon"></div>
              </el-tooltip>
            </div>
            <div class="card-item-content-box">
              <div v-auto-fit-text class="card-item-content text-blue">
                {{ statisticData?.waitCreateLogisticOrderNum ?? '-' }}
              </div>
            </div>
          </div>
          <div class="card-item">
            <div class="card-item-header">
              <div class="card-title">待排单（生产单）</div>
              <el-tooltip
                class="item"
                effect="light"
                content="目前订单中待排单的总生产单数"
                placement="bottom"
              >
                <div class="card-icon"></div>
              </el-tooltip>
            </div>
            <div class="card-item-content-box">
              <div v-auto-fit-text class="card-item-content text-blue">
                {{ statisticData?.waitArrangeOrderNum ?? '-' }}
              </div>
            </div>
          </div>
          <div class="card-item">
            <div class="card-item-header">
              <div class="card-title">生产中（生产单）</div>
              <el-tooltip
                class="item"
                effect="light"
                content="目前订单中排单完成后到发货前的总生产单数"
                placement="bottom"
              >
                <div class="card-icon"></div>
              </el-tooltip>
            </div>
            <div class="card-item-content-box">
              <div v-auto-fit-text class="card-item-content text-blue">
                {{ statisticData?.producingOrderNum ?? '-' }}
              </div>
            </div>
          </div>
          <div class="card-item">
            <div class="card-item-header">
              <div class="card-title">待发货（订单）</div>
              <el-tooltip
                class="item"
                effect="light"
                content="目前订单中待发货状态的总订单数"
                placement="bottom"
              >
                <div class="card-icon"></div>
              </el-tooltip>
            </div>
            <div class="card-item-content-box">
              <div v-auto-fit-text class="card-item-content text-blue">
                {{ statisticData?.waitShipmentNum ?? '-' }}
              </div>
            </div>
          </div>
          <div class="card-item">
            <div class="card-item-header">
              <div class="card-title">拦截申请（订单）</div>
              <el-tooltip
                class="item"
                effect="light"
                content="目前在生产拦截申请和发货拦截申请中的总订单数"
                placement="bottom"
              >
                <div class="card-icon"></div>
              </el-tooltip>
            </div>
            <div class="card-item-content-box">
              <div v-auto-fit-text class="card-item-content text-yellow">
                {{ statisticData?.blockApplyOrderNum ?? '-' }}
              </div>
            </div>
          </div>
          <div class="card-item">
            <div class="card-item-header">
              <div class="card-title">异常单（订单）</div>
              <el-tooltip
                class="item"
                effect="light"
                content="所有订单中的异常单总订单数"
                placement="bottom"
              >
                <div class="card-icon"></div>
              </el-tooltip>
            </div>
            <div class="card-item-content-box">
              <div class="card-item-content text-red">
                {{ statisticData?.exceptionOrderNum ?? '-' }}
              </div>
            </div>
          </div>
        </div>
        <div class="card-container">
          <div class="card-item">
            <div class="card-item-header">
              <div class="card-title">缺货中订单（订单）</div>
              <el-tooltip
                class="item"
                effect="light"
                content="缺货统计中的商品总订单数"
                placement="bottom"
              >
                <div class="card-icon"></div>
              </el-tooltip>
            </div>
            <div class="card-item-content-box">
              <div v-auto-fit-text class="card-item-content text-yellow">
                {{ statisticData?.outOfStockOrderNum ?? '-' }}
              </div>
            </div>
          </div>
          <div class="card-item">
            <div class="card-item-header">
              <div class="card-title">缺货&lt;24h单（订单）</div>
              <el-tooltip
                class="item"
                effect="light"
                content="缺货总订单中的缺货时长在24h内的订单数"
                placement="bottom"
              >
                <div class="card-icon"></div>
              </el-tooltip>
            </div>
            <div class="card-item-content-box">
              <div v-auto-fit-text class="card-item-content text-yellow">
                {{ statisticData?.outOfStock24HourOrderNum ?? '-' }}
              </div>
            </div>
          </div>
          <div class="card-item">
            <div class="card-item-header">
              <div class="card-title">缺货&lt;48h单（订单）</div>
              <el-tooltip
                class="item"
                effect="light"
                content="缺货总订单中的缺货时长在48h内的订单数"
                placement="bottom"
              >
                <div class="card-icon"></div>
              </el-tooltip>
            </div>
            <div class="card-item-content-box">
              <div class="card-item-content text-yellow">
                {{ statisticData?.outOfStock48HourOrderNum ?? '-' }}
              </div>
            </div>
          </div>
          <div class="card-item">
            <div class="card-item-header">
              <div class="card-title">缺货≥48h单（订单）</div>
              <el-tooltip
                class="item"
                effect="light"
                content="缺货总订单中的缺货时长大于48h内的订单数"
                placement="bottom"
              >
                <div class="card-icon"></div>
              </el-tooltip>
            </div>
            <div class="card-item-content-box">
              <div v-auto-fit-text class="card-item-content text-red">
                {{ statisticData?.outOfStockOver48HourOrderNum ?? '-' }}
              </div>
            </div>
          </div>
          <div class="card-item">
            <div class="card-item-header">
              <div class="card-title">缺货库存SKU数</div>
              <el-tooltip
                class="item"
                effect="light"
                content="缺货的库存SKU的总数目"
                placement="bottom"
              >
                <div class="card-icon"></div>
              </el-tooltip>
            </div>
            <div class="card-item-content-box">
              <div v-auto-fit-text class="card-item-content text-red">
                {{ statisticData?.outOfStockSkuNum ?? '-' }}
              </div>
            </div>
          </div>
          <div class="card-item">
            <div class="card-item-header">
              <div class="card-title">缺货总件数</div>
              <el-tooltip
                class="item"
                effect="light"
                content="缺货的货物总件数"
                placement="bottom"
              >
                <div class="card-icon"></div>
              </el-tooltip>
            </div>
            <div class="card-item-content-box">
              <div v-auto-fit-text class="card-item-content text-yellow">
                {{ statisticData?.outOfStockProductNum ?? '-' }}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="chart-wrapper" style="width: 100%">
      <el-radio-group
        v-model="chartTimes1"
        size="small"
        class="chart-controls"
        @change="getchartTimes($event, 'ORDER_TREND')"
      >
        <el-radio-button
          v-for="time in timeOptions"
          :key="time.type"
          :value="time.type"
          :label="time.name"
        >
        </el-radio-button>
      </el-radio-group>
      <div
        ref="orderChart1"
        v-loading="orderChart1Loading"
        class="chart-container"
        style="width: 100%"
      />
    </div>
    <div class="charts-row">
      <div class="chart-wrapper chart-half">
        <el-radio-group
          v-model="chartTimes2"
          size="small"
          class="chart-controls"
          @change="getchartTimes($event, 'SHIPMENT_TREND')"
        >
          <el-radio-button
            v-for="time in timeOptions"
            :key="time.type"
            :value="time.type"
            :label="time.name"
          >
          </el-radio-button>
        </el-radio-group>
        <div
          ref="orderChart2"
          v-loading="orderChart2Loading"
          class="chart-container"
          style="width: 100%"
        />
      </div>
      <div class="chart-wrapper chart-half">
        <el-radio-group
          v-model="chartTimes3"
          size="small"
          class="chart-controls"
          @change="getchartTimes($event, 'OVERTIME_SHIPMENT_TREND')"
        >
          <el-radio-button
            v-for="time in timeOptions"
            :key="time.type"
            :value="time.type"
            :label="time.name"
          >
          </el-radio-button>
        </el-radio-group>
        <div
          ref="orderChart3"
          v-loading="orderChart3Loading"
          class="chart-container"
          style="width: 100%"
        />
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, nextTick, type Ref } from 'vue'
import * as echarts from 'echarts/core'

import {
  TitleComponent,
  GridComponent,
  LegendComponent,
} from 'echarts/components'
import { LineChart } from 'echarts/charts'
import { UniversalTransition } from 'echarts/features'
import { CanvasRenderer } from 'echarts/renderers'
import { getStatisticData, trendApi } from '@/api/statistic'
import type {
  statisticData as StatisticData,
  trendType as trendType,
} from '@/types/api/statistic'
import { TooltipComponent } from 'echarts/components'
echarts.use([TooltipComponent])
echarts.use([
  TitleComponent,
  GridComponent,
  LegendComponent,
  LineChart,
  CanvasRenderer,
  UniversalTransition,
])

const today = new Date()
  .toLocaleDateString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
  })
  .replace(/\//g, '-')

const yesterday = new Date(new Date().setDate(new Date().getDate() - 1))
  .toLocaleDateString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
  })
  .replace(/\//g, '-')

// 获取统计数据
const statisticData = ref<StatisticData | null>(null)

// 图表 loading 状态（无数据时展示 loading）
const orderChart1Loading = ref<boolean>(true)
const orderChart2Loading = ref<boolean>(true)
const orderChart3Loading = ref<boolean>(true)

const timeOptions = ref<{ type: string; name: string }[]>([
  { type: '0', name: '日数据' },
  { type: '1', name: '周数据' },
  { type: '2', name: '月数据' },
])

const chartTimes1 = ref<string>('0')
const chartTimes2 = ref<string>('0')
const chartTimes3 = ref<string>('0')

// 图表容器引用
const orderChart1 = ref<HTMLDivElement | null>(null)
const orderChart2 = ref<HTMLDivElement | null>(null)
const orderChart3 = ref<HTMLDivElement | null>(null)

// 图表实例数组
const chartInstances: (echarts.ECharts | null)[] = [null, null, null]

type ChartSeriesItem = {
  name: string
  data: (number | { value: number; count?: number })[]
  color: string
}
type ChartConfig = {
  title: string
  legend: string[]
  xAxisData: string[]
  series: ChartSeriesItem[]
}

// 图表配置
const chartConfig1 = ref<ChartConfig>({
  title: '订单趋势统计（单）',
  legend: ['接单数', '生产数', '发货数'],
  xAxisData: [''],
  series: [
    {
      name: '接单数',
      data: [0],
      color: '#30d2cb',
    },
    {
      name: '生产数',
      data: [0],
      color: '#9e95ff',
    },
    {
      name: '发货数',
      data: [0],
      color: '#6bb3fd',
    },
  ],
})

const chartConfig2 = ref<ChartConfig>({
  title: '订单发货效率',
  legend: ['24H发货率', '48H发货率'],
  xAxisData: [''],

  series: [
    {
      name: '24H发货率',
      data: [0],
      color: '#3e9fff',
    },
    {
      name: '48H发货率',
      data: [0],
      color: '#ac84ff',
    },
  ],
})

const chartConfig3 = ref<ChartConfig>({
  title: '订单超时情况',
  legend: ['发货超时率'],
  xAxisData: [''],

  series: [
    {
      name: '发货超时率',
      data: [{ value: 0, count: 0 }],
      color: '#ff6845',
    },
  ],
})

const overtimeTooltipFormatter = (params: TooltipParam[]) =>
  params
    .map((item) => {
      const dataObj =
        item.data && typeof item.data === 'object'
          ? (item.data as { value: number | string; count?: number })
          : null
      const count =
        dataObj && typeof dataObj.count === 'number' ? dataObj.count : null
      const valueText = `${item.value}%`
      return `${item.marker}${item.seriesName}: ${valueText}${
        count !== null ? `（${count}单）` : ''
      }`
    })
    .join('<br/>')

// 创建图表配置的函数
type TooltipParam = {
  marker: string
  seriesName: string
  value: number | string
  data?: unknown
}

const createChartOption = (
  config: Ref<ChartConfig>,
  isPercent = false,
  customFormatter?: (params: TooltipParam[]) => string,
) => {
  const data = config.value
  return {
    title: {
      text: data.title,
      left: 'left',
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross',
        crossStyle: {
          type: 'dashed',
        },
        label: {
          backgroundColor: '#6a7985',
        },
      },
      formatter:
        customFormatter ??
        ((params: TooltipParam[]) =>
          params
            .map(
              (item) =>
                `${item.marker}${item.seriesName}: ${
                  isPercent ? `${item.value}%` : item.value
                }`,
            )
            .join('<br/>')),
    },
    legend: {
      data: data.legend,
      top: 'top',
      left: 'center',
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: data.xAxisData,
      axisLabel: {
        // 关键配置：添加省略号
        overflow: 'truncate', // 截断显示
        width: 120, // 每个标签的最大宽度（像素）

        formatter: function (value: string) {
          // 手动截断，超过6个字符加省略号
          if (value.length > 10) {
            return value.substring(0, 10) + '...'
          }
          return value
        },
      },
    },
    yAxis: {
      type: 'value',
      axisLabel: isPercent
        ? {
            formatter: '{value}%',
            color: '#666',
          }
        : {
            color: '#666',
          },
      axisLine: {
        lineStyle: { color: '#ccc' },
      },
      splitLine: {
        lineStyle: { color: '#eee' },
      },
    },
    series: data.series.map((item) => ({
      name: item.name,
      type: 'line',
      data: item.data,
      smooth: true,
      lineStyle: {
        color: item.color,
        width: 3,
      },
      itemStyle: {
        color: item.color,
      },
      areaStyle: {
        color: {
          type: 'linear',
          x: 0,
          y: 0,
          x2: 0,
          y2: 1,
          colorStops: [
            {
              offset: 0,
              color: item.color,
            },
            {
              offset: 1,
              color: item.color + '00', // 添加透明度，00 表示完全透明
            },
          ],
          globalCoord: false,
        },
      },
    })),
  }
}

// 自动缩放文字：保证卡片内数字不超出边框宽度，超出则减小字号
const adjustTextSize = (el: HTMLElement) => {
  const maxFontSize = 45
  const minFontSize = 16

  const card = el.closest('.card-item') as HTMLElement | null
  const containerWidth = card?.clientWidth ?? el.parentElement?.clientWidth ?? 0

  // 获取 card-item-content-text 的实际宽度
  const contentBox = el.parentElement
  const contentText = contentBox?.querySelector(
    '.card-item-content-text',
  ) as HTMLElement | null

  let contentTextWidth = 0
  let gap = 0
  let marginRight = 0

  if (contentText && contentBox) {
    contentTextWidth = contentText.offsetWidth
    // 获取 gap 值
    const contentBoxStyle = window.getComputedStyle(contentBox)
    gap = parseFloat(contentBoxStyle.gap) || 0
    // 获取 margin-right 值
    const contentTextStyle = window.getComputedStyle(contentText)
    marginRight = parseFloat(contentTextStyle.marginRight) || 0
  }

  const limitWidth = containerWidth - contentTextWidth - gap - marginRight - 20

  el.style.fontSize = `${maxFontSize}px`

  let current = maxFontSize
  while (current > minFontSize && el.scrollWidth > limitWidth) {
    current -= 1
    el.style.fontSize = `${current}px`
  }
}

const vAutoFitText = {
  mounted(el: HTMLElement) {
    nextTick(() => {
      adjustTextSize(el)
    })

    const card = el.closest('.card-item') as HTMLElement | null
    if (card && 'ResizeObserver' in window) {
      const observer = new ResizeObserver(() => {
        adjustTextSize(el)
      })
      observer.observe(card)
      ;(el as { __autoFitObserver__?: ResizeObserver }).__autoFitObserver__ =
        observer
    }
  },
  updated(el: HTMLElement) {
    nextTick(() => {
      adjustTextSize(el)
    })
  },
  unmounted(el: HTMLElement) {
    const observer = (el as { __autoFitObserver__?: ResizeObserver })
      .__autoFitObserver__
    if (observer) {
      observer.disconnect()
      delete (el as { __autoFitObserver__?: ResizeObserver })
        .__autoFitObserver__
    }
  },
}

const getStatisticDataApi = async () => {
  // 统计数据
  getStatisticData()
    .then((res) => {
      if (res.code === 200) {
        statisticData.value = res.data
      }
    })
    .catch((error) => {
      console.error('获取统计数据失败:', error)
    })

  // 订单趋势统计
  trendApi({
    timeUnit: 0,
    trendType: 'ORDER_TREND',
  })
    .then((res) => {
      if (res.code === 200) {
        const isEmpty = checkOrderTrendDataEmpty(res.data)
        // 无论数据是否为空，都要更新 x 轴数据
        updateOrderTrendChart(res.data, 0)
        updateChart(
          chartInstances[0],
          chartConfig1,
          isEmpty,
          false,
          chartTimes1.value,
        )
        orderChart1Loading.value = !(res.data && res.data.length > 0)
      }
    })
    .catch((error) => {
      console.error('获取订单趋势数据失败:', error)
    })

  // 订单发货效率
  trendApi({
    timeUnit: 0,
    trendType: 'SHIPMENT_TREND',
  })
    .then((res) => {
      if (res.code === 200) {
        const isEmpty = checkShipmentTrendDataEmpty(res.data)
        // 无论数据是否为空，都要更新 x 轴数据
        updateShipmentTrendChart(res.data, 0)
        updateChart(
          chartInstances[1],
          chartConfig2,
          isEmpty,
          true,
          chartTimes2.value,
        )
        orderChart2Loading.value = !(res.data && res.data.length > 0)
      }
    })
    .catch((error) => {
      console.error('获取发货趋势数据失败:', error)
    })

  // 订单生产效率
  trendApi({
    timeUnit: 0,
    trendType: 'OVERTIME_SHIPMENT_TREND',
  })
    .then((res) => {
      if (res.code === 200) {
        const isEmpty = checkOvertimeTrendDataEmpty(res.data)
        // 无论数据是否为空，都要更新 x 轴数据
        updateOvertimeTrendChart(res.data, 0)
        updateChart(
          chartInstances[2],
          chartConfig3,
          isEmpty,
          true,
          chartTimes3.value,

          overtimeTooltipFormatter,
        )
        orderChart3Loading.value = !(res.data && res.data.length > 0)
      }
    })
    .catch((error) => {
      console.error('获取超时发货趋势数据失败:', error)
    })
}

onMounted(async () => {
  await nextTick()
  // 订单趋势统计
  if (orderChart1.value) {
    chartInstances[0] = echarts.init(orderChart1.value)
    chartInstances[0]?.setOption(createChartOption(chartConfig1))
  }
  // 订单发货效率
  if (orderChart2.value) {
    chartInstances[1] = echarts.init(orderChart2.value)
    chartInstances[1]?.setOption(createChartOption(chartConfig2, true))
  }
  // 订单生产效率
  if (orderChart3.value) {
    chartInstances[2] = echarts.init(orderChart3.value)
    chartInstances[2]?.setOption(
      createChartOption(chartConfig3, true, overtimeTooltipFormatter),
    )
  }
  // 请求成功后立即更新对应的图表
  getStatisticDataApi()
  // 监听窗口大小变化，自动调整图表大小
  window.addEventListener('resize', handleResize)
})

const getchartTimes = async (v: string, type: string) => {
  try {
    // 切换时间维度时先开启对应 loading，等数据返回后根据是否有数据决定是否保留
    if (type === 'ORDER_TREND') {
      orderChart1Loading.value = true
    } else if (type === 'SHIPMENT_TREND') {
      orderChart2Loading.value = true
    } else if (type === 'OVERTIME_SHIPMENT_TREND') {
      orderChart3Loading.value = true
    }

    const { data } = await trendApi({
      timeUnit: v,
      trendType: type,
    })
    if (type == 'ORDER_TREND') {
      const isEmpty = checkOrderTrendDataEmpty(data)
      // 无论数据是否为空，都要更新 x 轴数据
      updateOrderTrendChart(data, v)
      updateChart(
        chartInstances[0],
        chartConfig1,
        isEmpty,
        false,
        chartTimes1.value,
      )
      orderChart1Loading.value = !(data && data.length > 0)
    } else if (type == 'SHIPMENT_TREND') {
      const isEmpty = checkShipmentTrendDataEmpty(data)
      // 无论数据是否为空，都要更新 x 轴数据
      updateShipmentTrendChart(data, v)
      updateChart(
        chartInstances[1],
        chartConfig2,
        isEmpty,
        true,
        chartTimes2.value,
      )
      orderChart2Loading.value = !(data && data.length > 0)
    } else {
      const isEmpty = checkOvertimeTrendDataEmpty(data)
      // 无论数据是否为空，都要更新 x 轴数据
      updateOvertimeTrendChart(data, v)
      updateChart(
        chartInstances[2],
        chartConfig3,
        isEmpty,
        true,
        chartTimes3.value,
        overtimeTooltipFormatter,
      )
      orderChart3Loading.value = !(data && data.length > 0)
    }
  } catch (error) {
    console.log(error)
  }
}

// 空数据提示文字
const generatePeriodText = (timeRange: string): string => {
  if (timeRange === '0') {
    const startTime = new Date(new Date().setDate(new Date().getDate() - 14))
      .toLocaleDateString('zh-CN', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
      })
      .replace(/\//g, '-')

    return `当前周期（${startTime} 至 ${yesterday}）暂无订单数据\n\n请在订单流转后等待数据更新查看趋势`
  } else if (timeRange === '1') {
    // 8周前该周周一的日期
    const now = new Date()
    const eightWeeksAgo = new Date(now.getTime() - 8 * 7 * 24 * 60 * 60 * 1000)
    const dayOfWeek = eightWeeksAgo.getDay() // 0=周日, 1=周一, ..., 6=周六
    const daysToMonday = dayOfWeek === 0 ? -6 : 1 - dayOfWeek // 如果是周日，往前6天；否则往前到周一
    const mondayDate = new Date(
      eightWeeksAgo.getTime() + daysToMonday * 24 * 60 * 60 * 1000,
    )
    const startTime = mondayDate
      .toLocaleDateString('zh-CN', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
      })
      .replace(/\//g, '-')

    // 上个周日的日期
    const today = new Date()
    const todayDayOfWeek = today.getDay() // 0=周日, 1=周一, ..., 6=周六
    const daysToLastSunday = todayDayOfWeek === 0 ? -7 : -todayDayOfWeek // 如果是周日，往前7天；否则往前到上一个周日
    const lastSunday = new Date(
      today.getTime() + daysToLastSunday * 24 * 60 * 60 * 1000,
    )
    const endTime = lastSunday
      .toLocaleDateString('zh-CN', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
      })
      .replace(/\//g, '-')

    return `当前周期（${startTime} 至 ${endTime}）暂无订单数据\n\n请在订单流转后等待数据更新查看趋势`
  } else if (timeRange === '2') {
    // 六个月前该月第一天的日期
    const now = new Date()
    const sixMonthsAgo = new Date(now.getFullYear(), now.getMonth() - 6, 1)
    const startTime = sixMonthsAgo
      .toLocaleDateString('zh-CN', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
      })
      .replace(/\//g, '-')

    // 上一月第一天的日期
    const currentDate = new Date()
    const lastMonthFirstDay = new Date(
      currentDate.getFullYear(),
      currentDate.getMonth() - 1,
      1,
    )
    const endTime = lastMonthFirstDay
      .toLocaleDateString('zh-CN', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
      })
      .replace(/\//g, '-')

    return `当前周期（${startTime} 至 ${endTime}）暂无订单数据\n\n请在订单流转后等待数据更新查看趋势`
  }
  return ''
}

// 更新图表（统一处理空状态和正常状态）
const updateChart = (
  instance: echarts.ECharts | null,
  config: Ref<ChartConfig>,
  isEmpty: boolean,
  isPercent = false,
  timeRange: string,
  customFormatter?: (params: TooltipParam[]) => string,
) => {
  if (!instance) return
  if (isEmpty) {
    const periodText = generatePeriodText(timeRange)
    setNotopt(instance, config, periodText, isPercent)
  } else {
    // 使用 notMerge: true 完全替换配置，确保从空状态切换回来时配置正确
    instance.setOption(
      createChartOption(config, isPercent, customFormatter),
      true,
    )
  }
}

// 图表空状态
const setNotopt = (
  demo: echarts.ECharts | null,
  config: Ref<ChartConfig>,
  subtext = '暂无数据',
  isPercent = false,
) => {
  if (!demo) return
  const chartData = config.value
  const option = {
    title: [
      {
        text: chartData.title,
        left: 'left',
      },
      {
        text: ' {a|}',
        x: 'center',
        y: 'center',
        subtext,
        itemGap: -20,
        textStyle: {
          rich: {
            a: {
              color: '#000',
              fontSize: '16',
              height: 120,
              width: 220,
              backgroundColor: {
                image:
                  'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjQiIGhlaWdodD0iNDEiIHZpZXdCb3g9IjAgMCA2NCA0MSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCiAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAxKSIgZmlsbD0ibm9uZSIgZmlsbFJ1bGU9ImV2ZW5vZGQiPg0KICAgIDxlbGxpcHNlIGZpbGw9IiNkZGQiIGN4PSIzMiIgY3k9IjMzIiByeD0iMzIiIHJ5PSI3IiAvPg0KICAgIDxnIGZpbGxSdWxlPSJub256ZXJvIiBzdHJva2U9IiM5OTkiPg0KICAgICAgPHBhdGgNCiAgICAgICAgZD0iTTU1IDEyLjc2TDQ0Ljg1NCAxLjI1OEM0NC4zNjcuNDc0IDQzLjY1NiAwIDQyLjkwNyAwSDIxLjA5M2MtLjc0OSAwLTEuNDYuNDc0LTEuOTQ3IDEuMjU3TDkgMTIuNzYxVjIyaDQ2di05LjI0eiIgLz4NCiAgICAgIDxwYXRoDQogICAgICAgIGQ9Ik00MS42MTMgMTUuOTMxYzAtMS42MDUuOTk0LTIuOTMgMi4yMjctMi45MzFINTV2MTguMTM3QzU1IDMzLjI2IDUzLjY4IDM1IDUyLjA1IDM1aC00MC4xQzEwLjMyIDM1IDkgMzMuMjU5IDkgMzEuMTM3VjEzaDExLjE2YzEuMjMzIDAgMi4yMjcgMS4zMjMgMi4yMjcgMi45Mjh2LjAyMmMwIDEuNjA1IDEuMDA1IDIuOTAxIDIuMjM3IDIuOTAxaDE0Ljc1MmMxLjIzMiAwIDIuMjM3LTEuMzA4IDIuMjM3LTIuOTEzdi0uMDA3eiINCiAgICAgICAgZmlsbD0iI2UxZTFlMSIgLz4NCiAgICA8L2c+DQogIDwvZz4NCjwvc3ZnPg==',
              },
            },
          },
        },
        subtextStyle: {
          fontSize: 16,
        },
      },
    ],
    // 图例
    legend: {
      data: chartData.legend,
      top: 'top',
      left: 'center',
    },
    // 横坐标
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: chartData.xAxisData,
      axisLabel: {
        overflow: 'truncate',
        width: 120,
        formatter: function (value: string) {
          if (value.length > 10) {
            return value.substring(0, 10) + '...'
          }
          return value
        },
      },
    },
    // 网格配置
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
    },
    // 纵坐标，默认范围从0到1
    yAxis: {
      type: 'value',
      min: 0,
      max: 1,
      axisLabel: isPercent
        ? {
            formatter: '{value}%',
            color: '#666',
          }
        : {
            color: '#666',
          },
      axisLine: {
        lineStyle: { color: '#ccc' },
      },
      splitLine: {
        show: false,
      },
    },
    // 清空 series 数据
    series: chartData.series.map((item) => ({
      name: item.name,
      type: 'line',
      data: [],
      color: item.color,
    })),
  }
  demo.setOption(option, true)
}

// 检查订单趋势数据是否为空
const checkOrderTrendDataEmpty = (data: trendType[]): boolean => {
  const confirmNums = data.map((el) => el.confirmNum)
  const produceNums = data.map((el) => el.produceNum)
  const shipmentNums = data.map((el) => el.shipmentNum)
  const hasData =
    confirmNums.some((item) => item !== 0) ||
    produceNums.some((item) => item !== 0) ||
    shipmentNums.some((item) => item !== 0)
  return !hasData
}

// 更新订单趋势图表数据
const updateOrderTrendChart = (data: trendType[], type: number | string) => {
  const confirmNums = data.map((el) => el.confirmNum)
  const produceNums = data.map((el) => el.produceNum)
  const shipmentNums = data.map((el) => el.shipmentNum)
  const startTimes = data.map((el) => el.startTime)
  const timerange = data.map((el) => `${el.startTime}——${el.endTime}`)

  if (type == 0) {
    chartConfig1.value.xAxisData = startTimes
  } else {
    chartConfig1.value.xAxisData = timerange
  }

  chartConfig1.value.series[0].data = confirmNums
  chartConfig1.value.series[1].data = produceNums
  chartConfig1.value.series[2].data = shipmentNums
}

// 检查发货效率数据是否为空
const checkShipmentTrendDataEmpty = (data: trendType[]): boolean => {
  const shipmentRateOf24Hours = data.map((el) => el.shipmentRateOf24Hour)
  const shipmentRateOf48Hours = data.map((el) => el.shipmentRateOf48Hour)
  const hasData =
    shipmentRateOf24Hours.some((item) => item !== 0) ||
    shipmentRateOf48Hours.some((item) => item !== 0)
  return !hasData
}

// 更新发货效率图表数据
const updateShipmentTrendChart = (data: trendType[], type: number | string) => {
  const shipmentRateOf24Hours = data.map((el) => el.shipmentRateOf24Hour)
  const shipmentRateOf48Hours = data.map((el) => el.shipmentRateOf48Hour)
  const startTimes = data.map((el) => el.startTime)
  const timerange = data.map((el) => `${el.startTime}-${el.endTime}`)

  if (type == 0) {
    chartConfig2.value.xAxisData = startTimes
  } else {
    chartConfig2.value.xAxisData = timerange
  }

  chartConfig2.value.series[0].data = shipmentRateOf24Hours
  chartConfig2.value.series[1].data = shipmentRateOf48Hours
}

// 检查超时情况数据是否为空
const checkOvertimeTrendDataEmpty = (data: trendType[]): boolean => {
  const overtimeShipmentRates = data.map((el) => el.overtimeShipmentRate)
  const hasData = overtimeShipmentRates.some((item) => item !== 0)
  return !hasData
}

// 更新超时情况图表数据
const updateOvertimeTrendChart = (data: trendType[], type: number | string) => {
  const overtimeShipmentOrderNums = data.map(
    (el) => el.overtimeShipmentOrderNum,
  )
  const overtimeShipmentRates = data.map((el) => el.overtimeShipmentRate)
  const startTimes = data.map((el) => el.startTime)
  const timerange = data.map((el) => `${el.startTime}-${el.endTime}`)

  if (type == 0) {
    chartConfig3.value.xAxisData = startTimes
  } else {
    chartConfig3.value.xAxisData = timerange
  }

  chartConfig3.value.series[0].data = overtimeShipmentRates.map(
    (rate, idx) => ({
      value: rate,
      count: overtimeShipmentOrderNums[idx],
    }),
  )
}

const handleResize = () => {
  chartInstances.forEach((instance) => {
    instance?.resize()
  })
}

onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize)
  chartInstances.forEach((instance, index) => {
    instance?.dispose()
    chartInstances[index] = null
  })
})
</script>
<style lang="scss" scoped>
.dashboard-title {
  font-size: 18px;
  font-weight: 600;
  color: #333;
  padding: 20px;
}
.card-wrapper {
  background-color: #fff;
}
.card-container-wrapper {
  padding: 0 20px 20px;
}
.card-container {
  width: 100%;
  background-color: #fff;
  border-radius: 5px;
  box-sizing: border-box;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
  &:not(:last-child) {
    margin-bottom: 20px;
  }

  .card-item {
    min-width: 270px;
    height: 120px;
    background-color: #f7f7f7;
    border-radius: 5px;
    padding: 8px 15px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;

    .card-item-header {
      display: flex;
      align-items: center;

      .card-title {
        font-size: 18px;
        font-weight: 600;
        color: #333;
      }

      .card-icon {
        width: 20px;
        height: 20px;
        cursor: pointer;
        background-size: 100% 100%;
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='256' height='256' viewBox='0 0 256 256'%3E%3Cpath fill='%238e8d8d' d='M140 180a12 12 0 1 1-12-12a12 12 0 0 1 12 12M128 72c-22.06 0-40 16.15-40 36v4a8 8 0 0 0 16 0v-4c0-11 10.77-20 24-20s24 9 24 20s-10.77 20-24 20a8 8 0 0 0-8 8v8a8 8 0 0 0 16 0v-.72c18.24-3.35 32-17.9 32-35.28c0-19.85-17.94-36-40-36m104 56A104 104 0 1 1 128 24a104.11 104.11 0 0 1 104 104m-16 0a88 88 0 1 0-88 88a88.1 88.1 0 0 0 88-88'/%3E%3C/svg%3E");
      }
    }

    .card-item-content-box {
      display: flex;
      align-items: flex-end;
      gap: 10px;

      .card-item-content {
        font-size: 50px;
        font-weight: 500;
        white-space: nowrap;
      }

      .card-item-content-text {
        font-size: 14px;
        color: #666;
        display: flex;
        align-items: center;
        margin-right: 10px;
        width: 100%;
        white-space: nowrap;
        margin-bottom: 3px;
      }
    }
  }
}

.text-blue {
  color: #409eff;
}

.text-green {
  color: #67c23a;
}

.text-red {
  color: #f56c6c;
}

.text-yellow {
  color: #e6a23c;
}

.dashboard-wrapper {
  height: 100%;
  width: 100%;
  margin: 0 auto;
  overflow-x: hidden;
}

.chart-wrapper {
  position: relative;
  margin-top: 20px;
}

.chart-container {
  min-height: 500px;
  height: 500px;
  background-color: #fff;
  border-radius: 5px;
  padding: 20px;
  box-sizing: border-box;
}

.chart-controls {
  position: absolute;
  top: 30px;
  right: 30px;
  z-index: 10;
}

.charts-row {
  display: flex;
  gap: 10px;
}

.chart-half {
  width: 50%;
}

@media (max-width: 1000px) {
  .charts-row {
    flex-direction: column;
  }

  .chart-half {
    width: 100%;
  }
}
</style>

<style lang="scss">
.up-icon-red {
  width: 18px;
  height: 18px;
  background-size: 100% 100%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='256' height='256' viewBox='0 0 24 24'%3E%3Cpath fill='%23f56c6c' d='M12.725 2.451a.75.75 0 0 0-1.007-.013L3.504 9.69A.75.75 0 0 0 4 11.003h4.382c.138 1.255.057 2.576-.252 3.969c-.318 1.434-1.722 3.25-4.515 5.438a.75.75 0 0 0 .535 1.337c3.311-.322 6.112-1.537 8.365-3.662c2.08-1.963 3.228-4.334 3.422-7.082H20a.75.75 0 0 0 .511-1.299z'/%3E%3C/svg%3E");
}
.up-icon-green {
  width: 18px;
  height: 18px;
  background-size: 100% 100%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%2367C23A' d='M12.725 2.451a.75.75 0 0 0-1.007-.013L3.504 9.69A.75.75 0 0 0 4 11.003h4.382c.138 1.255.057 2.576-.252 3.969c-.318 1.434-1.722 3.25-4.515 5.438a.75.75 0 0 0 .535 1.337c3.311-.322 6.112-1.537 8.365-3.662c2.08-1.963 3.228-4.334 3.422-7.082H20a.75.75 0 0 0 .511-1.299z'/%3E%3C/svg%3E");
}
.down-icon-green {
  width: 18px;
  height: 18px;
  background-size: 100% 100%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='256' height='256' viewBox='0 0 24 24'%3E%3Cpath fill='%2367C23A' d='M4.15 2.253a.75.75 0 0 0-.535 1.337C6.408 5.778 7.812 7.594 8.13 9.028c.309 1.393.39 2.714.252 3.969H4a.75.75 0 0 0-.496 1.312l8.214 7.253a.75.75 0 0 0 1.007-.013l7.786-7.253a.75.75 0 0 0-.511-1.3h-4.063c-.194-2.747-1.342-5.118-3.422-7.08C10.262 3.79 7.46 2.574 4.15 2.252'/%3E%3C/svg%3E");
}
.down-icon-red {
  width: 18px;
  height: 18px;
  background-size: 100% 100%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23F56C6C' d='M4.15 2.253a.75.75 0 0 0-.535 1.337C6.408 5.778 7.812 7.594 8.13 9.028c.309 1.393.39 2.714.252 3.969H4a.75.75 0 0 0-.496 1.312l8.214 7.253a.75.75 0 0 0 1.007-.013l7.786-7.253a.75.75 0 0 0-.511-1.3h-4.063c-.194-2.747-1.342-5.118-3.422-7.08C10.262 3.79 7.46 2.574 4.15 2.252'/%3E%3C/svg%3E");
}
</style>
