package com.abbidot.tracker.vm

import android.app.Application
import android.content.Context
import android.os.Build
import android.text.TextUtils
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.tracker.R
import com.abbidot.tracker.bean.DFUStateBean
import com.abbidot.tracker.bean.FirmwareBean
import com.abbidot.tracker.retrofit2.NetworkApi
import com.abbidot.tracker.service.DfuService
import com.abbidot.tracker.util.bluetooth.SRBleUtil
import com.clj.fastble.BleManager
import com.clj.fastble.callback.BleScanCallback
import com.clj.fastble.data.BleDevice
import com.clj.fastble.data.BleScanState
import com.clj.fastble.scan.BleScanRuleConfig
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import no.nordicsemi.android.dfu.DfuProgressListener
import no.nordicsemi.android.dfu.DfuServiceInitiator

/**
 *Created  by .yzq on 2023/3/16/016.
 * @link
 * @description:
 */
class DeviceDFUViewModel(application: Application) : AndroidViewModel(application) {

    val mFirmwareInfoLiveData = MutableLiveData<Result<FirmwareBean>>()
    val mDfuStateLiveData = MutableLiveData<DFUStateBean>()

    //dfu成功
    val mDFUSuccessCode = 101

    //dfu失败
    val mDFUFailCode = -2

    //记下更新时间，不用频繁更新
    private var mUpdatePostTimeMillis = System.currentTimeMillis()


    /**
     * 获取固件信息
     */
    fun getFirmware() {
//        activity.showLoading(isShowLoading)
        viewModelScope.launch(Dispatchers.IO) {
            val result = NetworkApi.getFirmware("GPS_Tracker_01")
            mFirmwareInfoLiveData.postValue(result)
        }
    }

    /**
     * 对比版本号是否可以更新
     */
    fun checkVersionUpdate(localVersion: String, serviceVersion: String): Boolean {
        if (TextUtils.isEmpty(localVersion)) return false
        val localVersionInt = (localVersion.replace(".", "").substring(1, 4)).toInt()
        val serviceVersionInt = serviceVersion.replace(".", "").toInt()
        LogUtil.e("对比固件版本localVersionInt=$localVersionInt,serviceVersionInt=$serviceVersionInt")
        return serviceVersionInt > localVersionInt
    }

    fun startDFU(context: Context, device: BleDevice, path: String) {
        viewModelScope.launch {
            val dFUStateBean = DFUStateBean(context.getString(R.string.txt_dfu_model))
            mDfuStateLiveData.value = dFUStateBean
            //是否扫描到
            var isScan = false
            val dfuCmd = byteArrayOf(0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66)
            SRBleUtil.instance.writeData(device, dfuCmd)
            if (BleScanState.STATE_IDLE != BleManager.getInstance().scanSate) BleManager.getInstance()
                .cancelScan()
            // 扫描超时时间，可选，默认10秒
            val scanRuleConfig = BleScanRuleConfig.Builder().setScanTimeOut(60000).build()
            BleManager.getInstance().initScanRule(scanRuleConfig)
            BleManager.getInstance().scan(object : BleScanCallback() {
                override fun onScanStarted(success: Boolean) {
                    val stateBean = DFUStateBean(context.getString(R.string.txt_search_dfu))
                    mDfuStateLiveData.value = stateBean
                    LogUtil.e("开始搜索DUF设备。。。。")
                }

                override fun onScanning(bleDevice: BleDevice?) {
                    bleDevice?.apply {
                        LogUtil.e("搜索DUF设备中。。。已搜索到$name")
                        val deviceDFUName = "DfuTarg"
//                        val deviceDFUName = "xxx"
                        if (!TextUtils.isEmpty(name) && name.contains(deviceDFUName)) {
                            isScan = true
                            BleManager.getInstance().cancelScan()
                            dfu(context, bleDevice, path)
                        }
                    }
                }

                override fun onScanFinished(scanResultList: MutableList<BleDevice>?) {
                    LogUtil.e("搜索DUF设备结束。")
                    if (!isScan) {
                        val stateBean =
                            DFUStateBean(context.getString(R.string.txt_no_dfu), mDFUFailCode)
                        mDfuStateLiveData.value = stateBean
                    }
                }
            })
        }
    }


