package com.module.backstage.activity.setting

import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.google.gson.Gson
import com.hboxs.serialport.plc.message.Message
import com.hboxs.serialport.plc.thread.ThreadSettingParam
import com.hboxs.serialport.sbc.SBCHeartbeat
import com.hboxs.serialport.sbc.VBoxMessage
import com.hboxs.serialport.sbc.frame.VboxCommand
import com.module.backstage.model.ApkInfoBean
import com.quyunshuo.androidbaseframemvvm.base.BaseApplication
import com.quyunshuo.androidbaseframemvvm.base.addressenum.PlcSettingAddressEnum
import com.quyunshuo.androidbaseframemvvm.base.ktx.launchIO
import com.quyunshuo.androidbaseframemvvm.base.mvvm.vm.BaseViewModel
import com.quyunshuo.androidbaseframemvvm.base.utils.SpUtils
import com.quyunshuo.androidbaseframemvvm.common.constant.Heartbeat
import com.quyunshuo.androidbaseframemvvm.common.constant.MMKVName
import com.quyunshuo.androidbaseframemvvm.common.enums.ConnectStateEnum
import com.quyunshuo.androidbaseframemvvm.common.util.ToastUtil
import com.quyunshuo.androidbaseframemvvm.common.util.XLogUtil
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * 首页的VM层
 *
 * @property mRepo HomeRepository 仓库层 通过Hilt注入
 *
 * @author Qu Yunshuo
 * @since 5/25/21 5:41 PM
 */
@HiltViewModel
class SettingViewModel @Inject constructor(private val mRepo: SettingRepository) : BaseViewModel() {
    private val TAG = "SettingViewModel"
    val data = MutableLiveData<String>()

    @Inject
    lateinit var threadSettingParam: ThreadSettingParam

    private var _isM3Success = MutableLiveData<Boolean>()//
    val isM3Success: LiveData<Boolean> get() = _isM3Success

    private var _connectState = MutableLiveData<String>()
    val connectState: LiveData<String> get() = _connectState

    private var _apkInfo = MutableLiveData<ApkInfoBean>()
    val apkInfo: LiveData<ApkInfoBean> get() = _apkInfo


    private val _powerOn = MutableLiveData<Boolean>()
    val powerOn: LiveData<Boolean> get() = _powerOn

    private val _powerOncomplete = MutableLiveData<Boolean>()
    val powerOncomplete: LiveData<Boolean> get() = _powerOncomplete

    /**
     * 模拟获取数据
     */
    fun getData() {
        launchIO {
            mRepo.getData()
                .catch { Log.d("qqq", "getData: $it") }
                .collect { data.postValue(it) }
        }
    }

    fun ack(messageEvent: Message) {
        val name = messageEvent.name
        Log.d(TAG, "ack: " + name)
        when (name) {
            PlcSettingAddressEnum.M3.address -> {
                threadSettingParam.stopSetM3()
                _isM3Success.value = true
                viewModelScope.launch {
                    delay(3000)
                    threadSettingParam.startRstM3()
                }
            }

            PlcSettingAddressEnum.RM3.address -> {
                threadSettingParam.stopRstM3()
            }

            else -> {}
        }

    }

    fun response(messageEvent: Message) {

    }

    fun initDev(text: String?) {
        if (Heartbeat.clientId == null || Heartbeat.clientId == "") {
            ToastUtil.switchToastStyleToWarn("id获取失败，请重试")
            return
        }
        //连接服务器
        viewModelScope.launch(Dispatchers.IO) {
            mRepo.initDev(text).catch {
                Log.d(TAG, "initDev onerror: " + it)
            }.collect {
                CoroutineScope(Dispatchers.Main).launch {
                    Log.d(TAG, "initDev onnext: " + it)
                    initDevSuccess(it)
                }

            }
        }

    }

    fun getApkinfo() {
        //连接服务器
        viewModelScope.launch(Dispatchers.IO) {
            mRepo.apkinfo().catch {
                Log.d(TAG, "apkinfo onerror: " + it)
            }.collect {
                CoroutineScope(Dispatchers.Main).launch {
                    Log.d(TAG, "apkinfo onnext: " + it)
                    apkInfoSuccess(it)
//                    initDevSuccess(it)
                }

            }
        }
    }


    private fun apkInfoSuccess(result: String) {
        var gson: Gson = Gson()
        val apkInfoBean = gson.fromJson(result, ApkInfoBean::class.java)
        //当前版本号
        val versionCode = getVersionCode()
        Log.d(TAG,"versionCode:"+versionCode)
        //下载的版本号
        val version: Int = apkInfoBean.version
       /* if (versionCode > version) {
            //当前版本号小于等于下载的版本号，则不提示更新
            Log.d(
                TAG,
                "apkInfoSuccess: 当前版本号小于等于下载的版本号" + versionCode + ":" + version
            )
        } else {
            //当前版本号大于下载的版本号，则要提示更新
            Log.d(TAG, "apkInfoSuccess: 当前版本号大于下载的版本号")
            _apkInfo.value = apkInfoBean

        }*/
        if (versionCode<version){
            _apkInfo.value = apkInfoBean
        }
    }


