package com.abbidot.tracker.vm

import android.content.Context
import android.content.Intent
import android.os.CountDownTimer
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.AppCompatImageView
import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.recyclerview.widget.RecyclerView
import com.abbidot.baselibrary.constant.MMKVKey
import com.abbidot.baselibrary.list.BaseRecyclerAdapter
import com.abbidot.baselibrary.util.MMKVUtil
import com.abbidot.baselibrary.util.Utils
import com.abbidot.tracker.R
import com.abbidot.tracker.adapter.SelectMapListDialogAdapter
import com.abbidot.tracker.base.BaseActivity
import com.abbidot.tracker.bean.DataBean
import com.abbidot.tracker.bean.MapDeviceBean
import com.abbidot.tracker.bean.MenuTxtBean
import com.abbidot.tracker.bean.PetBean
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.dialog.SelectMapListDialog
import com.abbidot.tracker.retrofit2.NetworkApi
import com.abbidot.tracker.util.LonAndLatUtil
import com.abbidot.tracker.util.Util
import com.abbidot.tracker.util.ViewUtil
import com.abbidot.tracker.util.bluetooth.SRBleUtil
import com.abbidot.tracker.widget.TypefaceButton
import com.abbidot.tracker.widget.TypefaceTextView
import com.clj.fastble.BleManager
import kotlinx.coroutines.launch

class MapViewModel : ViewModel() {

    val mMapDeviceLiveData = MutableLiveData<Result<MapDeviceBean>>()
    val mRefreshLocationLiveData = MutableLiveData<Result<String>>()
    private var mCountDownTimer: CountDownTimer? = null

    //几分钟倒计时(min)
    private var mRefreshDataMin = 0.35f
    private var mDeviceId = ""

    var mDeviceMsgType = ConstantInt.SpecialType

    private val mMapGooglePackageName = "com.google.android.apps.maps"
    private val mMapGaoDePackageName = "com.autonavi.minimap"
    private val mMapBaiduPackageName = "com.baidu.BaiduMap"
    private var mSelectMapListDialogAdapter: SelectMapListDialogAdapter? = null
    private var mSelectMapListDialog: SelectMapListDialog? = null
    private var mMapDeviceBean: MapDeviceBean? = null

    fun setupRefreshLocation(deviceId: String) {
        viewModelScope.launch {
            val result = NetworkApi.setupRefreshLocation(deviceId)
            mRefreshLocationLiveData.value = result
        }
    }

    fun getMapDeviceStatus(deviceId: String, isNeedCountDown: Boolean = true) {
        viewModelScope.launch {
            stopGetData()
            val result = NetworkApi.getMapDeviceStatus(deviceId)
            mMapDeviceLiveData.value = result
        }
        mDeviceId = deviceId
        if (isNeedCountDown) countDownGetData(deviceId)
    }

    /**
     * 更新刷新时间
     */
    fun updateMillisInFuture(refreshMin: Float) {
        if (refreshMin <= 0) return
        mRefreshDataMin = refreshMin
        countDownGetData(mDeviceId)
    }

    /**
     * 每隔mMillisInFuture分钟执行一次请求
     */
    private fun countDownGetData(deviceId: String) {
        stopGetData()
        mCountDownTimer = object : CountDownTimer((mRefreshDataMin * 60 * 1000L).toLong(), 1000) {
            override fun onTick(time: Long) {
            }

            override fun onFinish() {
                getMapDeviceStatus(deviceId)
            }
        }.start()
    }

