/**
 * 地图工具函数模块
 * 提供腾讯地图相关的通用工具函数
 * 
 * 主要功能：
 * - 坐标格式转换
 * - 坐标有效性验证
 * - 地图实例管理辅助函数
 */

/**
 * 验证坐标是否有效
 * @param {number} lng 经度
 * @param {number} lat 纬度
 * @returns {boolean} 坐标是否有效
 */
// export function isValidCoordinate(lng, lat) { // 高德
//   return (
//     lng !== null &&
//     lng !== undefined &&
//     lat !== null &&
//     lat !== undefined &&
//     lng >= -180 &&
//     lng <= 180 &&
//     lat >= -90 &&
//     lat <= 90 &&
//     !isNaN(lng) &&
//     !isNaN(lat)
//   )
// }
export function isValidCoordinate(lat, lng) {
  return (
    lat !== null &&
    lat !== undefined &&
    lng !== null &&
    lng !== undefined &&
    lat >= -90 &&
    lat <= 90 &&
    lng >= -180 &&
    lng <= 180 &&
    !isNaN(lat) &&
    !isNaN(lng)
  )
}

/**
 * 将点对象数组转换为 TMap.LatLng 对象数组
 * @param {Array<{lng: number, lat: number}>} points 点对象数组
 * @returns {Array<TMap.LatLng>} TMap.LatLng 对象数组
 */
export function convertPointsToLatLng(points) {
  if (!points || !Array.isArray(points)) {
    return []
  }
  
  return points
    .filter(p => p && isValidCoordinate(p.lng, p.lat))
    .map(p => new TMap.LatLng(p.lat, p.lng))
}

/**
 * 将经纬度数组转换为 TMap.LatLng 对象数组
 * @param {Array<[number, number]>} lngLatArray 经纬度数组 [[lng, lat], ...]
 * @returns {Array<TMap.LatLng>} TMap.LatLng 对象数组
 */
export function convertLngLatArrayToLatLng(lngLatArray) {
  if (!lngLatArray || !Array.isArray(lngLatArray)) {
    return []
  }
  
  return lngLatArray
    .filter(([lng, lat]) => isValidCoordinate(lng, lat))
    .map(([lng, lat]) => new TMap.LatLng(lat, lng))
}

/**
 * 安全地设置地图中心点
 * @param {Object} map 地图实例
 * @param {number} lng 经度
 * @param {number} lat 纬度
 * @param {number} zoom 缩放级别（可选）
 * @returns {boolean} 是否设置成功
 */
export function safeSetMapCenter(map, lat, lng, zoom) {
  if (!map || !isValidCoordinate(lat, lng)) {
    console.warn('[mapUtils] 无效的地图实例或坐标')
    return false
  }
  
  try {
    const center = new TMap.LatLng(lat, lng)
    map.setCenter(center)
    
    if (typeof zoom === 'number' && zoom >= 3 && zoom <= 20) {
      map.setZoom(zoom)
    }
    
    return true
  } catch (err) {
    console.error('[mapUtils] 设置地图中心失败', err)
    return false
  }
}

/**
 * 安全地获取地图中心点
 * @param {Object} map 地图实例
 * @returns {Object|null} 包含 lng, lat 的对象，失败返回 null
 */
export function safeGetMapCenter(map) {
  if (!map || typeof map.getCenter !== 'function') {
    return null
  }
  
  try {
    const center = map.getCenter()
    return {
	  lat: center.lat,
      lng: center.lng
    }
  } catch (err) {
    console.error('[mapUtils] 获取地图中心失败', err)
    return null
  }
}

/**
 * 格式化坐标显示
 * @param {Object} point 点对象 {lng, lat}
 * @param {number} precision 精度（小数位数），默认 5
 * @returns {string} 格式化后的坐标字符串
 */
export function formatCoordinate(point, precision = 5) {
  if (!point || !isValidCoordinate(point.lng, point.lat)) {
    return '--'
  }
  
  return `${point.lng.toFixed(precision)}, ${point.lat.toFixed(precision)}`
}

/**
 * 计算两点之间的距离（米）
 * 使用 Haversine 公式
 * @param {Object} point1 点1 {lng, lat}
 * @param {Object} point2 点2 {lng, lat}
 * @returns {number} 距离（米）
 */
export function calculateDistance(point1, point2) {
  if (!isValidCoordinate(point1.lng, point1.lat) || 
      !isValidCoordinate(point2.lng, point2.lat)) {
    return 0
  }
  
  const R = 6371000 // 地球半径（米）
  const lat1 = point1.lat * Math.PI / 180
  const lat2 = point2.lat * Math.PI / 180
  const deltaLat = (point2.lat - point1.lat) * Math.PI / 180
  const deltaLng = (point2.lng - point1.lng) * Math.PI / 180
  
  const a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
            Math.cos(lat1) * Math.cos(lat2) *
            Math.sin(deltaLng / 2) * Math.sin(deltaLng / 2)
  
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
  
  return R * c
}

/**
 * 判断点是否在多边形内
 * 使用射线法
 * @param {Object} point 点 {lng, lat}
 * @param {Array<Object>} polygon 多边形顶点数组 [{lng, lat}, ...]
 * @returns {boolean} 点是否在多边形内
 */
export function isPointInPolygon(point, polygon) {
  if (!isValidCoordinate(point.lng, point.lat) || 
      !polygon || polygon.length < 3) {
    return false
  }
  
  let inside = false
  const x = point.lng
  const y = point.lat
  
  for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
    const xi = polygon[i].lng
    const yi = polygon[i].lat
    const xj = polygon[j].lng
    const yj = polygon[j].lat
    
    const intersect = ((yi > y) !== (yj > y)) &&
                     (x < (xj - xi) * (y - yi) / (yj - yi) + xi)
    
    if (intersect) {
      inside = !inside
    }
  }
  
  return inside
}
