
import android.content.Context;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;

/**
 * 高德定位服务类
 * 提供基于高德地图的定位功能，支持多种定位模式和场景
 * 优化后的版本使用更规范的回调机制和资源管理
 */
public class VolAMapLocation {

    public VolAMapLocation ()  { }

    protected int gpsStatus;
    private AMapLocationClient locationClient = null;
    private AMapLocationListener mLocationListener;
    private boolean isInitialized = false;
    private boolean isLocating = false;

    /**
     * 定位结果数据类
     * 封装了定位返回的所有信息，便于统一管理和传递
     */
    public static class LocationResult {
        public final int errorCode;           // 错误码
        public final int locationType;        // 定位类型
        public final double latitude;         // 纬度
        public final double longitude;        // 经度
        public final double accuracy;         // 精度
        public final double altitude;         // 海拔
        public final double speed;            // 速度
        public final double bearing;          // 方向角
        public final String buildingId;       // 室内定位建筑物ID
        public final String floor;            // 室内定位楼层
        public final String address;          // 地址描述
        public final String country;          // 国家
        public final String province;         // 省份
        public final String city;             // 城市
        public final String district;         // 城区
        public final String street;           // 街道
        public final String streetNum;        // 街道门牌号
        public final String cityCode;         // 城市编码
        public final String adCode;           // 区域编码
        public final String poiName;          // 当前位置POI名称
        public final String aoiName;          // 当前位置所处AOI名称
        public final int gpsStatus;           // 设备当前GPS状态

        /**
         * 构造函数
         * @param location 高德定位结果对象
         * @param gpsStatus GPS状态
         */
        public LocationResult(AMapLocation location, int gpsStatus) {
            this.errorCode = location.getErrorCode();
            this.locationType = location.getLocationType();
            this.latitude = location.getLatitude();
            this.longitude = location.getLongitude();
            this.accuracy = location.getAccuracy();
            this.altitude = location.getAltitude();
            this.speed = location.getSpeed();
            this.bearing = location.getBearing();
            this.buildingId = location.getBuildingId();
            this.floor = location.getFloor();
            this.address = location.getAddress();
            this.country = location.getCountry();
            this.province = location.getProvince();
            this.city = location.getCity();
            this.district = location.getDistrict();
            this.street = location.getStreet();
            this.streetNum = location.getStreetNum();
            this.cityCode = location.getCityCode();
            this.adCode = location.getAdCode();
            this.poiName = location.getPoiName();
            this.aoiName = location.getAoiName();
            this.gpsStatus = gpsStatus;
        }
    }

    /**
     * 初始化失败监听器接口
     */
    public interface OnInitializationFailedListener {
        /**
         * 初始化失败回调
         * @param reason 失败原因
         */
        void onInitializationFailed(String reason);
    }

    /**
     * 定位结果监听器接口
     */
    public interface OnLocationResultListener {
        /**
         * 定位结果回调
         * @param result 定位结果数据
         */
        void onLocationResult(LocationResult result);
    }

    private OnInitializationFailedListener initializationFailedListener;
    private OnLocationResultListener locationResultListener;

    /**
     * 设置初始化失败监听器
     * @param listener 监听器实例
     */
    public void setOnInitializationFailedListener(OnInitializationFailedListener listener) {
        synchronized (this) {
            this.initializationFailedListener = listener;
        }
    }

    /**
     * 设置定位结果监听器
     * @param listener 监听器实例
     */
    public void setOnLocationResultListener(OnLocationResultListener listener) {
        synchronized (this) {
            this.locationResultListener = listener;
        }
    }

    /**
     * 通知初始化失败
     * 内部方法，用于触发初始化失败回调
     * 
     * @param reason 失败原因
     */
    private void notifyInitializationFailed(String reason) {
        synchronized (this) {
            if (initializationFailedListener != null) {
                initializationFailedListener.onInitializationFailed(reason);
            }
        }
    }

    /**
     * 通知定位结果
     * 内部方法，用于触发定位结果回调
     * 
     * @param result 定位结果数据
     */
    private void notifyLocationResult(LocationResult result) {
        synchronized (this) {
            if (locationResultListener != null) {
                locationResultListener.onLocationResult(result);
            }
        }
    }

