import Taro from '@tarojs/taro';
import { getLocationByIP } from '../../utils/Robotaxi-public-method';

/** 定位来源：gps 精确定位 / ip 粗定位 / fallback 兜底坐标。 */
export type UserLocationSource = 'gps' | 'ip' | 'fallback';

/** 统一的用户定位结果。 */
export interface UserLocation {
  latitude: number;
  longitude: number;
  /** 本次坐标的来源，便于上层按精度差异做不同处理。 */
  source: UserLocationSource;
  /** 仅 ip 来源可能带回的城市名。 */
  city?: string;
  /** 仅 ip 来源可能带回的行政区编码。 */
  adcode?: string;
}

/** 默认兜底坐标（北京），与项目其它地方保持一致。 */
export const DEFAULT_FALLBACK_LOCATION: UserLocation = {
  latitude: 39.916527,
  longitude: 116.397128,
  source: 'fallback',
};

const isValidCoordinate = (value: unknown): value is number =>
  typeof value === 'number' && Number.isFinite(value);

/**
 * 获取用户定位（公共函数）。
 *
 * 优先级：
 *   1. Taro.getLocation 精确 GPS 定位（source: 'gps'）
 *   2. 失败退回 getLocationByIP 的 IP 粗定位（source: 'ip'）
 *   3. 再失败退回默认兜底坐标（source: 'fallback'）
 *
 * 该函数**永不 reject**，始终 resolve 出一个可用坐标，调用方可据 `source` 判断精度。
 *
 * @param options.highAccuracy 是否开启高精度 GPS（默认 false）。
 */
export const getUserLocation = async (
  options?: { highAccuracy?: boolean }
): Promise<UserLocation> => {
  // 1) GPS 精确定位
  try {
    const res: any = await Taro.getLocation({
      type: 'gcj02',
      isHighAccuracy: options?.highAccuracy ?? false,
    });
    if (isValidCoordinate(res?.latitude) && isValidCoordinate(res?.longitude)) {
      return {
        latitude: res.latitude,
        longitude: res.longitude,
        source: 'gps',
      };
    }
  } catch (error) {
    // 忽略，进入 IP 兜底
  }

  // 2) IP 粗定位
  try {
    const res: any = await getLocationByIP();
    if (isValidCoordinate(res?.latitude) && isValidCoordinate(res?.longitude)) {
      return {
        latitude: res.latitude,
        longitude: res.longitude,
        source: 'ip',
        city: res.city || '',
        adcode: res.adcode || '',
      };
    }
  } catch (error) {
    // 忽略，进入默认兜底
  }

  // 3) 默认兜底
  return { ...DEFAULT_FALLBACK_LOCATION };
};
