/**
 * 判断是否在中国境外
 */
function outOfChina(lng, lat) {
  return !(lng >= 72.004 && lng <= 137.8347 && lat >= 0.8293 && lat <= 55.8271)
}

/**
 * 辅助函数：纬度转换
 */
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 * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0) / 3.0
  ret += ((20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin((y / 3.0) * Math.PI)) * 2.0) / 3.0
  ret +=
    ((160.0 * Math.sin((y / 12.0) * Math.PI) + 320 * Math.sin((y * Math.PI) / 30.0)) * 2.0) / 3.0
  return ret
}

/**
 * 辅助函数：经度转换
 */
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 * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0) / 3.0
  ret += ((20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin((x / 3.0) * Math.PI)) * 2.0) / 3.0
  ret +=
    ((150.0 * Math.sin((x / 12.0) * Math.PI) + 300.0 * Math.sin((x / 30.0) * Math.PI)) * 2.0) / 3.0
  return ret
}

/**
 * GCJ-02 (高德/腾讯坐标系) 转 WGS-84 (GPS原始坐标系)
 * @param {number} lng GCJ-02经度
 * @param {number} lat GCJ-02纬度
 * @returns {number[]} [WGS-84经度, WGS-84纬度]
 */
export function gcj02ToWgs84(lng, lat) {
  // 判断是否在中国境内（简化版，实际需更完整判断）
  if (outOfChina(lng, lat)) {
    return [lng, lat] // 境外坐标不转换
  }

  let dlat = _transformLat(lng - 105.0, lat - 35.0)
  let dlng = _transformLng(lng - 105.0, lat - 35.0)

  const radlat = (lat / 180.0) * Math.PI
  let magic = Math.sin(radlat)
  magic = 1 - 0.00669342162296594323 * magic * magic
  const sqrtmagic = Math.sqrt(magic)

  dlat =
    (dlat * 180.0) / (((6378245.0 * (1 - 0.00669342162296594323)) / (magic * sqrtmagic)) * Math.PI)
  dlng = (dlng * 180.0) / ((6378245.0 / sqrtmagic) * Math.cos(radlat) * Math.PI)

  // 初始转换结果（粗略值）
  let wgsLat = lat - dlat
  let wgsLng = lng - dlng

  return [wgsLng, wgsLat]
}

/**
 * WGS-84 转 GCJ-02（用于迭代优化）
 */
export function wgs84ToGcj02(lng, lat) {
  if (outOfChina(lng, lat)) {
    return [lng, lat]
  }
  let dlat = _transformLat(lng - 105.0, lat - 35.0)
  let dlng = _transformLng(lng - 105.0, lat - 35.0)
  const radlat = (lat / 180.0) * Math.PI
  let magic = Math.sin(radlat)
  magic = 1 - 0.00669342162296594323 * magic * magic
  const sqrtmagic = Math.sqrt(magic)
  dlat =
    (dlat * 180.0) / (((6378245.0 * (1 - 0.00669342162296594323)) / (magic * sqrtmagic)) * Math.PI)
  dlng = (dlng * 180.0) / ((6378245.0 / sqrtmagic) * Math.cos(radlat) * Math.PI)
  return [lng + dlng, lat + dlat]
}
