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

// 信号强度数据项接口
interface SignalStrengthItem {
  id?: number
  userLon?: string
  userLat?: string
  rssi?: number // 确保 rssi 是 number
  [key: string]: any // 允许其他字段
}

const mapContainer = ref<HTMLDivElement | null>(null)
const networkType = ref<string>('ALL')
const networkName = ref<string>('ALL')
const startDate = ref<string>('')
const endDate = ref<string>('')
const loading = ref<boolean>(false)
const dataLoaded = ref<boolean>(false)

let map: any = null
let heatmapOverlay: any = null

// 将后端返回的数据转换为热力图库需要的格式
const transformDataForHeatmap = (data: SignalStrengthItem[]) => {
  return data
    .filter(item => {
      const lat = parseFloat(String(item.userLat))
      const lon = parseFloat(String(item.userLon))
      // 过滤掉无效坐标和无效信号强度
      return !isNaN(lat) && !isNaN(lon) && lat !== 0 && lon !== 0 && item.rssi != null
    })
    .map(item => {
      // 热力图权重需要是正数，我们将RSSI（-120到0）映射到一个正数范围（例如1到100）
      // 信号越强（越接近0），权重越高
      const rssi = item.rssi ?? -120;
      const count = Math.max(1, 100 - (Math.abs(rssi) - 20));
      return {
        lng: parseFloat(String(item.userLon)),
        lat: parseFloat(String(item.userLat)),
        count: count
      }
    })
}

// 渲染热力图
const renderHeatmap = (points: any[]) => {
  if (!map) return

  // 如果已存在热力图层，先移除
  if (heatmapOverlay) {
    map.removeOverlay(heatmapOverlay)
  }

  if (points.length === 0) {
    return; // 没有数据点，不创建图层
  }

  // 创建热力图实例
  heatmapOverlay = new window.BMapLib.HeatmapOverlay({ radius: 20, opacity: 0.8 })
  map.addOverlay(heatmapOverlay)

  // 设置热力图数据
  heatmapOverlay.setDataSet({
    data: points,
    max: 100 // 设置权重的最大值
  });

  // 自动调整地图视野以包含所有点
  const viewport = map.getViewport(points.map((p: any) => new window.BMap.Point(p.lng, p.lat)));
  map.centerAndZoom(viewport.center, viewport.zoom);
}

// 获取数据
const fetchData = async () => {
  loading.value = true
  dataLoaded.value = false

  try {
    const params = new URLSearchParams()
    params.append('networkType', networkType.value)
    params.append('networkName', networkName.value)
    if (startDate.value) params.append('startTime', new Date(startDate.value).getTime().toString())
    if (endDate.value) {
        const end = new Date(endDate.value);
        end.setHours(23, 59, 59, 999);
        params.append('endTime', end.getTime().toString());
    }

    const response = await fetch(`http://localhost:8081/api/signal/heatmap?${params.toString()}`)
    if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`)

    const responseData = await response.json()
    if (responseData.code !== 200) throw new Error(responseData.message || '获取数据失败')

    const heatmapPoints = transformDataForHeatmap(responseData.data || [])
    
    if (map) {
        renderHeatmap(heatmapPoints)
    }

  } catch (error) {
    console.error('获取数据失败:', error)
    if(map) renderHeatmap([]); // 清空热力图
  } finally {
    loading.value = false
    dataLoaded.value = true
  }
}

// 初始化地图
const initMap = async () => {
  await nextTick()

  // 轮询检查百度地图API和热力图库是否都已加载
  if (!window.BMap || !window.BMapLib?.HeatmapOverlay) {
    console.warn('百度地图API或热力图库未加载，200ms后重试...')
    setTimeout(initMap, 200)
    return
  }

  if (!mapContainer.value) {
    console.warn('地图容器未找到')
    return
  }

  map = new window.BMap.Map(mapContainer.value)
  map.centerAndZoom(new window.BMap.Point(105.8951, 36.5667), 5) // 默认中国中心
  map.enableScrollWheelZoom(true)
  map.addControl(new window.BMap.MapTypeControl({ mapTypes: [window.BMap.MapTypeId.NORMAL, window.BMap.MapTypeId.SATELLITE] }))
  map.addControl(new window.BMap.NavigationControl())

  // 地图初始化后立即获取数据
  fetchData()
}

// 监听筛选条件变化
watch([networkType, networkName, startDate, endDate], () => {
  if (map && dataLoaded.value) {
    fetchData()
  }
})

onMounted(() => {
  initMap()
})

onUnmounted(() => {
  if (heatmapOverlay && map) {
    map.removeOverlay(heatmapOverlay)
  }
  map = null
})
</script>

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

    <h2>业务需求7：信号覆盖-信号强度分布（热力图）</h2>

    <div class="filter-bar">
      <div class="filter-item">
        <label for="networkType">运营商:</label>
        <select id="networkType" v-model="networkType" class="select-input" :disabled="loading">
          <option value="ALL">ALL</option>
          <option value="CMCC">中国移动</option>
          <option value="CUCC">中国联通</option>
          <option value="CTCC">中国电信</option>
        </select>
      </div>
      <div class="filter-item">
        <label for="networkName">网络类型:</label>
        <select id="networkName" v-model="networkName" class="select-input" :disabled="loading">
          <option value="ALL">ALL</option>
          <option value="2G">2G</option>
          <option value="3G">3G</option>
          <option value="4G">4G</option>
          <option value="5G">5G</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>
      <button @click="fetchData" class="refresh-btn" :disabled="loading">
        {{ loading ? '加载中...' : '刷新' }}
      </button>
    </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 {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 16px;
  padding: 12px;
  background: #f9fafb;
  border-radius: 6px;
  flex-wrap: wrap;
}

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

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

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

.map-container {
  width: 100%;
  height: calc(100vh - 220px);
  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>