<template>
  <view class="page" @click="closeMoreMenu">
    <!-- 固定顶部导航栏 -->
    <AnalyticsTopBar 
      :title="'配送效率分析'"
      :lastUpdateTime="lastUpdateTime"
      :sidebarVisible="showSidebarMenu"
      @menu-click="handleMenu"
      @refresh="refreshData"
      @search="handleSearch"
      @notification="handleNotification"
      @fullscreen="handleFullscreen"
      @mobile="handleMobile"
      @dropdown="handleDropdown"
      @settings="handleSettings"
    />
    
    <view class="page-layout">
      <!-- 侧边栏菜单组件 -->
      <AnalyticsSidebarMenu 
        :visible="showSidebarMenu" 
        :currentPath="currentPath"
        @visible-change="handleSidebarUpdate"
      />
      
      <!-- 主内容区域 -->
      <view class="main-content">
        <view class="container">

      <!-- 时间维度筛选（快捷 + 自定义） -->
      <view class="tabs">
        <view
          v-for="p in timePeriods"
          :key="p.value"
          class="tab"
          :class="{ active: selectedPeriod === p.value && !customRangeEnabled }"
          @click="selectPeriod(p.value)"
        >
          {{ p.label }}
        </view>
        <view
          class="tab"
          :class="{ active: customRangeEnabled }"
          @click="toggleCustomRange"
        >
          自定义
        </view>
      </view>

      <AnalyticsDateRangePicker
        v-if="customRangeEnabled"
        :initialStartDate="selectedStartDate"
        :initialEndDate="selectedEndDate"
        @apply="onDateRangeApply"
        @clear="onDateRangeClear"
      />

      <!-- KPI 指标卡片 -->
      <view class="kpi-grid">
        <view class="kpi-card">
          <text class="kpi-label">配送时效</text>
          <text class="kpi-value">{{ deliveryData.avg_delivery_time }}分钟</text>
          <text class="kpi-meta">较上期：{{ formatPct(deliveryData.time_growth) }}</text>
        </view>
        <view class="kpi-card">
          <text class="kpi-label">配送费用</text>
          <text class="kpi-value">¥{{ formatMoney(deliveryData.total_fee) }}</text>
          <text class="kpi-meta">平均：¥{{ formatMoney(deliveryData.avg_fee) }}</text>
        </view>
        <view class="kpi-card">
          <text class="kpi-label">配送员效率</text>
          <text class="kpi-value">{{ formatInt(deliveryData.avg_orders_per_driver) }}</text>
          <text class="kpi-meta">单/人/天</text>
        </view>
        <view class="kpi-card">
          <text class="kpi-label">客户满意度</text>
          <text class="kpi-value">{{ formatScore(deliveryData.satisfaction_rate) }}分</text>
          <text class="kpi-meta">较上期：{{ formatPct(deliveryData.satisfaction_growth) }}</text>
        </view>
      </view>

      <!-- 配送时效 & 满意度（合并图表） -->
      <view class="card card-full">
        <view class="card-head">
          <text class="card-title">配送时效 & 满意度</text>
          <text class="card-desc">{{ selectedPeriodText }} · 平均配送时间 / 满意度趋势</text>
        </view>
        <EChartsView class="chart-box" :option="timeChartOption" />
      </view>

      <!-- 配送费用分析 -->
      <view class="card">
        <view class="card-head">
          <text class="card-title">配送费用分析</text>
          <text class="card-desc">费用分布情况</text>
        </view>
        <EChartsView class="chart-box" :option="feeChartOption" />
      </view>

      <!-- 配送员效率排行 -->
      <view class="card">
        <view class="card-head">
          <text class="card-title">配送员效率排行 TOP 10</text>
          <text class="card-desc">按订单数排序</text>
        </view>
        <view class="rank-scroll" @mouseenter="onRankHover(true)" @mouseleave="onRankHover(false)">
          <scroll-view class="rank-scroll-inner" :scroll-y="true" :show-scrollbar="true">
            <view class="rank-list">
              <view v-for="d in topDrivers" :key="d.id" class="rank-item">
                <text class="rank-no">{{ d.rank }}</text>
                <text class="rank-name">{{ d.name }}</text>
                <view class="rank-right">
                  <text class="rank-val">{{ d.orders }} 单</text>
                  <text class="chip" :class="d.rating >= 4.5 ? 'pos' : 'neg'">
                    ⭐{{ d.rating }}
                  </text>
                </view>
              </view>
            </view>
          </scroll-view>
        </view>
      </view>

      <!-- 留白 -->
      <view style="height: 24px;"></view>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup lang="uts">