    private fun initDevSuccess(result: String) {
        /*
            这里的逻辑：
            1. 情况一：显示连接中，等待后台审核【提示客户】，还有后续。
            2. 情况二：设备没有脱离，就显示设备没有脱离【提示客户】就结束了。-----------
            3. 情况三：找不到商家，就显示找不到商家【提示客户】就结束了。-----------
            4. 情况四：生产部未录入改设备的位置信息，就显示生产部未录入改设备的位置信息【提示客户】就结束了------------
            5. 情况五：设备已经初始化【提示客户】，并且要记录已经连接成功了。
         */

        if (result == "设备申请中，请耐心等待") {
            ToastUtil.switchToastStyleToSuccess(result)
            SpUtils.putString(MMKVName.CONNECT_STATE, ConnectStateEnum.CONNECTING.name)
            connecting(ConnectStateEnum.CONNECTING.name)
        } else if (result == "该设备未脱离") {
            ToastUtil.switchToastStyleToError(result)
            SpUtils.putString(MMKVName.CONNECT_STATE, ConnectStateEnum.DISCONNECTED.name)
            disconnected()
        } else if (result == "找不到商家") {
            ToastUtil.switchToastStyleToError(result)
            SpUtils.putString(MMKVName.CONNECT_STATE, ConnectStateEnum.DISCONNECTED.name)
            disconnected()
        } else if (result == "生产部未录入改设备的位置信息") {
            ToastUtil.switchToastStyleToError(result)
            SpUtils.putString(MMKVName.CONNECT_STATE, ConnectStateEnum.DISCONNECTED.name)
            disconnected()
        } else if (result == "该设备已经初始化" || result.equals("设备申请成功")) {
            SpUtils.putString(MMKVName.MANAGER_ID, Heartbeat.managerId!!)
            ToastUtil.switchToastStyleToSuccess(result)
            SpUtils.putString(MMKVName.CONNECT_STATE, ConnectStateEnum.CONNECTED.name)
            connected(ConnectStateEnum.CONNECTED.name)
        }

    }

    /**
     * 连接中的处理
     */
    private fun connecting(data: String) {
        //通知前台连接发起修改一下名称
        _connectState.value = data
    }

    /**
     * 连接断开的处理
     */
    private fun disconnected() {
        //通知前台连接发起修改一下名称

    }

    /**
     * 连接成功的处理
     */
    private fun connected(data: String) {

        _connectState.value = data
    }


    /*
     * 获取当前程序的版本号
     */
    private fun getVersionCode(): Int {
        //获取packagemanager的实例
        val packageManager: PackageManager = BaseApplication.context.packageManager
        //getPackageName()是你当前类的包名，0代表是获取版本信息
        var packInfo: PackageInfo? = null
        try {
            packInfo = packageManager.getPackageInfo(BaseApplication.context.packageName, 0)
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
        }
        Log.e("TAG", "版本号" + packInfo!!.versionCode)
        Log.e("TAG", "版本名" + packInfo.versionName)
        return packInfo.versionCode
    }

    /*
    * 获取当前程序的版本号
    */
    public fun getVersionName(): String {
        //获取packagemanager的实例
        val packageManager: PackageManager = BaseApplication.context.packageManager
        //getPackageName()是你当前类的包名，0代表是获取版本信息
        var packInfo: PackageInfo? = null
        try {
            packInfo = packageManager.getPackageInfo(BaseApplication.context.packageName, 0)
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
        }
        Log.e("TAG", "版本号" + packInfo!!.versionCode)
        Log.e("TAG", "版本名" + packInfo.versionName)
        return packInfo.versionName
    }

    fun disposeData(messageEvent: VBoxMessage) {
        when (messageEvent.cmd) {

            VboxCommand.CMD_HEARTBEAT -> {
                Log.d("settingview","HEARTBEAT:"+messageEvent.data)
                if (SBCHeartbeat.devCode.startsWith("01")) {
                 //   _powerOncomplete.value = true
                    threadSettingParam.stopSetM3()
                } else if (SBCHeartbeat.devCode.startsWith("02")) {
                 //   _powerOncomplete.value = true
                    threadSettingParam.stopSetM3()

                }
            }

            else -> {}
        }
        //  XLogUtil.d(messageEvent.cmd + ":messageEvent.data11111:" + messageEvent.data)
        //  XLogUtil.d(messageEvent.cmd + ":messageEvent.dataSBCHeartbeat.devCode:" + SBCHeartbeat.devCode)

    }

}