    /**
     * 设置设备默认状态
     */
    fun addDeviceDefaultStateData(context: Context, deviceStateList: MutableList<DataBean>) {
        DataBean().apply {
            imageId = R.drawable.icon_map_signal
            menuType = ConstantInt.Close
            name = "LTE"
            value =
                context.getString(R.string.tracker_manage_set_network) + "：" + context.getString(R.string.txt_offline)
            deviceStateList.add(this)
        }
        DataBean().apply {
            imageId = R.drawable.icon_map_gps
            menuType = ConstantInt.Close
            name = context.getString(R.string.tracker_manage_set_gps)
            value =
                context.getString(R.string.tracker_manage_set_gps) + "：" + context.getString(R.string.txt_sleep)
            deviceStateList.add(this)
        }
        DataBean().apply {
            imageId = R.drawable.icon_map_zone
            menuType = ConstantInt.Close
            name = context.getString(R.string.txt_wifi)
            value =
                context.getString(R.string.txt_smart_power_zone) + "：" + context.getString(R.string.txt_outside)
            deviceStateList.add(this)
        }
        DataBean().apply {
            imageId = 0
            state = -1
            menuType = ConstantInt.Close
            value = String.format(context.getString(R.string.tracker_manage_set_battery), "0")
            name = "N/A"
            deviceStateList.add(this)
        }
    }

    /**
     * 设置设备状态和告警信息显示
     */
    fun setDeviceStateAndWarningData(
        context: Context,
        petBean: PetBean?,
        mapDeviceBean: MapDeviceBean,
        deviceStateList: MutableList<DataBean>,
        deviceStateAdapter: BaseRecyclerAdapter<DataBean>,
        deviceMsgList: MutableList<DataBean>,
        deviceMsgAdapter: BaseRecyclerAdapter<DataBean>,
        rvMsg: RecyclerView,
        isLive: Boolean = false
    ) {
        ViewUtil.instance.viewShow(rvMsg)
        mapDeviceBean.apply {
            deviceMsgList.clear()
            //设备关机
            if (powerSwitch == ConstantInt.Close) {
//                setNoState(context, deviceStateList)
                //警告状态
                DataBean().apply {
                    val timeString =
                        Utils.formatTime(updateTime * 1000, Utils.DATE_FORMAT_PATTERN_EN6)
                    value = context.getString(R.string.txt_tracker_power_off) + " $timeString"
                    deviceMsgList.add(this)
                }
            }
            //设备充电
            else if (powerSwitch == ConstantInt.Type3) {
//                setDeviceState(context, mapDeviceBean, deviceStateList)

                //警告状态
                DataBean().apply {
                    value = context.getString(R.string.txt_on_charging)
                    deviceMsgList.add(this)
                }
            }
            //设备休眠
            else if (powerSwitch == ConstantInt.Type2) {
//                setDeviceState(context, mapDeviceBean, deviceStateList)
//                setNoState(context, deviceStateList)

                //警告状态
                DataBean().apply {
                    value = context.getString(R.string.txt_in_sleep_mode)
                    deviceMsgList.add(this)
                }
            }
            //判断是否连接了蓝牙
            else if (null != petBean && null != SRBleUtil.instance.getConnectMacDevice(petBean.macID)) {
                //网络无信号
//                if (lteSignal <= ConstantInt.NoSignal) {
//                    setNoState(context, deviceStateList)
//                } else {
//                    setDeviceState(context, mapDeviceBean, deviceStateList)
//                }
                val nearby =
                    String.format(context.getString(R.string.txt_is_nearby), petBean.petName)
                //警告状态
                DataBean().apply {
                    value = nearby
                    state = ConstantInt.Type1
                    deviceMsgList.add(this)
                }
            }
            //网络无信号/ 分钟后无上报所有绿点取消显示
            else if (lteSignal <= ConstantInt.NoSignal || Util.isTimeoutReport(
                    updateTime, gnssInterval
                )
            ) {
//                setNoState(context, deviceStateList)

                //警告状态
                DataBean().apply {
                    value = context.getString(R.string.map_current_no_signal)
                    deviceMsgList.add(this)
                }
            } else {
                //警告状态
                setWaringData(context, mapDeviceBean, deviceMsgList, isLive)
            }
            setDeviceState(context, mapDeviceBean, deviceStateList)
            deviceStateAdapter.notifyItemRangeChanged(0, deviceStateList.size)
            deviceMsgAdapter.setData(deviceMsgList)
            deviceMsgAdapter.notifyDataSetChanged()
//            if (deviceMsgList.size > 0) {
//                if (isWarningAnimEnd) {
//                    YoYo.with(Techniques.FadeOut).onStart {
//                        isWarningAnimEnd = false
//                    }.onEnd {
//                        isWarningAnimEnd = true
//                    }.delay(29 * 1000).duration(3000).playOn(rvMsg)
//                }
//            }
        }
    }

