<template>
  <view class="region-map">
    <view class="map-head">
      <view class="map-head-left">
        <text class="map-title">销售地域分布</text>
        <view class="map-switch">
          <view 
            class="map-switch-btn" 
            :class="{ active: mapType === 'china' }"
            @click="switchMapType('china')"
          >
            中国地图
          </view>
          <view 
            class="map-switch-btn" 
            :class="{ active: mapType === 'world' }"
            @click="switchMapType('world')"
          >
            全国地图
          </view>
        </view>
      </view>
    </view>
    <view v-if="loading || !chartOption || chartOption == null" class="chart-loading">
      <text>{{ loading ? '加载中...' : '暂无数据' }}</text>
    </view>
    <EChartsView v-else class="chart-box" :option="chartOption" :key="'map-' + mapType" />
  </view>
</template>

<script setup lang="uts">
import { ref, watch, onMounted } from 'vue'
import EChartsView from '@/uni_modules/charts/EChartsView.vue'

/**
 * 销售地域分布组件 (UTS / uni-app-x)
 * 1:1 复刻数据分析中心地图分布
 */

type RegionDataItem = { name: string; value: number }

const props = defineProps({
  startDate: { type: Date, required: true },
  endDate: { type: Date, required: true },
  topMerchants: { type: Array, default: () => [] as Array<any> },
  loading: { type: Boolean, default: false }
})

const mapType = ref('china')
const regionData = ref<Array<RegionDataItem>>([])
const chartOption = ref<any>(null)

// --- 数据处理逻辑 ---

function toPlainObject(obj: any): any {
  if (obj == null) return null
  if (typeof obj !== 'object') return obj
  if (Array.isArray(obj)) {
    return (obj as Array<any>).map((item : any) : any => toPlainObject(item))
  }
  const plain: Record<string, any> = {}
  const keys = Object.keys(obj as object)
  for (let i = 0; i < keys.length; i++) {
    const key = keys[i]
    const value = (obj as Record<string, any>)[key]
    if (typeof value === 'function' || key.startsWith('_') || key === 'toJSON') {
      continue
    }
    if (value != null && typeof value === 'object' && !Array.isArray(value)) {
      plain[key] = toPlainObject(value)
    } else {
      plain[key] = value
    }
  }
  return plain
}

function buildChartOption() {
  if (regionData.value.length === 0) {
    chartOption.value = null
    return
  }

  const currentData = regionData.value
  const maxValue = Math.max(...currentData.map((d: RegionDataItem): number => d.value), 1)

  let option: any = {}

  if (mapType.value === 'china') {
    option = {
      tooltip: {
        trigger: 'item'
      },
      visualMap: {
        min: 0,
        max: maxValue,
        left: 'left',
        top: 'bottom',
        text: ['高', '低'],
        inRange: {
          color: ['#e0f2fe', '#0ea5e9', '#0284c7', '#0369a1']
        },
        calculable: true,
        textStyle: {
          color: 'rgba(0,0,0,0.65)',
          fontSize: 12
        }
      },
      geo: {
        map: 'china',
        roam: false,
        zoom: 1.5,
        top: '40%',
        itemStyle: {
          areaColor: '#f0f0f0',
          borderColor: '#fff',
          borderWidth: 1
        },
        emphasis: {
          itemStyle: {
            areaColor: '#0ea5e9'
          },
          label: {
            show: true,
            color: '#111'
          }
        }
      },
      series: [
        {
          name: '销售额',
          type: 'map',
          map: 'china',
          geoIndex: 0,
          data: currentData,
          label: {
            show: true,
            fontSize: 11,
            color: 'rgba(0,0,0,0.75)'
          },
          itemStyle: {
            borderColor: '#fff',
            borderWidth: 1
          },
          emphasis: {
            itemStyle: {
              areaColor: '#0ea5e9',
              borderColor: '#fff',
              borderWidth: 2
            },
            label: {
              show: true,
              color: '#fff',
              fontSize: 12,
              fontWeight: 'bold'
            }
          }
        }
      ]
    }
  } else {
    option = {
      tooltip: {
        trigger: 'axis',
        axisPointer: { type: 'shadow' }
      },
      grid: { left: 60, right: 20, top: 36, bottom: 60 },
      xAxis: {
        type: 'category',
        data: currentData
          .sort((a, b) => b.value - a.value)
          .slice(0, 15)
          .map((d) => d.name),
        axisLabel: {
          rotate: 45,
          color: 'rgba(0,0,0,0.55)',
          fontSize: 12
        }
      },
      yAxis: {
        type: 'value',
        axisLabel: {
          color: 'rgba(0,0,0,0.55)'
        },
        splitLine: {
          lineStyle: { color: 'rgba(0,0,0,0.06)' }
        }
      },
      series: [
        {
          name: '销售额',
          type: 'bar',
          data: currentData
            .sort((a, b) => b.value - a.value)
            .slice(0, 15)
            .map((d) => d.value),
          barWidth: 18,
          itemStyle: {
            borderRadius: [6, 6, 0, 0],
            color: '#3b82f6'
          }
        }
      ]
    }
  }

  chartOption.value = toPlainObject(option)
}

