<script setup lang="ts">
import { onMounted, ref, onUnmounted, watch, nextTick } from 'vue'

interface RegionTopPhoneItem {
  rowIndex: number
  colIndex: number
  centerLon: number
  centerLat: number
  phoneModel: string
  os: string
  osVersion: string
  totalTraffic: number
  recordCount: number
}

const mapContainer = ref<HTMLDivElement | null>(null)
const operator = ref<string>('CTCC') // 默认选择中国电信
const networkType = ref<string>('')
const minUploadTraffic = ref<number | null>(null)
const maxUploadTraffic = ref<number | null>(null)
const minDownloadTraffic = ref<number | null>(null)
const maxDownloadTraffic = ref<number | null>(null)
const startDate = ref<string>('')
const endDate = ref<string>('')
const minTrafficThreshold = ref<number>(1000) // 预设流量阈值（KB）
const gridRows = ref<number>(20) // 网格行数
const gridCols = ref<number>(15) // 网格列数
const loading = ref<boolean>(false)
const dataLoaded = ref<boolean>(false)
const dataList = ref<RegionTopPhoneItem[]>([])

let map: any = null
let overlays: any[] = []
let updateMarkersRetryCount = 0 // 重试计数器
const MAX_UPDATE_RETRIES = 10 // 最大重试次数
// 定义百度地图类型别名，简化访问
const BMap = (window as any).BMap

// 初始化地图（参考需求7的实现方式）
const initMap = async () => {
  await nextTick()

  // 轮询检查百度地图API是否已加载
  if (!(window as any).BMap) {
    console.warn('百度地图API未加载，200ms后重试...')
    setTimeout(initMap, 200)
    return
  }
  else {
    console.log('百度地图API已加载')
  }

  if (!mapContainer.value) {
    console.warn('地图容器未找到，等待100ms后重试')
    setTimeout(initMap, 100)
    return
  }

  console.log('地图容器已找到，开始创建地图实例')

  try {
    const BMap = (window as any).BMap
    console.log('开始创建地图实例，容器:', mapContainer.value)
    
    // 如果之前有地图实例，先清理
    if (map) {
      console.log('检测到已有地图实例，先清理')
      try {
        map.clearOverlays()
      } catch (e) {
        console.warn('清理旧地图实例失败:', e)
      }
    }
    
    map = new BMap.Map(mapContainer.value)
    console.log('地图实例创建成功')
    
    map.centerAndZoom(new BMap.Point(105.8951, 36.5667), 5) // 默认中国中心
    console.log('地图中心点设置完成')
    
    map.enableScrollWheelZoom(true)
    map.enableDragging(true)
    console.log('地图交互功能启用完成')
    
    map.addControl(new BMap.MapTypeControl({ mapTypes: [BMap.MapTypeId?.NORMAL || 1, BMap.MapTypeId?.SATELLITE || 2] }))
    map.addControl(new BMap.NavigationControl())
    map.addControl(new BMap.ScaleControl())
    console.log('地图控件添加完成')

    // 监听地图移动和缩放事件，更新标记（增加防抖和容错）
    let updateTimer: any = null
    const debouncedUpdateMarkers = () => {
      if (updateTimer) clearTimeout(updateTimer)
      updateTimer = setTimeout(() => {
        updateMarkers()
      }, 300)
    }
    map.addEventListener('moveend', debouncedUpdateMarkers)
    map.addEventListener('zoomend', debouncedUpdateMarkers)

    console.log('地图初始化完成')

    // 地图初始化后立即获取数据
    fetchData()
  } catch (error) {
    console.error('地图初始化过程中出错:', error)
    // 即使出错也尝试获取数据
    if (map) {
      console.log('地图实例存在，尝试获取数据')
      fetchData()
    } else {
      console.error('地图实例创建失败，无法获取数据')
      loading.value = false
      dataLoaded.value = true
    }
  }
}