    /**
     * 初始化定位服务
     * 创建高德定位客户端并设置定位监听器
     * 
     * @return 初始化成功返回true，失败返回false
     */
    public boolean initialize(android.content.Context context) {
        synchronized (this) {
            if (isInitialized) {
                return true;
            }
            
            try {
                mLocationListener = new AMapLocationListener() {
                    @Override
                    public void onLocationChanged(AMapLocation aMapLocation) {
                        if (aMapLocation.getGpsAccuracyStatus() == AMapLocation.GPS_ACCURACY_GOOD) {
                            gpsStatus = 1;
                        } else if (aMapLocation.getGpsAccuracyStatus() == AMapLocation.GPS_ACCURACY_BAD) {
                            gpsStatus = 0;
                        } else if (aMapLocation.getGpsAccuracyStatus() == AMapLocation.GPS_ACCURACY_UNKNOWN) {
                            gpsStatus = -1;
                        }
                        
                        LocationResult result = new LocationResult(aMapLocation, gpsStatus);
                        notifyLocationResult(result);
                    }
                };
                
                locationClient = new AMapLocationClient(context);
                locationClient.setLocationListener(mLocationListener);
                
                isInitialized = true;
                return true;
            } catch (Exception e) {
                //String errorMessage = "初始化失败: " + volcano.Java.base.rg_KeFuHuoYiChangLei.rg_取异常文本(e);
                //notifyInitializationFailed(errorMessage);
                return false;
            }
        }
    }



    /**
     * 开始定位
     * 根据指定的参数配置并启动定位服务
     * 
     * @param scene 定位场景，
     * @param mode 定位模式
     * @param singleLocation 是否单次定位
     * @param interval 定位间隔时间（毫秒）
     * @param needAddress 是否需要地址信息
     * @param mockEnable 是否允许模拟位置
     * @param timeout 定位超时时间（毫秒）
     * @param cacheEnable 是否启用定位缓存
     * @return 启动成功返回true，失败返回false
     */
    public boolean startLocation(int scene, int mode, boolean singleLocation, long interval, 
                                boolean needAddress, boolean mockEnable, long timeout, boolean cacheEnable) {
        synchronized (this) {
            
            if (isLocating) {
                stopLocation();
            }
            
            try {
                AMapLocationClientOption option = new AMapLocationClientOption();
                AMapLocationClientOption.AMapLocationPurpose aMapLocationPurpose = null;
                AMapLocationClientOption.AMapLocationMode aMapLocationMode = null;
                
                if (scene == 3) {
                    aMapLocationPurpose = AMapLocationClientOption.AMapLocationPurpose.Sport;
                } else if (scene == 1) {
                    aMapLocationPurpose = AMapLocationClientOption.AMapLocationPurpose.SignIn;
                } else if (scene == 2) {
                    aMapLocationPurpose = AMapLocationClientOption.AMapLocationPurpose.Transport;
                }
                
                if (mode == 1) {
                    aMapLocationMode = AMapLocationClientOption.AMapLocationMode.Device_Sensors;
                } else if (mode == 2) {
                    aMapLocationMode = AMapLocationClientOption.AMapLocationMode.Battery_Saving;
                } else if (mode == 3) {
                    aMapLocationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy;
                } else {
                    aMapLocationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy;
                }
                
                if (aMapLocationPurpose != null) {
                    option.setLocationPurpose(aMapLocationPurpose);
                }
                if (aMapLocationMode != null) {
                    option.setLocationMode(aMapLocationMode);
                }
                
                option.setOnceLocation(singleLocation);
                if (interval > 0) {
                    option.setInterval(interval);
                }
                option.setNeedAddress(needAddress);
                option.setMockEnable(mockEnable);
                option.setHttpTimeOut(timeout);
                option.setLocationCacheEnable(cacheEnable);
                
                locationClient.setLocationOption(option);
                locationClient.startLocation();
                
                isLocating = true;
                return true;
            } catch (Exception e) {
                //notifyInitializationFailed("开始定位失败: " + volcano.Java.base.rg_KeFuHuoYiChangLei.rg_取异常文本(e));
                return false;
            }
        }
    }


    /**
     * 停止定位
     * 停止当前正在进行的定位服务，但不会释放定位资源
     */
    public void stopLocation() {
        synchronized (this) {
            if (locationClient != null && isLocating) {
                try {
                    locationClient.stopLocation();
                    isLocating = false;
                } catch (Exception e) {
                    //notifyInitializationFailed("停止定位失败: " + volcano.Java.base.rg_KeFuHuoYiChangLei.rg_取异常文本(e));
                }
            }
        }
    }

    /**
     * 释放资源
     * 停止定位并释放所有定位相关资源，包括定位客户端和监听器
     * 调用此方法后需要重新初始化才能再次使用定位功能
     */
    public void release() {
        synchronized (this) {
            stopLocation();
            if (locationClient != null) {
                try {
                    locationClient.onDestroy();
                    locationClient = null;
                } catch (Exception e) {
                    //notifyInitializationFailed("释放资源失败: " + volcano.Java.base.rg_KeFuHuoYiChangLei.rg_取异常文本(e));
                }
            }
            isInitialized = false;
            initializationFailedListener = null;
            locationResultListener = null;
        }
    }
}
