package com.abbidot.tracker.vm

import android.text.TextUtils
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.abbidot.baselibrary.constant.MMKVKey
import com.abbidot.baselibrary.util.AppUtils
import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.baselibrary.util.MMKVUtil
import com.abbidot.tracker.util.LonAndLatUtil
import com.baidu.mapapi.model.LatLng
import com.baidu.mapapi.search.geocode.GeoCodeResult
import com.baidu.mapapi.search.geocode.GeoCoder
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult
import com.mapbox.geojson.Point
import com.mapbox.search.ResponseInfo
import com.mapbox.search.ReverseGeoOptions
import com.mapbox.search.SearchCallback
import com.mapbox.search.SearchEngine
import com.mapbox.search.SearchEngineSettings
import com.mapbox.search.common.AsyncOperationTask
import com.mapbox.search.result.SearchResult


/**
 *Created  by .yzq on 2022/6/27/027.
 * @link
 * @description: 地理编码(mapbox地图 和 百度地图)
 */
class GeoCoderViewModel : ViewModel() {

    var mLat = 0.0
    var mLon = 0.0

    //地区、州、省
    var mRegion = ""

    //国家缩写
    var mCountryCode = ""
    var mAddress = ""
    val mLatLonAddressLiveData = MutableLiveData<String>()

    //Mapbox反向地理编码
    private var mMapboxSearchRequestTask: AsyncOperationTask? = null
    private var mSearchEngine: SearchEngine? = null

    //百度地图反向地理编码
    private var mBaiduMapGeoCoder: GeoCoder? = null

    //是否显示详细地址信息
    private var isShowDetailAddress = true

    /**
     * 反地理编码
     * 使用原生gps(WGS84)坐标
     * @param showDetailAddress 是否显示最详细的地址
     */
    fun getLatLonAddress(latitude: Double, longitude: Double, showDetailAddress: Boolean = true) {
        if (latitude == 0.0 && longitude == 0.0) return

        isShowDetailAddress = showDetailAddress

        //相同经纬度不需要反地理编码
        if (mLon == longitude && mLat == latitude) {
            mLatLonAddressLiveData.value = mAddress
            return
        }
        mLon = longitude
        mLat = latitude

        if (AppUtils.isChina(AppUtils.SWITCH_MAP_TYPE)) {
            baiduMapReverseGeocoder(latitude, longitude)
        } else {
            if (MMKVUtil.getBoolean(MMKVKey.isGpsToGCJ02)) {
                baiduMapReverseGeocoder(latitude, longitude)
            } else {
                mapBoxReverseGeocoder(latitude, longitude)
            }
        }
    }