// 创建手机logo图标（使用文字作为占位符）
const createPhoneIcon = (phoneModel: string, traffic: number): string => {
  // 使用手机型号的版本号部分（如android4.1.2中的4.1.2）
  let displayText = phoneModel
  if (phoneModel.toLowerCase().includes('android')) {
    // 提取版本号部分
    const versionMatch = phoneModel.match(/android(\d+\.\d+\.\d+|\d+\.\d+)/i)
    if (versionMatch) {
      displayText = versionMatch[1] // 只显示版本号，如4.1.2
    } else {
      // 如果没有匹配到版本号，使用前几个字符
      displayText = phoneModel.length > 4 ? phoneModel.substring(0, 4) : phoneModel
    }
  } else {
    displayText = phoneModel.length > 4 ? phoneModel.substring(0, 4) : phoneModel
  }
  
  const size = 40
  const fontSize = 11
  
  // 修复XML字符串中的换行问题，避免base64编码错误
  const svgContent = `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
    <rect width="${size}" height="${size}" rx="8" fill="#4b9cff" opacity="0.9"/>
    <text x="50%" y="50%" text-anchor="middle" dominant-baseline="middle" 
          font-size="${fontSize}" font-weight="bold" fill="white">${displayText}</text>
    <text x="50%" y="75%" text-anchor="middle" dominant-baseline="middle" 
          font-size="8" fill="white" opacity="0.8">${(traffic / 1000).toFixed(1)}K</text>
  </svg>`
  
  return `data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(svgContent)))}`
}

// 更新地图标记（增加容错和延迟处理）
const updateMarkers = () => {
  if (!map || !dataLoaded.value || dataList.value.length === 0) {
    // 如果没有数据，只清除覆盖物
    overlays.forEach(overlay => {
      try {
        map?.removeOverlay(overlay)
      } catch (error) {
        console.warn('移除覆盖物失败:', error)
      }
    })
    overlays = []
    return
  }
  
  // 清除旧的覆盖物
  overlays.forEach(overlay => {
    try {
      map.removeOverlay(overlay)
    } catch (error) {
      console.warn('移除覆盖物失败:', error)
    }
  })
  overlays = []
  
  // 获取地图可视区域 - 增加容错处理
  let bounds: any = null
  try {
    bounds = map.getBounds()
    // 等待地图边界稳定（解决刚初始化时边界不完整问题）
    if (!bounds) {
      if (updateMarkersRetryCount < MAX_UPDATE_RETRIES) {
        updateMarkersRetryCount++
        console.log(`地图边界未获取到，${updateMarkersRetryCount}/${MAX_UPDATE_RETRIES}次重试`)
        setTimeout(() => updateMarkers(), 500)
      } else {
        console.warn('地图边界获取失败，已达到最大重试次数，停止重试')
        updateMarkersRetryCount = 0
      }
      return
    }
  } catch (error) {
    if (updateMarkersRetryCount < MAX_UPDATE_RETRIES) {
      updateMarkersRetryCount++
      console.warn(`获取地图边界失败，${updateMarkersRetryCount}/${MAX_UPDATE_RETRIES}次重试:`, error)
      setTimeout(() => updateMarkers(), 500)
    } else {
      console.warn('获取地图边界失败，已达到最大重试次数，停止重试')
      updateMarkersRetryCount = 0
    }
    return
  }
  
  const sw = bounds.getSouthWest()
  const ne = bounds.getNorthEast()
  
  if (!sw || !ne || !sw.lat || !sw.lng || !ne.lat || !ne.lng) {
    if (updateMarkersRetryCount < MAX_UPDATE_RETRIES) {
      updateMarkersRetryCount++
      console.warn(`地图边界数据不完整，${updateMarkersRetryCount}/${MAX_UPDATE_RETRIES}次重试更新标记`)
      setTimeout(() => updateMarkers(), 500)
    } else {
      console.warn('地图边界数据不完整，已达到最大重试次数，停止重试')
      updateMarkersRetryCount = 0
    }
    return
  }
  
  // 重置重试计数器（成功获取边界后）
  updateMarkersRetryCount = 0
  
  // 过滤出在可视区域内且流量超过阈值的数据
  let visibleData = dataList.value.filter(item => {
    // 检查是否在可视区域内
    const inBounds = item.centerLat >= sw.lat && item.centerLat <= ne.lat &&
                     item.centerLon >= sw.lng && item.centerLon <= ne.lng
    // 检查流量是否超过阈值
    const exceedsThreshold = item.totalTraffic >= minTrafficThreshold.value
    return inBounds && exceedsThreshold
  })
  
  // 再次限制最多显示100条，确保性能
  if (visibleData.length > 100) {
    visibleData = visibleData.slice(0, 100)
    console.log(`可视区域内数据过多，限制显示前100条`)
  }
  
  console.log(`准备显示 ${visibleData.length} 个标记点`)
  
  // 在地图上显示手机logo（使用类型断言避免错误）
  const BMap = (window as any).BMap
  visibleData.forEach(item => {
    try {
      const point = new BMap.Point(item.centerLon, item.centerLat)
      
      const icon = new BMap.Icon(
        createPhoneIcon(item.phoneModel, item.totalTraffic),
        new BMap.Size(40, 40),
        { anchor: new BMap.Size(20, 20) }
      )
      
      const marker = new BMap.Marker(point, { icon })
      
      // 信息窗口
      const infoWindow = new BMap.InfoWindow(`
        <div style="padding:8px">
          <p><strong>手机型号:</strong> ${item.phoneModel}</p>
          <p><strong>操作系统:</strong> ${item.os}</p>
          <p><strong>系统版本:</strong> ${item.osVersion || '未指定'}</p>
          <p><strong>总流量:</strong> ${(item.totalTraffic / 1024).toFixed(2)} MB</p>
          <p><strong>记录数:</strong> ${item.recordCount}</p>
          <p><strong>区域:</strong> 第${item.rowIndex + 1}行, 第${item.colIndex + 1}列</p>
          <p><strong>坐标:</strong> ${item.centerLat.toFixed(6)}, ${item.centerLon.toFixed(6)}</p>
        </div>
      `, { width: 200 })
      
      marker.addEventListener('click', () => map.openInfoWindow(infoWindow, point))
      map.addOverlay(marker)
      overlays.push(marker)
    } catch (error) {
      console.warn(`创建标记失败 (${item.phoneModel}):`, error)
    }
  })
}

