package com.sd.geelyhmiweb.viewmodels

import android.content.Context
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.amap.api.location.AMapLocation
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.location.AMapLocationClientOption.AMapLocationMode
import com.amap.api.location.AMapLocationClientOption.AMapLocationProtocol
import com.amap.api.location.AMapLocationListener
import com.amap.api.location.AMapLocationQualityReport
import com.amap.api.location.CoordinateConverter
import com.amap.api.location.DPoint
import com.sd.geelyhmiweb.bean.MyLoc
import com.sd.geelyhmiweb.utils.CrsShiftUtils
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject


@HiltViewModel
class AMapLoc @Inject constructor(@ApplicationContext var context: Context) : ViewModel() {

    val TAG = AMapLoc::class.java::getSimpleName.toString()
    private var locationClient: AMapLocationClient? = null
    private var locationOption: AMapLocationClientOption? = null

    private var myLoc = MyLoc()
    var myLocValue = MutableLiveData<MyLoc>()

    /**
     * 初始化定位
     *
     * @since 2.8.0
     * @author hongming.wang
     */
    fun initLocation() {
        //初始化client
        try {
            locationClient = AMapLocationClient(context)
            locationOption = getDefaultOption()
            //设置定位参数
            locationClient?.setLocationOption(locationOption)
            // 设置定位监听
            locationClient?.setLocationListener(locationListener)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 默认的定位参数
     * @since 2.8.0
     * @author hongming.wang
     */
    private fun getDefaultOption(): AMapLocationClientOption {
        val mOption = AMapLocationClientOption()
        mOption.setLocationMode(AMapLocationMode.Hight_Accuracy) //可选，设置定位模式，可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        mOption.setGpsFirst(true) //可选，设置是否gps优先，只在高精度模式下有效。默认关闭
        mOption.setHttpTimeOut(30000) //可选，设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        mOption.setInterval(2000) //可选，设置定位间隔。默认为2秒 最快1秒，低于1秒还是1秒
        mOption.setNeedAddress(false) //可选，设置是否返回逆地理地址信息。默认是true
        mOption.setOnceLocation(false) //可选，设置是否单次定位。默认是false
        mOption.setOnceLocationLatest(false) //可选，设置是否等待wifi刷新，默认为false.如果设置为true,会自动变为单次定位，持续定位时不要使用
        AMapLocationClientOption.setLocationProtocol(AMapLocationProtocol.HTTP) //可选， 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
        mOption.setSensorEnable(true) //可选，设置是否使用传感器。默认是false
        mOption.setWifiScan(true) //可选，设置是否开启wifi扫描。默认为true，如果设置为false会同时停止主动刷新，停止以后完全依赖于系统刷新，定位位置可能存在误差
        mOption.setLocationCacheEnable(true) //可选，设置是否使用缓存定位，默认为true
        mOption.setGeoLanguage(AMapLocationClientOption.GeoLanguage.DEFAULT) //可选，设置逆地理信息的语言，默认值为默认语言（根据所在地区选择语言）
        return mOption
    }

    private fun getTrancesportOption(): AMapLocationClientOption {
        val mOption = AMapLocationClientOption()
        /**
         * 设置签到场景，相当于设置为：
         * option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
         * option.setOnceLocation(false);
         * option.setOnceLocationLatest(false);
         * option.setMockEnable(false);
         * option.setWifiScan(true);
         *
         * 其他属性均为模式属性。
         * 如果要改变其中的属性，请在在设置定位场景之后进行
         */
        mOption.setHttpTimeOut(1000) //可选，设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        mOption.setInterval(2000) //可选，设置定位间隔。默认为2秒
        mOption.setLocationPurpose(AMapLocationClientOption.AMapLocationPurpose.Transport)
        return mOption
    }


    /**
     * 定位监听
     */
    private var locationListener: AMapLocationListener = AMapLocationListener { location ->
        if (null != location) {
            /*val sb = StringBuffer()
            //errCode等于0代表定位成功，其他的为定位失败，具体的可以参照官网定位错误码说明
            if (location.errorCode == 0) {
                sb.append("定位成功" + "\n")
                sb.append("定位类型: " + location.locationType + "\n")
                sb.append("经    度    : " + location.longitude + "\n")
                sb.append("纬    度    : " + location.latitude + "\n")
                sb.append("精    度    : " + location.accuracy + "米" + "\n")
                sb.append("提供者    : " + location.provider + "\n")

                sb.append("速    度    : " + location.speed + "米/秒" + "\n")
                sb.append("角    度    : " + location.bearing + "\n")
                // 获取当前提供定位服务的卫星个数
                sb.append("星    数    : " + location.satellites + "\n")
                sb.append("国    家    : " + location.country + "\n")
                sb.append("省            : " + location.province + "\n")
                sb.append("市            : " + location.city + "\n")
                sb.append("城市编码 : " + location.cityCode + "\n")
                sb.append("区            : " + location.district + "\n")
                sb.append("区域 码   : " + location.adCode + "\n")
                sb.append("地    址    : " + location.address + "\n")
                sb.append("兴趣点    : " + location.poiName + "\n")
                //定位完成的时间
         *//*       sb.append(
                    "定位时间: " + AmapUtils.formatUTC(
                        location.time,
                        "yyyy-MM-dd HH:mm:ss"
                    ) + "\n"
                )*//*
            } else {
                //定位失败
                sb.append("定位失败" + "\n")
                sb.append("错误码:" + location.errorCode + "\n")
                sb.append("错误信息:" + location.errorInfo + "\n")
                sb.append("错误描述:" + location.locationDetail + "\n")
            }
            sb.append("***定位质量报告***").append("\n")
            sb.append("* WIFI开关：")
                .append(if (location.locationQualityReport.isWifiAble) "开启" else "关闭")
                .append("\n")
            sb.append("* GPS状态：")
                .append(getGPSStatusString(location.locationQualityReport.gpsStatus)).append("\n")
            sb.append("* GPS星数：").append(location.locationQualityReport.gpsSatellites)
                .append("\n")
            sb.append("* 网络类型：" + location.locationQualityReport.networkType).append("\n")
            sb.append("* 网络耗时：" + location.locationQualityReport.netUseTime).append("\n")
            sb.append("****************").append("\n")*/
            //定位之后的回调时间
    /*        sb.append(
                "回调时间: " + AmapUtils.formatUTC(
                    System.currentTimeMillis(),
                    "yyyy-MM-dd HH:mm:ss"
                ) + "\n"
            )*/

            //解析定位结果，
//            val result = sb.toString()
//            println("result = ${result}")
//            CustomLog.d(TAG, result)
            setMyLocation(location, "result")
        } else {
//            CustomLog.d(TAG, "定位失败，loc is null")
        }
    }

    private fun setMyLocation(location: AMapLocation, debugString: String = "") {
        var dst= CrsShiftUtils.convert(location.longitude,location.latitude,CrsShiftUtils.Method.GCJ02_2_WGS84)

//        var decimalFormat = DecimalFormat("#.00000000")
//        var strLat = decimalFormat.format(dst[1])
//        var strLng = decimalFormat.format(dst[0])
        myLoc.lat = dst[1]
        myLoc.lng = dst[0]
        myLoc.bearing = location.bearing
        myLoc.altitude = location.altitude
        myLoc.speed = location.speed
//        myLoc.com_time = location.time
//        myLoc.debugStr = debugString

//        println("--------lat = ${myLoc.lat}  lng = ${myLoc.lng}  bearing=${myLoc.bearing}")
        myLocValue.postValue(myLoc)
//        val loc = location.latitude.toString() + " " + location.longitude.toString()
    }

    /**
     * 获取GPS状态的字符串
     * @param statusCode GPS状态码
     * @return
     */
    private fun getGPSStatusString(statusCode: Int): String {
        var str = ""
        when (statusCode) {
            AMapLocationQualityReport.GPS_STATUS_OK -> str = "GPS状态正常"
            AMapLocationQualityReport.GPS_STATUS_NOGPSPROVIDER -> str =
                "手机中没有GPS Provider，无法进行GPS定位"

            AMapLocationQualityReport.GPS_STATUS_OFF -> str = "GPS关闭，建议开启GPS，提高定位质量"
            AMapLocationQualityReport.GPS_STATUS_MODE_SAVING -> str =
                "选择的定位模式中不包含GPS定位，建议选择包含GPS定位的模式，提高定位质量"

            AMapLocationQualityReport.GPS_STATUS_NOGPSPERMISSION -> str =
                "没有GPS定位权限，建议开启gps定位权限"
        }
        return str
    }


    /**
     * 开始定位
     *
     * @since 2.8.0
     * @author hongming.wang
     */
    fun startLocation() {
        try {
            //根据控件的选择，重新设置定位参数
//            resetOption()
            // 设置定位参数
            locationClient?.setLocationOption(locationOption)
            // 启动定位
            locationClient?.startLocation()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 停止定位
     *
     * @since 2.8.0
     * @author hongming.wang
     */
    fun stopLocation() {
        try {
            // 停止定位
            locationClient?.stopLocation()
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 销毁定位
     *
     * @since 2.8.0
     * @author hongming.wang
     */
    fun destroyLocation() {
        if (null != locationClient) {
            /**
             * 如果AMapLocationClient是在当前Activity实例化的，
             * 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy
             */
            locationClient?.onDestroy()
            locationClient = null
            locationOption = null
        }
    }


    /**
     * WGS-84转高德坐标(GCJ-02)
     */
    fun convertWGS84ToGCJ02(longitude: Double, latitude: Double): DPoint {
        val converter = CoordinateConverter(context)
        // 设置源坐标为GPS坐标（WGS-84）
        converter.from(CoordinateConverter.CoordType.GPS)
        converter.coord(DPoint(latitude, longitude))
        val destLatLng = converter.convert()

        return destLatLng
    }


}