<template>
  <view class="user-map-card">
    <view class="card-header">
      <text class="title">用户地域分布</text>
    </view>
    
    <view class="card-content">
      <!-- 左侧地图 -->
      <view class="map-section">
        <EChartsView :option="mapOption" class="map-chart" />
      </view>
      
      <!-- 右侧表格 -->
      <view class="table-section">
        <view class="table-header">
          <text class="th province">TOP省份</text>
          <text class="th count">累积用户数</text>
          <text class="th count">新增用户数</text>
          <text class="th count">访客数</text>
          <text class="th amount">支付金额</text>
        </view>
        <scroll-view class="table-body" scroll-y="true">
          <view v-for="(item, index) in tableData" :key="index" class="table-row">
            <text class="td province">{{ item.name }}</text>
            <text class="td count">{{ item.total }}</text>
            <text class="td count">{{ item.newUsers }}</text>
            <text class="td count">{{ item.visitors }}</text>
            <text class="td amount">{{ item.amount }}</text>
          </view>
        </scroll-view>
      </view>
    </view>
  </view>
</template>

<script lang="uts">
import EChartsView from '@/uni_modules/charts/EChartsView.vue'

type RegionData = {
  name: string
  total: number
  newUsers: number
  visitors: number
  amount: number
}

export default {
  components: {
    EChartsView
  },
  data() {
    return {
      mapOption: {} as any,
      tableData: [
        { name: '未知', total: 55398, newUsers: 463, visitors: 1112, amount: 287460.5 },
        { name: '广东', total: 2697, newUsers: 0, visitors: 9, amount: 0 },
        { name: '北京', total: 1058, newUsers: 0, visitors: 4, amount: 0 },
        { name: '河南', total: 823, newUsers: 0, visitors: 3, amount: 0 },
        { name: '福建', total: 799, newUsers: 0, visitors: 4, amount: 0 },
        { name: '山东', total: 792, newUsers: 0, visitors: 0, amount: 0 },
        { name: '浙江', total: 780, newUsers: 0, visitors: 1, amount: 0 },
        { name: '江苏', total: 779, newUsers: 0, visitors: 4, amount: 0 },
        { name: '四川', total: 768, newUsers: 0, visitors: 3, amount: 0 },
        { name: '湖南', total: 520, newUsers: 0, visitors: 2, amount: 0 },
        { name: '湖北', total: 480, newUsers: 0, visitors: 1, amount: 0 }
      ] as Array<RegionData>
    }
  },
  mounted() {
    setTimeout(() => {
      this.initMap()
    }, 200)
  },
  methods: {
    initMap() {
      // 提取地图数据
      const data = this.tableData.filter(it => it.name !== '未知').map(it => ({
        name: it.name,
        value: it.total
      }))

      const option = {
        tooltip: {
          trigger: 'item',
          formatter: '{b}<br/>累积用户: {c}'
        },
        visualMap: {
          min: 0,
          max: 3000,
          left: 'left',
          top: 'bottom',
          text: ['高', '低'],
          inRange: {
            color: ['#fff7ed', '#fbbf24', '#f59e0b', '#d97706']
          },
          calculable: true
        },
        geo: {
          map: 'china',
          roam: false,
          zoom: 1.2,
          emphasis: {
            itemStyle: {
              areaColor: '#f97316'
            },
            label: {
              show: true
            }
          },
          itemStyle: {
            areaColor: '#f8fafc',
            borderColor: '#e2e8f0'
          }
        },
        series: [
          {
            name: '用户数',
            type: 'map',
            geoIndex: 0,
            data: data
          }
        ]
      }
      this.mapOption = this.toPlainObject(option)
    },
    toPlainObject(obj: any): any {
      if (obj == null) return null
      if (typeof obj !== 'object') return obj
      if (Array.isArray(obj)) {
        return obj.map((item) => this.toPlainObject(item))
      }
      const plain: any = {}
      for (const key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
          const value = obj[key]
          if (typeof value === 'function' || key.startsWith('_') || key === 'toJSON') {
            continue
          }
          if (value != null && typeof value === 'object' && !Array.isArray(value)) {
            let isSimple = true
            for (const k in value) {
              if (typeof value[k] === 'object' && value[k] !== null) {
                isSimple = false
                break
              }
            }
            plain[key] = isSimple ? { ...value } : this.toPlainObject(value)
          } else {
            plain[key] = value
          }
        }
      }
      return plain
    }
  }
}
</script>

<style scoped lang="scss">
.user-map-card {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  /* margin-bottom 移除，由父级 Grid gap 控制或统一添加 */
  display: flex;
  flex-direction: column;
  height: 100%; /* 让卡片自身也撑满容器 */
}

.card-header {
  margin-bottom: 20px;
}

.title {
  font-size: 16px;
  font-weight: bold;
  color: #333;
}

.card-content {
  display: flex;
  flex-direction: row;
  flex: 1; /* 让内容区在容器高时自适应 */
  min-height: 450px; /* 最小基础高度 */
}

.map-section {
  flex: 4;
  height: 100%;
}

.map-chart {
  width: 100%;
  height: 100%;
}

.table-section {
  flex: 6;
  display: flex;
  flex-direction: column;
  padding-left: 20px;
}

.table-header {
  display: flex;
  flex-direction: row;
  background: #f8faff;
  padding: 12px 0;
  border-bottom: 1px solid #eef2f7;
}

.table-body {
  flex: 1;
  height: 0;
}

.table-row {
  display: flex;
  flex-direction: row;
  padding: 12px 0;
  border-bottom: 1px solid #f0f2f5;
  
  &:hover {
    background: #f9fbff;
  }
}

.th, .td {
  font-size: 13px;
  color: #666;
  text-align: center;
}

.province { flex: 1.5; text-align: left; padding-left: 15px; }
.count { flex: 1.5; }
.amount { flex: 2; }

.th {
  color: #333;
  font-weight: 500;
}

.td {
  color: #666;
}
</style>
