package com.sjkj.base_lib.utils;

import android.text.TextUtils;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Poi;
import com.amap.api.navi.AmapNaviPage;
import com.amap.api.navi.AmapNaviParams;
import com.amap.api.navi.AmapNaviType;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.sjkj.base_lib.app.AppManager;
import com.sjkj.base_lib.app.BaseApp;

import java.util.List;

public class LocationUtils implements AMapLocationListener {
    private static LocationUtils locationUtils;
    private AMapLocationClient mLocationClient = null;
    private AMapLocationClientOption mLocationOption = null;
    private OnLocationListener mLocation;

    public static LocationUtils getInstance() {
        if (locationUtils == null) {
            synchronized (LocationUtils.class) {
                if (locationUtils == null) {
                    locationUtils = new LocationUtils();
                }
            }
        }
        return locationUtils;
    }

    private void init(boolean onceLocation) {
        try {
            mLocationClient = new AMapLocationClient(BaseApp.getInstance());
        } catch (Exception e) {
            e.printStackTrace();
        }
        mLocationOption = new AMapLocationClientOption();
        //设置定位模式为AMapLocationMode.Hight_Accuracy，高精度模式。
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        //设置定位间隔,单位毫秒,默认为2000ms
        mLocationOption.setInterval(5000);
        //设置是否只定位一次,默认为false
        mLocationOption.setOnceLocation(onceLocation);
        //返回最近3s内精度最高的一次定位结果。
        mLocationOption.setOnceLocationLatest(onceLocation);
        //设置是否返回地址信息（默认返回地址信息）
        mLocationOption.setNeedAddress(true);
        //单位是毫秒，默认30000毫秒，建议超时时间不要低于8000毫秒。
        mLocationOption.setHttpTimeOut(20000);
        //关闭缓存机制
        mLocationOption.setLocationCacheEnable(false);
        //给定位客户端对象设置定位参数
        mLocationClient.setLocationOption(mLocationOption);
        mLocationClient.setLocationListener(this);
    }

//    public String getAddress(double latitude, double longitude) {
//        Geocoder geocoder = new Geocoder(App.getInstance(), Locale.getDefault());
//        try {
//            List<Address> addresses = geocoder.getFromLocation(latitude,
//                    longitude, 1);
//            if (addresses.size() > 0) {
//                Address address = addresses.get(0);
//                String data = address.getAddressLine(0);
////                int startCity = data.indexOf("1:\"") + "1:\"".length();
////                int endCity = data.indexOf("\"", startCity);
////                String city = data.substring(startCity, endCity);
////
////                int startPlace = data.indexOf("feature=") + "feature=".length();
////                int endplace = data.indexOf(",", startPlace);
////                String place = data.substring(startPlace, endplace);
////                return city + place;
//                return data;
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        return "";
//    }

    public void startLocation(boolean onceLocation, OnLocationListener locationListener) {
        try {
            this.mLocation = locationListener;
            XXPermissions.with(AppManager.getAppManager().currentActivity())
                    .permission(Permission.ACCESS_COARSE_LOCATION)
                    .permission(Permission.ACCESS_FINE_LOCATION)
//                    .permission(Permission.ACCESS_BACKGROUND_LOCATION)
                    .request(new OnPermissionCallback() {
                        @Override
                        public void onGranted(List<String> permissions, boolean all) {
                            if (all) {
                                init(onceLocation);
                                mLocationClient.startLocation();//开始
                            } else {
                                ToastUtils.show("获取部分权限成功，但部分权限未正常授予");
                            }
                        }

                        @Override
                        public void onDenied(List<String> permissions, boolean never) {
                            if (never) {
                                ToastUtils.show("被永久拒绝授权，请手动授予权限");
                                // 如果是被永久拒绝就跳转到应用权限系统设置页面
                                XXPermissions.startPermissionActivity(AppManager.getAppManager().currentActivity(), permissions);
                            } else {
                                ToastUtils.show("获取权限失败");
                            }
                        }
                    });
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    public void mapNav(double latitude, double longitude, String to) {
        getInstance().startLocation(true, new OnLocationListener() {
            @Override
            public void onLocationChanged(double lat, double lng, String address, int code) {
                if (code == 0) {
                    double mLongitude = lng;
                    double mLatitude = lat;
                    try {
                        double[] locations = gps84_To_Gcj02(mLatitude, mLongitude);
                        LatLng startPoint = new LatLng(locations[0], locations[1]);

                        double[] eventLocations = gps84_To_Gcj02(latitude, longitude);
                        LatLng endPoint = new LatLng(eventLocations[0], eventLocations[1]);
                        String addressStr = address;
                        if (TextUtils.isEmpty(addressStr)) {
                            addressStr = "起点";
                        }
                        Poi start = new Poi(addressStr, startPoint, "");
                        String toAddress = to;
                        if (TextUtils.isEmpty(toAddress)) {
                            toAddress = "终点";
                        }
                        Poi end = new Poi(toAddress, endPoint, "");
                        AmapNaviParams amapNaviParams = new AmapNaviParams(start, null, end, AmapNaviType.DRIVER);
                        amapNaviParams.setUseInnerVoice(true);
                        AmapNaviPage.getInstance().showRouteActivity(AppManager.getAppManager().currentActivity(), amapNaviParams, null);
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                        ToastUtils.show("路线分析失败");
                    }
                }
            }
        });
    }

    public static double pi = 3.1415926535897932384626;
    public static double ee = 0.00669342162296594323;
    public static double a = 6378245.0;

    /**
     * 84 to 火星坐标系 (GCJ-02) World Geodetic System ==> Mars Geodetic System
     *
     * @param lat
     * @param lon
     * @return
     */
    public static double[] gps84_To_Gcj02(double lat, double lon) {
        if (outOfChina(lat, lon)) {
            return new double[]{lat, lon};
        }
        double dLat = transformLat(lon - 105.0, lat - 35.0);
        double dLon = transformLon(lon - 105.0, lat - 35.0);
        double radLat = lat / 180.0 * pi;
        double magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
        double mgLat = lat + dLat;
        double mgLon = lon + dLon;
        return new double[]{mgLat, mgLon};
    }

    public static boolean outOfChina(double lat, double lon) {
        if (lon < 72.004 || lon > 137.8347)
            return true;
        if (lat < 0.8293 || lat > 55.8271)
            return true;
        return false;
    }

    public static double transformLat(double x, double y) {
        double 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;
    }

    public static double transformLon(double x, double y) {
        double 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;
    }

    public void stopLocation() {
        if (null == mLocationClient) {
            return;
        }
        mLocationClient.unRegisterLocationListener(this);
        mLocationClient.stopLocation();//关闭
        mLocationClient.onDestroy();//销毁
        mLocationClient = null;
    }

    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if (mLocation != null) {
            MapUtils.GPS gps = MapUtils.gcj_To_Gps84(aMapLocation.getLatitude(), aMapLocation.getLongitude());
            if (aMapLocation != null) {
                mLocation.onLocationChanged(gps.getLat(), gps.getLon(), aMapLocation.getAddress(), aMapLocation.getErrorCode());
            }
        }
    }

    public interface OnLocationListener {
        void onLocationChanged(double lat, double lng, String address, int code);
    }
}