    /**
     * Mapbox反向地理编码
     */
    private fun mapBoxReverseGeocoder(latitude: Double, longitude: Double) {
        if (null == mSearchEngine) {
            mSearchEngine =
                SearchEngine.createSearchEngineWithBuiltInDataProviders(SearchEngineSettings())
        }
        mMapboxSearchRequestTask?.cancel()
        mMapboxSearchRequestTask = mSearchEngine?.search(
            ReverseGeoOptions(
                center = Point.fromLngLat(longitude, latitude)
            ), object : SearchCallback {
                override fun onError(e: Exception) {
                    LogUtil.e(" Mapbox反地理编码error,${e.message}")
//                        mLatLonAddressLiveData.value = ""
                    baiduMapReverseGeocoder(latitude, longitude)
                }

                override fun onResults(
                    results: List<SearchResult>, responseInfo: ResponseInfo
                ) {
                    LogUtil.e(results.toString())
                    if (results.isNotEmpty()) {
                        val searchResult = results[0]
                        var address = ""
                        searchResult.metadata?.let {
                            it.countryIso1?.let { countryCode ->
                                mCountryCode = countryCode.uppercase()
                            }
                        }
                        searchResult.address?.let {
                            if (!TextUtils.isEmpty(it.houseNumber)) {
                                address += "${it.houseNumber} "
                            }
                            if (!TextUtils.isEmpty(it.street)) {
                                address += "${it.street} "
                            }
                            if (TextUtils.isEmpty(address) && !TextUtils.isEmpty(it.neighborhood)) {
                                address += "${it.neighborhood} "
                            }
                            if (isShowDetailAddress && !TextUtils.isEmpty(it.locality)) {
                                address += "${it.locality} "
                            }
                            if (isShowDetailAddress && !TextUtils.isEmpty(it.place)) {
                                address += "${it.place} "
                            }
                            if (isShowDetailAddress && !TextUtils.isEmpty(it.region)) {
                                address += "${it.region} "
                            }
                            if (isShowDetailAddress && !TextUtils.isEmpty(it.country)) {
                                address += "${it.country}"
                            }

                            //防止显示空的地址
                            if (TextUtils.isEmpty(address) && !TextUtils.isEmpty(it.locality)) {
                                address += "${it.locality} "
                            }
                            if (TextUtils.isEmpty(address) && !TextUtils.isEmpty(it.place)) {
                                address += "${it.place} "
                            }
                            if (TextUtils.isEmpty(address) && !TextUtils.isEmpty(it.region)) {
                                address += "${it.region} "
                            }
                            mRegion = it.region.toString()
                        }
//                    address = address?.replace("null", "")
                        mAddress = address
                        LogUtil.e("Mapbox反地理编码:$mAddress")
                        mLatLonAddressLiveData.value = mAddress
                    } else {
//                            mLatLonAddressLiveData.value = ""-
                        baiduMapReverseGeocoder(latitude, longitude)
                    }
                }
            })
    }

    /**
     * 百度地图反向地理编码
     */
    private fun baiduMapReverseGeocoder(latitude: Double, longitude: Double) {
        if (null == mBaiduMapGeoCoder) {
            mBaiduMapGeoCoder = GeoCoder.newInstance()
        }
        mBaiduMapGeoCoder?.destroy()
        mBaiduMapGeoCoder!!.setOnGetGeoCodeResultListener(object : OnGetGeoCoderResultListener {
            override fun onGetGeoCodeResult(p0: GeoCodeResult?) {
            }

            override fun onGetReverseGeoCodeResult(result: ReverseGeoCodeResult?) {
                if (null == result || result.error != com.baidu.mapapi.search.core.SearchResult.ERRORNO.NO_ERROR) {
                    //没有找到检索结果
                    return
                } else {
                    var address = ""
                    //行政区号
//                    val adCode = result.cityCode
                    result.addressDetail.apply {
                        if (isShowDetailAddress && !TextUtils.isEmpty(province)) {
                            address += province
                        }
                        if (isShowDetailAddress && !TextUtils.isEmpty(city)) {
                            address += city
                        }
                        if (!TextUtils.isEmpty(district)) {
                            address += district
                        }
                        if (!TextUtils.isEmpty(town)) {
                            address += town
                        }
                        if (!TextUtils.isEmpty(street)) {
                            address += street
                        }
                        if (!TextUtils.isEmpty(streetNumber)) {
                            address += streetNumber
                        }
                        mRegion = province
                        mCountryCode = countryCodeIso2.uppercase()
                        LogUtil.e("百度地图反向地理编码详细地址,${streetNumber},${town},${street},$result")
                    }
                    //详细地址
//                    val address = result.address
                    mAddress = address
                    mLatLonAddressLiveData.value = mAddress
                }
            }
        })
        val convertLonLat = LonAndLatUtil.convertFromWGS84ToGCJ02(latitude, longitude)
        mBaiduMapGeoCoder!!.reverseGeoCode(
            ReverseGeoCodeOption().location(LatLng(convertLonLat[0], convertLonLat[1]))
                // 设置是否返回新数据 默认值0不返回，1返回
                .newVersion(1)
                // POI召回半径，允许设置区间为0-1000米，超过1000米按1000米召回。默认值为1000
                .radius(500)
        )
    }

    override fun onCleared() {
        super.onCleared()
        //取消反地理编码搜索
        mBaiduMapGeoCoder?.destroy()
        mMapboxSearchRequestTask?.cancel()
    }
}