import { computed, reactive, ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'

import AnalyticsSidebarMenu from '@/components/analytics/AnalyticsSidebarMenu.uvue'
import AnalyticsTopBar from '@/components/analytics/AnalyticsTopBar.uvue'
import AnalyticsDateRangePicker from '@/components/analytics/AnalyticsDateRangePicker.uvue'
import EChartsView from '@/uni_modules/charts/EChartsView.vue'

import { fetchDeliveryAnalysis } from '@/services/analytics/deliveryAnalysisService.uts'
import { mapAnalyticsError } from '@/services/analytics/errorMapper.uts'

import type { TimePeriod } from '@/types/analytics/common.uts'
import type { DeliveryData, DriverRank } from '@/types/analytics/delivery.uts'

const lastUpdateTime = ref('')
const selectedPeriod = ref('7d')

const customRangeEnabled = ref(false)
const selectedStartDate = ref('')
const selectedEndDate = ref('')

const showMoreMenu = ref(false)
const showSidebarMenu = ref(false)
const currentPath = ref('/pages/mall/analytics/delivery-analysis')

const timePeriods = ref<Array<TimePeriod>>([
  { value: '7d', label: '7天' },
  { value: '30d', label: '30天' },
  { value: '90d', label: '90天' },
  { value: '1y', label: '1年' }
])

const deliveryData = reactive<DeliveryData>({
  avg_delivery_time: 0,
  time_growth: 0,
  total_fee: 0,
  avg_fee: 0,
  avg_orders_per_driver: 0,
  satisfaction_rate: 0,
  satisfaction_growth: 0
})

const topDrivers = reactive<Array<DriverRank>>([])

const timeChartOption = ref<any>({})
const feeChartOption = ref<any>({})
const isRankHover = ref(false)

const _trendRows = ref<Array<UTSJSONObject>>([])

const selectedPeriodText = computed((): string => {
  const p = timePeriods.value.find((t) => t.value === selectedPeriod.value)
  return p ? p.label : '7天'
})

onLoad(() => {
  updateTime()
  loadDeliveryData()
})

async function loadDeliveryData() {
  try {
    const range = selectedStartDate.value && selectedEndDate.value
      ? { start: selectedStartDate.value, end: selectedEndDate.value }
      : null

    const data: any = await fetchDeliveryAnalysis(selectedPeriod.value, range)
    const trendList = data.trendList
    const topList = data.topList

    const trendRows: Array<UTSJSONObject> = []
    let totalFee = 0
    let totalOrders = 0

    for (let i = 0; i < trendList.length; i++) {
      const r = trendList[i]
      const dayStr = r.getString('day') ?? ''
      const orders = r.getNumber('completed_orders') ?? 0
      const avgMin = r.getNumber('avg_delivery_minutes') ?? 0
      const avgFee = r.getNumber('avg_fee') ?? 0
      const tFee = r.getNumber('total_fee') ?? 0

      totalOrders += orders
      totalFee += tFee

      const obj = new UTSJSONObject()
      obj.set('day', dayStr)
      obj.set('avg_delivery_time', avgMin)
      obj.set('avg_fee', avgFee)
      obj.set('satisfaction_rate', 0)
      trendRows.push(obj)
    }

    let satisSum = 0
    let satisCnt = 0
    for (let i = 0; i < topList.length; i++) {
      const r = topList[i]
      const rating = r.getNumber('rating_avg')
      if (rating != null) {
        satisSum += rating
        satisCnt += 1
      }
    }
    const satisAvg = satisCnt > 0 ? satisSum / satisCnt : 0
    for (let i = 0; i < trendRows.length; i++) {
      trendRows[i].set('satisfaction_rate', satisAvg)
    }

    const last = trendRows.length > 0 ? trendRows[trendRows.length - 1] : null
    const prev = trendRows.length > 1 ? trendRows[trendRows.length - 2] : null

    const lastAvgTime = last != null ? last.getNumber('avg_delivery_time') ?? 0 : 0
    const prevAvgTime = prev != null ? prev.getNumber('avg_delivery_time') ?? 0 : 0
    const timeGrowth = prevAvgTime > 0 ? ((lastAvgTime - prevAvgTime) / prevAvgTime) * 100 : 0

    const lastSatis = last != null ? last.getNumber('satisfaction_rate') ?? 0 : 0
    const prevSatis = prev != null ? prev.getNumber('satisfaction_rate') ?? 0 : 0
    const satisGrowth = prevSatis > 0 ? ((lastSatis - prevSatis) / prevSatis) * 100 : 0

    const dayCount = Math.max(1, trendRows.length)
    const driverCount = Math.max(1, topList.length)
    const avgOrdersPerDriverPerDay = (totalOrders / driverCount) / dayCount

    deliveryData.avg_delivery_time = Math.round(lastAvgTime)
    deliveryData.time_growth = timeGrowth
    deliveryData.total_fee = totalFee
    deliveryData.avg_fee = totalOrders > 0 ? totalFee / totalOrders : 0
    deliveryData.avg_orders_per_driver = avgOrdersPerDriverPerDay
    deliveryData.satisfaction_rate = lastSatis
    deliveryData.satisfaction_growth = satisGrowth

    _trendRows.value = trendRows

    const list: Array<DriverRank> = []
    for (let i = 0; i < topList.length; i++) {
      const r = topList[i]
      list.push({
        id: r.getString('driver_id') ?? String(i),
        rank: i + 1,
        name: r.getString('driver_name') ?? '未知',
        orders: r.getNumber('orders') ?? 0,
        rating: r.getNumber('rating_avg') ?? 0
      })
    }
    topDrivers.splice(0, topDrivers.length, ...list)

    updateTime()
    buildChartOptions()
  } catch (e) {
    console.error('loadDeliveryData failed:', e)
    updateTime()
    buildChartOptions()
    uni.showToast({ title: mapAnalyticsError(e, { fallbackMessage: '配送分析数据加载失败' }), icon: 'none' })
  }
}

function selectPeriod(p: string) {
  selectedPeriod.value = p
  customRangeEnabled.value = false
  selectedStartDate.value = ''
  selectedEndDate.value = ''
  loadDeliveryData()
}

function toggleCustomRange() {
  customRangeEnabled.value = !customRangeEnabled.value
}

function onDateRangeApply(range: { start: string; end: string }) {
  selectedStartDate.value = range.start
  selectedEndDate.value = range.end
  customRangeEnabled.value = true
  loadDeliveryData()
}

function onDateRangeClear() {
  selectedStartDate.value = ''
  selectedEndDate.value = ''
  customRangeEnabled.value = false
  loadDeliveryData()
}

function refreshData() {
  loadDeliveryData()
  uni.showToast({ title: '已刷新', icon: 'success' })
}

function exportReport() {
  uni.showActionSheet({
    itemList: ['导出Excel', '导出PDF', '导出图片'],
    success: () => uni.showToast({ title: '导出成功', icon: 'success' })
  })
}

function updateTime() {
  const now = new Date()
  const hh = now.getHours().toString().padStart(2, '0')
  const mm = now.getMinutes().toString().padStart(2, '0')
  lastUpdateTime.value = `${hh}:${mm}`
}

function formatInt(n: number): string {
  const v = isFinite(n) ? Math.round(n) : 0
  if (v >= 10000) return (v / 10000).toFixed(1) + '万'
  return v.toString()
}

function formatMoney(n: number): string {
  const v = isFinite(n) ? n : 0
  if (v >= 10000) return (v / 10000).toFixed(1) + '万'
  return v.toFixed(2)
}

function formatPct(n: number): string {
  const v = isFinite(n) ? n : 0
  const sign = v > 0 ? '+' : ''
  return `${sign}${v.toFixed(1)}%`
}

function formatScore(n: number): string {
  const v = isFinite(n) ? n : 0
  return v.toFixed(1)
}

function buildChartOptions() {
  const rows = Array.isArray(_trendRows.value) ? _trendRows.value : []

  const xAxis: string[] = []
  const timeSeries: number[] = []
  const feeSeries: number[] = []
  const satisSeries: number[] = []

  for (let i = 0; i < rows.length; i++) {
    const r = rows[i]
    const day = r.getString('day') ?? ''
    xAxis.push(day.length >= 10 ? day.substring(5, 10) : day)
    timeSeries.push(r.getNumber('avg_delivery_time') ?? 0)
    feeSeries.push(r.getNumber('avg_fee') ?? 0)
    satisSeries.push(r.getNumber('satisfaction_rate') ?? 0)
  }

  timeChartOption.value = {
    tooltip: { trigger: 'axis' },
    legend: {
      data: ['平均配送时间(分钟)', '满意度(评分)'],
      top: 'bottom',
      itemGap: 30,
      itemWidth: 16,
      itemHeight: 16
    },
    grid: { left: 40, right: 50, top: 30, bottom: 60 },
    xAxis: {
      type: 'category',
      data: xAxis,
      axisTick: { alignWithLabel: true }
    },
    yAxis: [
      {
        type: 'value',
        name: '配送时间',
        min: 0,
        splitLine: { lineStyle: { color: '#e5e7eb' } }
      },
      {
        type: 'value',
        name: '满意度',
        min: 0,
        max: 5,
        position: 'right',
        splitLine: { show: false }
      }
    ],
    series: [
      {
        name: '平均配送时间(分钟)',
        type: 'line',
        smooth: true,
        symbolSize: 6,
        data: timeSeries,
        yAxisIndex: 0
      },
      {
        name: '满意度(评分)',
        type: 'line',
        smooth: true,
        symbol: 'circle',
        symbolSize: 6,
        data: satisSeries,
        yAxisIndex: 1
      }
    ]
  }

  feeChartOption.value = {
    tooltip: { trigger: 'axis' },
    grid: { left: 40, right: 20, top: 20, bottom: 30 },
    xAxis: { type: 'category', data: xAxis },
    yAxis: { type: 'value' },
    series: [
      {
        name: '平均配送费(元)',
        type: 'bar',
        data: feeSeries
      }
    ]
  }
}

function handleMenu() {
  showSidebarMenu.value = true
}

function handleSidebarUpdate(visible: boolean) {
  showSidebarMenu.value = visible
}

function toggleMoreMenu() {
  showMoreMenu.value = !showMoreMenu.value
}

function closeMoreMenu() {
  showMoreMenu.value = false
}

function handleSearch() {
  uni.showToast({ title: '搜索', icon: 'none' })
}

function handleNotification() {
  uni.showToast({ title: '通知', icon: 'none' })
}

function handleFullscreen() {
  uni.showToast({ title: '全屏', icon: 'none' })
}

function handleMobile() {
  uni.showToast({ title: '移动端', icon: 'none' })
}

function handleDropdown() {
  uni.showToast({ title: '下拉菜单', icon: 'none' })
}

function handleSettings() {
  uni.showToast({ title: '设置', icon: 'none' })
}

function onRankHover(hover: boolean) {
  isRankHover.value = hover
}
</script>

<style>
.page {
  min-height: 100vh;
  background: #f6f7fb;
}

/* 页面布局：宽屏时侧边栏+内容，窄屏时全屏内容 */
.page-layout {
  display: flex;
  flex-direction: row !important;
  min-height: 100vh;
}

.main-content {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding-top: 64px; /* 为固定顶部导航栏留出空间 */
}

.container {
  width: 100%;
  max-width: 1280px;
  margin: 0 auto;
  padding: 16px 16px 28px;
  box-sizing: border-box;
}

/* 顶部栏 */
.topbar {
  display: flex;
  flex-direction: row !important;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: #fff;
  border-radius: 14px;
  border: 1px solid rgba(0,0,0,0.06);
  width: 100%;
  box-sizing: border-box;
  overflow: hidden;
}

.topbar-left {
  display: flex;
  flex-direction: row !important;
  align-items: center;
  gap: 12px;
  flex: 1;
  min-width: 0;
}

.menu-icon {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: #f3f4f6;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s;
}

.menu-icon:active {
  background: #e5e7eb;
  transform: scale(0.95);
}

.menu-icon .icon {
  font-size: 18px;
  color: #111;
  line-height: 1;
}

.title-group {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  min-width: 0;
}

.title {
  font-size: 18px;
  font-weight: 700;
  color: #111;
  max-width: 420px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.subtitle {
  font-size: 12px;
  color: rgba(0,0,0,0.55);
  max-width: 420px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.topbar-right {
  display: flex;
  flex-direction: row !important;
  gap: 8px;
  align-items: center;
  flex-wrap: nowrap;
  flex-shrink: 0;
  position: relative;
  white-space: nowrap;
}

.icon-btn-icon {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: #f3f4f6;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s;
  flex-shrink: 0;
}

.icon-btn-icon:active {
  background: #e5e7eb;
  transform: scale(0.95);
}

.icon-btn-icon .icon {
  font-size: 16px;
  line-height: 1;
}

.more-btn {
  display: none;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: #f3f4f6;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  position: relative;
  transition: all 0.2s;
  flex-shrink: 0;
}

.more-btn.active {
  background: #e5e7eb;
}

.more-btn .icon {
  font-size: 18px;
  line-height: 1;
  color: #111;
}

/* 时间维度 tabs */
.tabs {
  margin-top: 12px;
  display: flex;
  flex-direction: row !important;
  gap: 8px;
  padding: 8px;
  background: #fff;
  border-radius: 14px;
  border: 1px solid rgba(0,0,0,0.06);
  overflow-x: auto;
  flex-wrap: wrap;
  justify-content: center;
}

.tab {
  padding: 8px 12px;
  border-radius: 999px;
  background: #f3f4f6;
  color: #111;
  font-size: 13px;
  white-space: nowrap;
  flex-shrink: 0;
}

.tab.active {
  background: #111;
  color: #fff;
}

/* KPI 网格 */
.kpi-grid {
  margin-top: 12px;
  display: flex;
  flex-direction: row !important;
  flex-wrap: wrap;
  gap: 12px;
}

.kpi-card {
  background: #fff;
  border-radius: 14px;
  border: 1px solid rgba(0,0,0,0.06);
  padding: 14px;
  box-sizing: border-box;
  flex: 1 1 calc(50% - 6px);
  min-width: 260px;
}

.kpi-label {
  font-size: 12px;
  color: rgba(0,0,0,0.55);
}

.kpi-value {
  margin-top: 8px;
  font-size: 22px;
  font-weight: 800;
  color: #111;
}

.kpi-meta {
  margin-top: 8px;
  font-size: 12px;
  color: rgba(0,0,0,0.55);
}

/* 卡片 */
.card {
  margin-top: 12px;
  background: #fff;
  border-radius: 16px;
  border: 1px solid rgba(0,0,0,0.06);
  box-shadow: 0 2px 10px rgba(0,0,0,0.04);
  padding: 14px;
  box-sizing: border-box;
}

.card-full {
  width: 100%;
}

.card-head {
  display: flex;
  flex-direction: row !important;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 16px;
}

.card-title {
  font-size: 14px;
  font-weight: 600;
  color: #111;
}

.card-desc {
  font-size: 12px;
  color: rgba(0,0,0,0.55);
}

.chart-box {
  width: 100%;
  height: 360px;
}

.rank-scroll {
  height: 320px;
  border-radius: 12px;
}

.rank-scroll-inner {
  height: 100%;
}

.rank-scroll-inner::-webkit-scrollbar {
  width: 0;
  height: 0;
}

.rank-scroll:hover .rank-scroll-inner::-webkit-scrollbar {
  width: 8px;
}

.rank-scroll:hover .rank-scroll-inner::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.25);
  border-radius: 999px;
}

.rank-scroll:hover .rank-scroll-inner::-webkit-scrollbar-track {
  background: rgba(0, 0, 0, 0.06);
}

.rank-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.rank-item {
  display: flex;
  flex-direction: row !important;
  align-items: center;
  gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid rgba(0,0,0,0.06);
}

.rank-item:last-child {
  border-bottom: none;
}

.rank-no {
  width: 28px;
  height: 28px;
  border-radius: 999px;
  background: rgba(0,0,0,0.06);
  text-align: center;
  line-height: 28px;
  font-size: 12px;
  flex: 0 0 auto;
}

.rank-name {
  flex: 1;
  font-size: 13px;
  color: #111;
}

.rank-val {
  font-size: 13px;
  color: rgba(0,0,0,0.65);
}

.rank-right {
  display: flex;
  flex-direction: row !important;
  align-items: center;
  gap: 8px;
}

.chip {
  padding: 3px 8px;
  border-radius: 999px;
  font-size: 12px;
}

.chip.pos {
  background: rgba(34,197,94,0.12);
  color: #16a34a;
}

.chip.neg {
  background: rgba(239,68,68,0.12);
  color: #dc2626;
}

@media screen and (min-width: 960px) {
  .kpi-card {
    flex: 1 1 calc(25% - 9px);
    min-width: 200px;
  }
}

@media screen and (max-width: 960px) {
  .title,
  .subtitle {
    max-width: 200px;
  }

  .topbar-right .btn-hidden {
    display: none !important;
  }

  .more-btn {
    display: flex !important;
  }
}

@media screen and (max-width: 959px) {
  .page-layout {
    flex-direction: column !important;
  }

  .main-content {
    width: 100%;
  }
}
</style>