function loadData() {
  const mockProvinces: Array<RegionDataItem> = [
    { name: '广东', value: 0 }, { name: '北京', value: 0 }, { name: '上海', value: 0 },
    { name: '浙江', value: 0 }, { name: '江苏', value: 0 }, { name: '山东', value: 0 },
    { name: '河南', value: 0 }, { name: '四川', value: 0 }, { name: '湖北', value: 0 },
    { name: '湖南', value: 0 }, { name: '福建', value: 0 }, { name: '安徽', value: 0 },
    { name: '河北', value: 0 }, { name: '陕西', value: 0 }, { name: '江西', value: 0 },
    { name: '重庆', value: 0 }, { name: '辽宁', value: 0 }, { name: '云南', value: 0 },
    { name: '广西', value: 0 }
  ]

  const merchants = props.topMerchants as Array<any>
  if (merchants.length > 0) {
    for (let i = 0; i < Math.min(merchants.length, mockProvinces.length); i++) {
        const salesStr = String(merchants[i].sales || '0')
        const sales = parseFloat(salesStr)
        mockProvinces[i].value = Math.round(sales * (Math.random() * 0.3 + 0.7))
    }
  } else {
    for (let i = 0; i < mockProvinces.length; i++) {
      mockProvinces[i].value = Math.round(Math.random() * 100000)
    }
  }

  regionData.value = mockProvinces
  buildChartOption()
}

function switchMapType(type: string) {
  mapType.value = type
  buildChartOption()
}

watch([() => props.startDate, () => props.endDate, () => props.topMerchants], () => {
  loadData()
})

onMounted(() => {
  loadData()
})
</script>

<style scoped>
.region-map { width: 100%; }
.map-head { margin-bottom: 8px; }
.map-head-left { display: flex; flex-direction: row; align-items: center; gap: 12px; flex: 1; }
.map-title { font-size: 14px; font-weight: 600; color: #111; }
.map-switch { display: flex; flex-direction: row; gap: 4px; background: #f3f4f6; border-radius: 8px; padding: 2px; }
.map-switch-btn { padding: 6px 12px; border-radius: 6px; font-size: 12px; color: rgba(0,0,0,0.65); background: transparent; cursor: pointer; transition: all 0.2s; white-space: nowrap; }
.map-switch-btn.active { background: #fff; color: #111; font-weight: 500; box-shadow: 0 1px 2px rgba(0,0,0,0.1); }
.chart-box { width: 100%; height: 360px; }
.chart-loading { width: 100%; height: 360px; display: flex; align-items: center; justify-content: center; color: rgba(0,0,0,0.45); font-size: 14px; }
</style>