    /**
     * 设置设备状态和告警信息显示
     */
    fun setDeviceStateAndWarningData(
        context: Context,
        petBean: PetBean?,
        mapDeviceBean: MapDeviceBean,
        rootView: ViewGroup,
        tvDeviceMsgView: TypefaceButton,
        deviceMsgCloseBtn: AppCompatImageView,
        deviceStateList: MutableList<DataBean>,
        deviceStateAdapter: BaseRecyclerAdapter<DataBean>,
    ) {
        mapDeviceBean.apply {
            tvDeviceMsgView.setBackgroundResource(R.color.device_msg_color1)
            if (null != petBean && BleManager.getInstance().isConnected(petBean.macID)) {
                if (isCloseMsg && mDeviceMsgType == ConstantInt.Type0) {

                } else {
                    val nearby =
                        String.format(context.getString(R.string.txt_is_nearby), petBean.petName)
                    tvDeviceMsgView.text = nearby
                    isCloseMsg = false
                    tvDeviceMsgView.setBackgroundResource(R.color.green_color10)
                    ViewUtil.instance.viewShow(rootView)
                    deviceMsgCloseBtn.visibility = View.GONE
                }
            } else if (inNoGoZone == ConstantInt.BadZone) {
                if (isCloseMsg && mDeviceMsgType == ConstantInt.Type1) {

                } else {
                    tvDeviceMsgView.text = context.getString(R.string.txt_in_no_go_zone)
                    ViewUtil.instance.viewShow(deviceMsgCloseBtn)
                    ViewUtil.instance.viewShow(rootView)
                    isCloseMsg = false
                    mDeviceMsgType = ConstantInt.Type1
                }
            } else if (inSafeZone == ConstantInt.BadZone) {
                if (isCloseMsg && mDeviceMsgType == ConstantInt.Type2) {

                } else {
                    tvDeviceMsgView.text = context.getString(R.string.txt_out_save_zone)
                    ViewUtil.instance.viewShow(rootView)
                    ViewUtil.instance.viewShow(deviceMsgCloseBtn)
                    isCloseMsg = false
                    mDeviceMsgType = ConstantInt.Type2
                }
            } else {
                mDeviceMsgType = ConstantInt.Type3
                rootView.visibility = View.GONE
            }
            setDeviceState(context, mapDeviceBean, deviceStateList)
//            deviceStateAdapter.notifyItemRangeChanged(0, deviceStateList.size)
            deviceStateAdapter.notifyDataSetChanged()
        }
    }

    /**
     * 设置没有的状态
     */
    private fun setNoState(context: Context, deviceStateList: MutableList<DataBean>) {
        deviceStateList[0].apply {
            menuType = ConstantInt.Close
            value =
                context.getString(R.string.tracker_manage_set_network) + "：" + context.getString(R.string.txt_offline)
        }
        deviceStateList[1].apply {
            menuType = ConstantInt.Close
            value =
                context.getString(R.string.tracker_manage_set_gps) + "：" + context.getString(R.string.txt_sleep)
        }
        deviceStateList[2].apply {
            menuType = ConstantInt.Close
            value =
                context.getString(R.string.txt_smart_power_zone) + "：" + context.getString(R.string.txt_outside)
        }
        deviceStateList[3].apply {
            menuType = ConstantInt.Close
            state = -1
            value = String.format(
                context.getString(R.string.tracker_manage_set_battery), "--"
            )
            name = "N/A"
        }
    }