    private fun dfu(context: Context, bleDevice: BleDevice, path: String) {
        val dfuServiceInitiator = DfuServiceInitiator(bleDevice.mac)
        dfuServiceInitiator.setDeviceName(bleDevice.name)
        dfuServiceInitiator.setKeepBond(false).setPacketsReceiptNotificationsEnabled(false)
            .setPacketsReceiptNotificationsValue(10)
            .setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true).setZip(path)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //Android O,通知栏问题
            DfuServiceInitiator.createDfuNotificationChannel(context)
        }
        dfuServiceInitiator.start(context, DfuService::class.java)
    }

    val mDfuProgressListener = object : DfuProgressListener {

        private val context = getApplication<Application>()

        /**设备正在连接 */
        override fun onDeviceConnecting(deviress: String) {
            val stateBean = DFUStateBean(context.getString(R.string.txt_connect_device))
            mDfuStateLiveData.value = stateBean
            LogUtil.e("DfuProgressListener -->>  onDeviceConnecting,dfu开始连接设备")
        }

        /**
         * 设备连接了  1
         * @param deviceAddress
         */
        override fun onDeviceConnected(deviceAddress: String) {
            val stateBean = DFUStateBean(context.getString(R.string.txt_device_connect_success))
            mDfuStateLiveData.value = stateBean
            LogUtil.e("DfuProgressListener -->> dfu连接设备成功 onDeviceConnected")
        }

        /**升级准备开始
         * 2
         */
        override fun onDfuProcessStarting(deviceAddress: String) {
            val stateBean = DFUStateBean(context.getString(R.string.txt_upgrade_start))
            mDfuStateLiveData.value = stateBean
            LogUtil.e("DfuProgressListener -->>  onDfuProcessStarting")
        }

        /**更新进度开始
         * 3
         */
        override fun onDfuProcessStarted(deviceAddress: String) {
            LogUtil.e("DfuProgressListener -->>  onDfuProcessStarted")
        }

        override fun onEnablingDfuMode(deviceAddress: String) {
            LogUtil.e("DfuProgressListener -->>  onEnablingDfuMode")
        }

        /**升级中的回调 */
        override fun onProgressChanged(
            deviceAddress: String,
            percent: Int,
            speed: Float,
            avgSpeed: Float,
            currentPart: Int,
            partsTotal: Int
        ) {
            val currentTimeMillis = System.currentTimeMillis()
            //500ms更新发送数据，不用频繁更新
            if (currentTimeMillis - mUpdatePostTimeMillis > 500 || percent == 100) {
                mUpdatePostTimeMillis = currentTimeMillis
                val dFUStateBean =
                    DFUStateBean(context.getString(R.string.txt_upgrading) + " ", percent)
                mDfuStateLiveData.value = dFUStateBean
            }
        }

        /**固件验证-未用 */
        override fun onFirmwareValidating(deviceAddress: String) {
            LogUtil.e("DfuProgressListener -->>  onFirmwareValidating")
        }

        /**设备正在断开
         * 4
         */
        override fun onDeviceDisconnecting(deviceAddress: String) {
            val dFUStateBean = DFUStateBean(context.getString(R.string.txt_unconnect_no))
            mDfuStateLiveData.value = dFUStateBean
            LogUtil.e("DfuProgressListener -->>  onDeviceDisconnecting")
        }

        /**设备断开了
         * 5
         */
        override fun onDeviceDisconnected(deviceAddress: String) {
            val stateBean = DFUStateBean(context.getString(R.string.txt_unconnect))
            mDfuStateLiveData.value = stateBean
            LogUtil.e("DfuProgressListener -->>  onDeviceDisconnected")
        }

        /**升级完成
         * 6
         */
        override fun onDfuCompleted(deviceAddress: String) {
            val stateBean = DFUStateBean(context.getString(R.string.txt_upgrade_success))
            mDfuStateLiveData.value = stateBean
            LogUtil.e("DfuProgressListener -->>  onDfuCompleted")
            val state =
                DFUStateBean(context.getString(R.string.txt_reconnect_device), mDFUSuccessCode)
            mDfuStateLiveData.value = state
        }

        override fun onDfuAborted(deviceAddress: String) {
            LogUtil.e("DfuProgressListener -->>  onDfuAborted")
        }

        /**升级失败 */
        override fun onError(deviceAddress: String, error: Int, errorType: Int, message: String) {
            LogUtil.e("DfuProgressListener -->>  onError")
            val stateBean = DFUStateBean(context.getString(R.string.txt_upgrade_fail), mDFUFailCode)
            mDfuStateLiveData.value = stateBean
        }
    }
}