// 获取数据
const fetchData = async () => {
  console.log('fetchData 函数被调用')
  loading.value = true
  dataLoaded.value = false
  
  // 清除旧数据
  dataList.value = []
  overlays.forEach(overlay => {
    try {
      map?.removeOverlay(overlay)
    } catch (error) {
      console.warn('移除覆盖物失败:', error)
    }
  })
  overlays = []
  
  try {
    const body: any = {}
    
    // 运营商筛选
    if (operator.value && operator.value !== 'ALL') {
      body.operator = operator.value
    }
    
    // 网络制式筛选
    if (networkType.value) {
      body.networkType = networkType.value
    }
    
    // 流量范围（手机流量）
    if (minUploadTraffic.value !== null) {
      body.minUploadTraffic = minUploadTraffic.value
    }
    if (maxUploadTraffic.value !== null) {
      body.maxUploadTraffic = maxUploadTraffic.value
    }
    if (minDownloadTraffic.value !== null) {
      body.minDownloadTraffic = minDownloadTraffic.value
    }
    if (maxDownloadTraffic.value !== null) {
      body.maxDownloadTraffic = maxDownloadTraffic.value
    }
    
    // 日期范围
    if (startDate.value) {
      body.startDate = startDate.value
    }
    if (endDate.value) {
      body.endDate = endDate.value
    }
    
    // 网格大小
    body.gridRows = gridRows.value
    body.gridCols = gridCols.value
    
    console.log('准备发送请求，请求体:', body)
    console.log('请求URL: http://localhost:8081/appTraffic/phoneRegionTop')
    
    const response = await fetch('http://localhost:8081/appTraffic/phoneRegionTop', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body)
    })
    
    console.log('收到响应，状态码:', response.status)
    
    if (!response.ok) {
      const errorText = await response.text()
      throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`)
    }
    
    const data = await response.json() as RegionTopPhoneItem[]
    console.log('收到数据:', data.length, '条')
    
    // 限制只显示前100条数据，避免数据量太大导致地图加载缓慢
    dataList.value = data.slice(0, 100)
    console.log('限制显示:', dataList.value.length, '条')
    
    // 地图已初始化：更新标记
    if (map) {
      await nextTick()
      // 重置重试计数器
      updateMarkersRetryCount = 0
      // 增加延迟，确保地图完全渲染后再更新标记
      setTimeout(() => {
        updateMarkers()
      }, 500) // 延迟500ms，确保地图完全加载
    } else {
      console.warn('地图未初始化，等待地图初始化后再更新标记')
    }
  } catch (error) {
    console.error('获取数据失败:', error)
    alert(`获取数据失败: ${error instanceof Error ? error.message : String(error)}`)
    dataList.value = []
  } finally {
    loading.value = false
    dataLoaded.value = true
    console.log('数据加载完成，loading状态:', loading.value)
  }
}

// 监听筛选条件变化（增加防抖，避免频繁请求）
const fetchDataDebounced = () => {
  let timer: any = null
  return () => {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      if (map && dataLoaded.value) fetchData()
    }, 500)
  }
}
const debouncedFetch = fetchDataDebounced()
watch([operator, networkType, minUploadTraffic, maxUploadTraffic, minDownloadTraffic, maxDownloadTraffic, startDate, endDate, minTrafficThreshold, gridRows, gridCols], debouncedFetch)

onMounted(() => {
  console.log('组件已挂载，开始初始化地图')
  initMap()
})

onUnmounted(() => {
  console.log('Req26组件卸载，清理地图资源')
  overlays.forEach(overlay => {
    try {
      map?.removeOverlay(overlay)
    } catch (error) {
      console.warn('移除覆盖物失败:', error)
    }
  })
  // 清理地图实例
  if (map) {
    try {
      map.clearOverlays()
    } catch (error) {
      console.warn('清理地图覆盖物失败:', error)
    }
  }
  map = null
  overlays = []
  // 重置状态
  loading.value = false
  dataLoaded.value = false
  dataList.value = []
})
</script>

<template>
  <div class="page">
    <!-- 加载遮罩 -->
    <div v-if="loading || !dataLoaded" class="loading-overlay">
      <div class="loading-spinner">
        <div class="spinner"></div>
        <p class="loading-text">加载数据中...</p>
      </div>
    </div>

    <h2>业务需求26：热门手机-热门手机分布图</h2>

    <div class="filter-bar">
      <div class="filter-item">
        <label for="operator">运营商:</label>
        <select id="operator" v-model="operator" class="select-input" :disabled="loading">
          <option value="ALL">全部</option>
          <option value="CMCC">CMCC（中国移动）</option>
          <option value="CUCC">CUCC（中国联通）</option>
          <option value="CTCC">CTCC（中国电信）</option>
        </select>
      </div>
      <div class="filter-item">
        <label for="networkType">网络制式:</label>
        <select id="networkType" v-model="networkType" class="select-input" :disabled="loading">
          <option value="">全部</option>
          <option value="Android">Android</option>
          <option value="iOS">iOS</option>
        </select>
      </div>
      <div class="filter-item">
        <label for="startDate">起始日期:</label>
        <input
          id="startDate"
          type="date"
          v-model="startDate"
          class="date-input"
          :disabled="loading"
        />
      </div>
      <div class="filter-item">
        <label for="endDate">结束日期:</label>
        <input
          id="endDate"
          type="date"
          v-model="endDate"
          class="date-input"
          :disabled="loading"
        />
      </div>
      <div class="filter-item">
        <label for="minTrafficThreshold">流量阈值(KB):</label>
        <input
          id="minTrafficThreshold"
          type="number"
          v-model.number="minTrafficThreshold"
          class="number-input"
          min="0"
          :disabled="loading"
        />
      </div>
      <button @click="fetchData" class="refresh-btn" :disabled="loading">
        {{ loading ? '加载中...' : '查询' }}
      </button>
    </div>

    <div class="filter-bar-secondary">
      <div class="filter-item">
        <label for="minUploadTraffic">最小上传流量(KB):</label>
        <input
          id="minUploadTraffic"
          type="number"
          v-model.number="minUploadTraffic"
          class="number-input"
          min="0"
          step="0.1"
          :disabled="loading"
        />
      </div>
      <div class="filter-item">
        <label for="maxUploadTraffic">最大上传流量(KB):</label>
        <input
          id="maxUploadTraffic"
          type="number"
          v-model.number="maxUploadTraffic"
          class="number-input"
          min="0"
          step="0.1"
          :disabled="loading"
        />
      </div>
      <div class="filter-item">
        <label for="minDownloadTraffic">最小下载流量(KB):</label>
        <input
          id="minDownloadTraffic"
          type="number"
          v-model.number="minDownloadTraffic"
          class="number-input"
          min="0"
          step="0.1"
          :disabled="loading"
        />
      </div>
      <div class="filter-item">
        <label for="maxDownloadTraffic">最大下载流量(KB):</label>
        <input
          id="maxDownloadTraffic"
          type="number"
          v-model.number="maxDownloadTraffic"
          class="number-input"
          min="0"
          step="0.1"
          :disabled="loading"
        />
      </div>
      <div class="filter-item">
        <label for="gridRows">网格行数:</label>
        <input
          id="gridRows"
          type="number"
          v-model.number="gridRows"
          class="number-input"
          min="1"
          max="50"
          :disabled="loading"
        />
      </div>
      <div class="filter-item">
        <label for="gridCols">网格列数:</label>
        <input
          id="gridCols"
          type="number"
          v-model.number="gridCols"
          class="number-input"
          min="1"
          max="50"
          :disabled="loading"
        />
      </div>
    </div>

    <div class="info-bar">
      <p>地图将可视区域分为{{ gridRows }}×{{ gridCols }}={{ gridRows * gridCols }}个矩形区域，显示每个区域流量Top1的热门手机（流量需超过阈值{{ minTrafficThreshold }}KB）</p>
    </div>

    <div class="map-container" ref="mapContainer"></div>
  </div>
</template>

<style scoped>
.page {
  padding: 16px;
  height: 100%;
  display: flex;
  flex-direction: column;
  position: relative;
}

h2 {
  margin: 0 0 16px 0;
  font-size: 20px;
  font-weight: 600;
}

.filter-bar,
.filter-bar-secondary {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 12px;
  padding: 12px;
  background: #f9fafb;
  border-radius: 6px;
  flex-wrap: wrap;
}

.filter-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.select-input,
.text-input,
.date-input,
.number-input {
  padding: 6px 12px;
  border: 1px solid #d1d5db;
  border-radius: 4px;
  font-size: 14px;
}

.number-input {
  width: 120px;
}

.text-input {
  width: 150px;
}

.refresh-btn {
  padding: 6px 16px;
  background: #3b82f6;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
}
.refresh-btn:hover:not(:disabled) {
  background: #2563eb;
}
.refresh-btn:disabled {
  background: #9ca3af;
  cursor: not-allowed;
}

.info-bar {
  margin-bottom: 12px;
  padding: 8px 12px;
  background: #e0f2fe;
  border-radius: 4px;
  font-size: 13px;
  color: #0369a1;
}

.map-container {
  width: 100%;
  height: calc(100vh - 350px);
  min-height: 500px;
  border: 1px solid #e5e7eb;
  border-radius: 4px;
  flex: 1;
}

.loading-overlay {
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
}
.loading-spinner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}
.spinner {
  width: 48px;
  height: 48px;
  border: 4px solid #e5e7eb;
  border-top-color: #3b82f6;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
.loading-text {
  font-size: 16px;
  color: #374151;
  margin: 0;
}
</style>