    /**
     * 设置设备状态
     */
    private fun setDeviceState(
        context: Context, mapDeviceBean: MapDeviceBean, deviceStateList: MutableList<DataBean>
    ) {
        mapDeviceBean.let {
            //是否超时上报
            val isTimeoutReport = Util.isTimeoutReport(it.updateTime, it.gnssInterval)
            deviceStateList[0].apply {
                menuType = ConstantInt.Open
                val lteValue =
                    if (isTimeoutReport || it.lteSignal == ConstantInt.NoSignal || it.powerSwitch == ConstantInt.Type0 || it.powerSwitch == ConstantInt.Type2) {
                        menuType = ConstantInt.Close
                        context.getString(R.string.txt_offline)
                    } else {
                        context.getString(R.string.txt_online)
                    }
                value = context.getString(R.string.tracker_manage_set_network) + "：$lteValue"
            }
            deviceStateList[1].apply {
                menuType = ConstantInt.Open
                val gpsValue =
                    if (isTimeoutReport || it.powerSwitch == ConstantInt.Type0 || it.powerSwitch == ConstantInt.Type2 || it.powerSwitch == ConstantInt.Type3 || it.inWifiZone == ConstantInt.Type1) {
                        menuType = ConstantInt.Close
                        context.getString(R.string.txt_sleep)
                    } else if (it.gpsSignal > ConstantInt.WeakSignal) context.getString(R.string.txt_strong_signal)
                    else if (it.gpsSignal == ConstantInt.NoSignal) {
                        menuType = ConstantInt.Close
                        context.getString(R.string.txt_no_signal)
                    } else context.getString(R.string.txt_weak_signal)
                value = context.getString(R.string.tracker_manage_set_gps) + "：$gpsValue"
            }
            deviceStateList[2].apply {
                menuType = ConstantInt.Open
                val wifiZoneValue = when (it.inWifiZone) {
                    ConstantInt.Open -> context.getString(R.string.txt_inside)

                    ConstantInt.Type2 -> {
                        menuType = ConstantInt.Close
                        context.getString(R.string.txt_not_set)
                    }

                    else -> {
                        menuType = ConstantInt.Close
                        context.getString(R.string.txt_outside)
                    }
                }
                if (it.powerSwitch == ConstantInt.Type0) menuType = ConstantInt.Close
                value = context.getString(R.string.txt_smart_power_zone) + "：$wifiZoneValue"
            }
            deviceStateList[3].apply {
                menuType =
                    if (isTimeoutReport || it.lteSignal == ConstantInt.NoSignal || it.powerSwitch == ConstantInt.Type0 || it.powerSwitch == ConstantInt.Type2) {
                        ConstantInt.Close
                        //                    state = -1
                        //                    value =
                        //                        String.format(context.getString(R.string.tracker_manage_set_battery), "--")
                        //                    name = "N/A"
                    } else {
                        if (it.batteryLevel > ConstantInt.LowBattery20) ConstantInt.Open
                        else ConstantInt.Close
                    }
                state = Utils.calculatePowerLevel(it.batteryLevel)
                value = String.format(
                    context.getString(R.string.tracker_manage_set_battery), "${it.batteryLevel}"
                )
                name = "${it.batteryLevel}%"
            }
        }
    }

    /**
     * 设置警告状态
     */
    private fun setWaringData(
        context: Context,
        mapDeviceBean: MapDeviceBean,
        deviceMsgList: MutableList<DataBean>,
        isLive: Boolean
    ) {
        mapDeviceBean.let {
            if (!isLive && it.inWifiZone == ConstantInt.Type1) {
                DataBean().apply {
                    value = context.getString(R.string.txt_in_power_zone)
                    state = ConstantInt.Type1
                    deviceMsgList.add(this)
                }
            } else if (it.batteryLevel <= ConstantInt.LowBattery10) {
                DataBean().apply {
                    value = String.format(context.getString(R.string.txt_battery_less_than), "10")
                    deviceMsgList.add(this)
                }
            } else if (it.batteryLevel <= ConstantInt.LowBattery20) {
                DataBean().apply {
                    value = String.format(context.getString(R.string.txt_battery_less_than), "20")
                    deviceMsgList.add(this)
                }
            } else if (it.batteryLevel <= ConstantInt.LowBattery30) {
                DataBean().apply {
                    value = String.format(context.getString(R.string.txt_battery_less_than), "30")
                    deviceMsgList.add(this)
                }
            } else if (it.gpsSignal <= ConstantInt.WeakSignal) {
                DataBean().apply {
                    value = context.getString(R.string.txt_weak_gps_signal)
                    deviceMsgList.add(this)
                }
            } else {
                if (!isLive) {
                    if (it.inNoGoZone == ConstantInt.BadZone) {
                        DataBean().apply {
                            value = context.getString(R.string.txt_in_no_go_zone)
                            deviceMsgList.add(this)
                        }
                    } else if (it.inSafeZone == ConstantInt.BadZone) {
                        DataBean().apply {
                            value = context.getString(R.string.txt_out_save_zone)
                            deviceMsgList.add(this)
                        }
                    }
//                    else if (it.inWifiZone == ConstantInt.Type0) {
//                        DataBean().apply {
//                            value = context.getString(R.string.txt_out_power_zone)
//                            deviceMsgList.add(this)
//                        }
//                    }
                    else {

                    }
                } else {

                }
            }
        }
    }

