<template>
  <!-- 地图容器 -->
  <div id="map" style="height: 800px; width: 100%"></div>
</template>

<script setup lang="ts">
import { onMounted, watch, nextTick, onUnmounted } from 'vue'
import L from 'leaflet'
import 'leaflet/dist/leaflet.css'

// 类型定义
interface PointProp {
  points?: Array<[number, number]>;
}

// 地图配置常量
const MAP_CONFIG = {
  center: [39.9042, 116.4074] as [number, number], // 初始中心坐标（北京）
  zoom: 4,        // 初始缩放级别
  minZoom: 0,     // 最小缩放级别
  maxZoom: 18,     // 最大缩放级别
  zoomControl: true // 缩放控件
}

// 轨迹线样式配置
const POLYLINE_STYLE = {
  color: 'blue',  // 轨迹线颜色
  weight: 3,      // 线宽
  lineJoin: 'round' as const // 连接处样式
}

// 响应式props定义
const props = withDefaults(defineProps<PointProp>(), {
  points: () => []
})

// 地图实例引用
let map: L.Map | null = null
// 轨迹线实例
let polyline: L.Polyline | null = null
// 标记点数组
let markers: L.Marker[] = []

/**
 * 初始化地图实例
 */
function initMap() {
  map = L.map('map', MAP_CONFIG)
  addTileLayer()
}

/**
 * 添加离线瓦片图层
 */
function addTileLayer() {
  L.tileLayer('/tiles/{z}/{y}/{x}.jpg', {
    attribution: 'Offline Map', // 图层属性说明
    tileSize: 256,             // 瓦片尺寸
    noWrap: true               // 禁止重复瓦片
  }).addTo(map!)
}

/**
 * 清除所有轨迹元素
 */
function clearLayers() {
  // 移除轨迹线
  polyline?.remove()
  // 批量移除标记点
  markers.forEach(marker => marker.remove())
  markers = []
}

/**
 * 将坐标转换为Leaflet的LatLng对象
 * @param point 原始坐标数组
 * @returns Leaflet坐标对象
 */
const convertToLatLng = (point: [number, number]) => L.latLng(point[0], point[1])

/**
 * 绘制轨迹线
 * @param latlngs 坐标点数组
 */
function createPolyline(latlngs: L.LatLng[]) {
  polyline = L.polyline(latlngs, POLYLINE_STYLE).addTo(map!)
  // 自动适配视图（按需启用）
  // map?.fitBounds(polyline.getBounds())
}

/**
 * 创建标记点
 * @param latlngs 坐标点数组
 * @returns 标记实例数组
 */
function createMarkers(latlngs: L.LatLng[]) {
  return latlngs.map(latlng => 
    L.marker(latlng).addTo(map!)
  )
}

/**
 * 主绘制函数
 * @param points 原始坐标数组
 */
 function drawTrajectory(points: Array<[number, number]>) {
  if (!map) return
  
  // 始终执行清理（无论是否有新坐标）
  clearLayers()
  
  // 仅在有有效坐标时创建新元素
  if (points?.length > 0) {
    const latlngs = points.map(convertToLatLng)
    createPolyline(latlngs)
    markers = createMarkers(latlngs)
  }
}

// 组件挂载时初始化地图
onMounted(() => {
  nextTick(() => {
    initMap()
  })
})

// 组件卸载时清理地图
onUnmounted(() => {
  map?.remove()
  map = null
})

// 监听points变化自动绘制轨迹
watch(() => props.points, (newPoints) => {
  drawTrajectory(newPoints || [])
}, { deep: true, immediate: true })
</script>