/**
 * 坐标转换工具类
 * 将高德地图坐标（GCJ-02）转换为WGS84坐标
 */

// 坐标转换常量
const PI = Math.PI
const A = 6378245.0 // WGS84椭球长半轴
const EE = 0.00669342162296594323 // WGS84椭球扁率

/**
 * 判断坐标是否在中国境内
 * @param {number} lng 经度
 * @param {number} lat 纬度
 * @returns {boolean} 是否在中国境内
 */
function isInChina(lng, lat) {
  return lng >= 73.66 && lng <= 135.05 && lat >= 3.86 && lat <= 53.55
}

/**
 * 将GCJ-02坐标转换为WGS84坐标
 * @param {number} gcjLng GCJ-02经度
 * @param {number} gcjLat GCJ-02纬度
 * @returns {Object} WGS84坐标 {lng, lat}
 */
function gcj02ToWgs84(gcjLng, gcjLat) {
  if (!isInChina(gcjLng, gcjLat)) {
    return {
      lng: gcjLng,
      lat: gcjLat
    }
  }

  let dLat = transformLat(gcjLng - 105.0, gcjLat - 35.0)
  let dLng = transformLng(gcjLng - 105.0, gcjLat - 35.0)

  const radLat = gcjLat / 180.0 * PI
  let magic = Math.sin(radLat)
  magic = 1 - EE * magic * magic
  const sqrtMagic = Math.sqrt(magic)

  dLat = (dLat * 180.0) / ((A * (1 - EE)) / (magic * sqrtMagic) * PI)
  dLng = (dLng * 180.0) / (A / sqrtMagic * Math.cos(radLat) * PI)

  const wgsLat = gcjLat - dLat
  const wgsLng = gcjLng - dLng

  return {
    lng: wgsLng,
    lat: wgsLat
  }
}

/**
 * 纬度转换函数
 * @param {number} x
 * @param {number} y
 * @returns {number}
 */
function transformLat(x, y) {
  let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x))
  ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0
  ret += (20.0 * Math.sin(y * PI) + 40.0 * Math.sin(y / 3.0 * PI)) * 2.0 / 3.0
  ret += (160.0 * Math.sin(y / 12.0 * PI) + 320 * Math.sin(y * PI / 30.0)) * 2.0 / 3.0
  return ret
}

/**
 * 经度转换函数
 * @param {number} x
 * @param {number} y
 * @returns {number}
 */
function transformLng(x, y) {
  let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x))
  ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0
  ret += (20.0 * Math.sin(x * PI) + 40.0 * Math.sin(x / 3.0 * PI)) * 2.0 / 3.0
  ret += (150.0 * Math.sin(x / 12.0 * PI) + 300.0 * Math.sin(x / 30.0 * PI)) * 2.0 / 3.0
  return ret
}

/**
 * 转换坐标点数组
 * @param {Array} points 坐标点数组，每个点包含lng和lat属性
 * @returns {Array} 转换后的坐标点数组
 */
function convertPointsToWgs84(points) {
  if (!Array.isArray(points)) {
    return []
  }

  return points.map(point => {
    if (!point || typeof point.lng !== 'number' || typeof point.lat !== 'number') {
      return point // 如果点数据不完整，返回原数据
    }

    const converted = gcj02ToWgs84(point.lng, point.lat)
    return {
      ...point,
      lng: converted.lng,
      lat: converted.lat
    }
  })
}

/**
 * 转换单个坐标点
 * @param {Object} point 坐标点对象 {lng, lat, ...}
 * @returns {Object} 转换后的坐标点对象
 */
function convertPointToWgs84(point) {
  if (!point || typeof point.lng !== 'number' || typeof point.lat !== 'number') {
    return point
  }

  const converted = gcj02ToWgs84(point.lng, point.lat)
  return {
    ...point,
    lng: converted.lng,
    lat: converted.lat
  }
}

export default {
  gcj02ToWgs84,
  convertPointsToWgs84,
  convertPointToWgs84,
  isInChina
}