    fun setMapDeviceBattery(
        context: Context,
        mapDeviceBean: MapDeviceBean,
        rootView: ViewGroup,
        batteryText: TypefaceTextView,
        closeBtn: AppCompatImageView //可关闭按钮
    ) {
        mapDeviceBean.apply {
            if (isCloseBattery) return@apply
            batteryText.let {
                canShowBattery = true
                rootView.visibility = View.VISIBLE
                if (powerSwitch == ConstantInt.Type2) {
                    //R.drawable.icon_weak_gps_image
                    it.setCompoundDrawablesWithIntrinsicBounds(
                        R.drawable.icon_device_sleep_image, 0, 0, 0
                    )
                    it.text = String.format(
                        context.getString(R.string.txt_fell_asleep),
                        Utils.getTimeDifference(updateTime * 1000, System.currentTimeMillis())
                    )
                    ViewUtil.instance.viewShow(closeBtn)
                } else if (powerSwitch == ConstantInt.Type0) {
                    //连接蓝牙就不显示关机
                    if (SRBleUtil.instance.isMacConnect(deviceMacId)) {
                        rootView.visibility = View.INVISIBLE
                        canShowBattery = false
                    } else {
                        it.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0)
                        it.text = context.getString(R.string.txt_powered_off)
                        ViewUtil.instance.viewShow(closeBtn)
                    }
                } else if (powerSwitch == ConstantInt.Type3) {
                    val image = if (batteryLevel == 100) {
                        it.text = context.getString(R.string.txt_fully_charged)
                        R.drawable.icon_fully_charged_image
                    } else {
                        it.text = context.getString(R.string.txt_charging)
                        R.drawable.icon_charge_image
                    }
                    it.setCompoundDrawablesWithIntrinsicBounds(image, 0, 0, 0)
                    ViewUtil.instance.viewShow(closeBtn)
                } else if (batteryLevel <= ConstantInt.LowBattery20) {
                    val lowBattery =
                        if (batteryLevel <= ConstantInt.LowBattery10) ConstantInt.LowBattery10
                        else ConstantInt.LowBattery20
                    it.setCompoundDrawablesWithIntrinsicBounds(
                        R.drawable.icon_low_battery_image, 0, 0, 0
                    )
                    it.text = String.format(
                        context.getString(R.string.txt_battery_less_than), "$lowBattery"
                    )
                } else {
                    rootView.visibility = View.INVISIBLE
                    canShowBattery = false
                }
            }
        }
    }

    fun setPetLocationReverseGeocode(
        context: Context,
        mapDeviceBean: MapDeviceBean,
        rootView: ViewGroup,
        locationText: TypefaceTextView,
    ) {
        mapDeviceBean.apply {
            val imageResId = if (inWifiZone == ConstantInt.Type1) {
                rootView.background =
                    ContextCompat.getDrawable(context, R.drawable.shape16_light_green_color_bg)
                R.drawable.icon_wifi_image
            } else {
                rootView.background =
                    ContextCompat.getDrawable(context, R.drawable.shape16_white_color_bg)
                R.drawable.icon_wifi_image
                0
            }
            locationText.setCompoundDrawablesWithIntrinsicBounds(
                imageResId, 0, 0, 0
            )
        }
    }

    /**
     * 显示导航地图
     */
    fun showNavigationDialog(activity: BaseActivity<*>, mapDeviceBean: MapDeviceBean?) {
        mMapDeviceBean = mapDeviceBean
        if (null == mSelectMapListDialog) {
            val mapList = mutableListOf<MenuTxtBean>()
            ViewUtil.instance.addMenuBean(
                mapList,
                activity.getString(R.string.map_navigate_map_google),
                mMapGooglePackageName,
                R.drawable.ico_map_google
            )
            ViewUtil.instance.addMenuBean(
                mapList,
                activity.getString(R.string.map_navigate_map_gaode),
                mMapGaoDePackageName,
                R.drawable.ico_map_gaode
            )
            ViewUtil.instance.addMenuBean(
                mapList,
                activity.getString(R.string.map_baidu_map),
                mMapBaiduPackageName,
                R.drawable.ico_map_gaode
            )

            mSelectMapListDialogAdapter = SelectMapListDialogAdapter(activity, mapList).apply {
                setOnItemClickListener(object : BaseRecyclerAdapter.OnItemClickListener {
                    override fun onItemClick(itemView: View?, pos: Int) {
                        selectMapNavigation(activity, mapList[pos])
                    }
                })
            }
            mSelectMapListDialog = SelectMapListDialog(activity, mSelectMapListDialogAdapter!!)
        }
        mSelectMapListDialog?.show()
    }

    /**
     * 选择地图开始跳转
     */
    private fun selectMapNavigation(activity: BaseActivity<*>, item: MenuTxtBean) {
        mSelectMapListDialog?.dismiss()
        mMapDeviceBean?.apply {
            try {
                when (item.menuValue) {
                    //谷歌地图
                    mMapGooglePackageName -> {
                        var lat = latitude
                        var lon = longitude
                        if (MMKVUtil.getBoolean(MMKVKey.isGpsToGCJ02)) {
                            val convertLatLon =
                                LonAndLatUtil.convertFromWGS84ToGCJ02(latitude, longitude)
                            lat = convertLatLon[0]
                            lon = convertLatLon[1]
                        }
                        val uri = "google.navigation:q=${lat},${lon}&mode=w".toUri()
                        val intent = Intent(Intent.ACTION_VIEW, uri)
                        intent.setPackage(item.menuValue)
                        activity.startActivity(intent)
                    }
                    //高德地图 https://lbs.amap.com/api/amap-mobile/guide/android/walk-navi
                    mMapGaoDePackageName -> {
                        val uri = "amapuri://openFeature?featureName=OnFootNavi&sourceApplication=${
                            activity.getString(
                                R.string.app_name
                            )
                        }&lat=${latitude}&lon=${longitude}&dev=1".toUri()
                        val intent = Intent(Intent.ACTION_VIEW, uri)
                        intent.setPackage(item.menuValue)
                        activity.startActivity(intent)
                    }
                    //百度地图 https://lbs.baidu.com/docs/webapi?title=mapadjustment/uri/andriod
                    mMapBaiduPackageName -> {
                        val uri =
                            "baidumap://map/direction?destination=name:|latlng:${latitude},${longitude}&mode=walking&coord_type=wgs84".toUri()
                        val intent = Intent(Intent.ACTION_VIEW, uri)
                        intent.setPackage(item.menuValue)
                        activity.startActivity(intent)
                    }
                }
            } catch (e: Exception) {
                activity.showToast(
                    activity.getString(R.string.txt_no_install), gravity = Gravity.CENTER
                )
            }
        }
    }


    /**
     * 停止获取数据
     */
    fun stopGetData() {
        if (null != mCountDownTimer) {
            mCountDownTimer!!.cancel()
            mCountDownTimer = null
        }
    }

    override fun onCleared() {
        super.onCleared()
        stopGetData()
    }
}