package com.module.backstage.vm

import android.util.Log
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.MutableLiveData
import com.hboxs.serialport.plc.message.Message
import com.hboxs.serialport.plc.thread.ThreadDebugParamParam
import com.hboxs.serialport.plc.util.HexUtils
import com.hboxs.serialport.plc.util.HexadecimalUtil
import com.hboxs.serialport.sbc.SBCHeartbeat
import com.hboxs.serialport.sbc.VBoxMessage
import com.hboxs.serialport.sbc.frame.VboxCommand
import com.module.backstage.R
import com.module.backstage.repo.DebugParamFragmentRepo
import com.quyunshuo.androidbaseframemvvm.base.addressenum.PlcDebugAddressEnum
import com.quyunshuo.androidbaseframemvvm.base.addressenum.PlcDebugStataAddressEnum
import com.quyunshuo.androidbaseframemvvm.base.mvvm.vm.BaseViewModel
import com.quyunshuo.androidbaseframemvvm.common.util.ToastUtil
import com.quyunshuo.androidbaseframemvvm.common.util.UiUtil
import dagger.hilt.android.lifecycle.HiltViewModel
import java.util.Arrays
import javax.inject.Inject

/**
 * HomeFragment 的 VM 层
 *
 * @author Qu Yunshuo
 * @since 2021/8/5 11:11 下午
 */
@HiltViewModel//@HiltViewModel 注解的作用是将 ViewModel 标记为可以由 Hilt 管理的依赖项。当你将 @HiltViewModel 注解添加到 ViewModel 类上时，Hilt 会自动处理 ViewModel 的创建和注入过程。这样，你就不需要手动调用 ViewModelProvider 来获取 ViewModel 实例了。
class DebugParamFragmentVM @Inject constructor(private val mRepo: DebugParamFragmentRepo) :
    BaseViewModel() {
    private val TAG = "DebugParamFragmentVM"
    private var threadDebugParamParam = ThreadDebugParamParam()

    //读取到的数据
    private var _paramDataListM228 = MutableLiveData<List<String>>()
    val paramDataListM228: MutableLiveData<List<String>> get() = _paramDataListM228

    private var _paramDataListM111 = MutableLiveData<List<String>>()
    val paramDataListM111: MutableLiveData<List<String>> get() = _paramDataListM111


    private var _paramDataListM166 = MutableLiveData<List<String>>()
    val paramDataListM166: MutableLiveData<List<String>> get() = _paramDataListM166


    private var _paramDataListM178 = MutableLiveData<List<String>>()
    val paramDataListM178: MutableLiveData<List<String>> get() = _paramDataListM178

    private var _paramDataListM198 = MutableLiveData<List<String>>()
    val paramDataListM198: MutableLiveData<List<String>> get() = _paramDataListM198


    private var _paramDataListM208 = MutableLiveData<List<String>>()
    val paramDataListM208: MutableLiveData<List<String>> get() = _paramDataListM208
    private var _paramDataListM218 = MutableLiveData<List<String>>()
    val paramDataListM218: MutableLiveData<List<String>> get() = _paramDataListM218

    private var _paramDataListM171 = MutableLiveData<List<String>>()
    val paramDataListM171: MutableLiveData<List<String>> get() = _paramDataListM171
    var _data1 = MutableLiveData<List<String>>()
    val data1: MutableLiveData<List<String>> get() = _data1
    var allData = ""
    var stataData = ""

    public var _paramDataMap = mutableMapOf<String, String>()
        get() = field

    private val _refreshPage = MutableLiveData<MutableList<String>>();
    val refreshPage: MutableLiveData<MutableList<String>> get() = _refreshPage

    private val _refreshStataPage = MutableLiveData<List<String>>();
    val refreshStataPage: MutableLiveData<List<String>> get() = _refreshStataPage


    var lutouC = MutableLiveData<String>()

    /**
     * 获取文章数据
     */
    fun getArticleData() {

    }

    fun getDebugParamData(): MutableList<PlcDebugAddressEnum> {
        return mRepo.arrayList
    }


    fun getDebugStataParamData(): MutableList<PlcDebugStataAddressEnum> {
        return mRepo.arraystataList
    }

    fun getThreadDebugParamParam(): LifecycleObserver {
        return threadDebugParamParam
    }

    fun ack(messageEvent: Message) {
        val isContain = PlcDebugAddressEnum.valueOf(messageEvent.name) ?: return
        ToastUtil.switchToastStyleToSuccess(UiUtil.getStringRes(R.string.base_backstage_update_success))
        threadDebugParamParam.jobSetBtn?.cancel()
        threadDebugParamParam.jobRstBtn?.cancel()

    }


    private fun M228(hex: String) {
        //    转成2进制
        val s = HexadecimalUtil.hexStringToByte(hex)
        //翻转后的数据
        val s1 = HexadecimalUtil.flipString(s, 8)
        val stringBuilder = StringBuilder(s1)
        val lis = Arrays.asList(
            *stringBuilder.reverse().toString().split("".toRegex()).dropLastWhile { it.isEmpty() }
                .toTypedArray())
        val list: ArrayList<String> = ArrayList(lis)
        list.removeAt(0)
        Log.d(TAG, "M228: " + list)
        _paramDataListM228.value = list
    }

    private fun M218(hex: String) {
        //    转成2进制
        val s = HexadecimalUtil.hexStringToByte(hex)
        //翻转后的数据
//        val s1 = HexadecimalUtil.flipString(s, 8)
        val stringBuilder = StringBuilder(s)
        val lis = Arrays.asList(
            *stringBuilder.reverse().toString().split("".toRegex()).dropLastWhile { it.isEmpty() }
                .toTypedArray())
        val list: ArrayList<String> = ArrayList(lis)
        list.removeAt(0)
        Log.d(TAG, "M218: " + list)
        _paramDataListM218.value = list
    }

    private fun M208(hex: String) {
        //    转成2进制
        val s = HexadecimalUtil.hexStringToByte(hex)
        //翻转后的数据
//        val s1 = HexadecimalUtil.flipString(s, 8)
        val stringBuilder = StringBuilder(s)
        val lis = Arrays.asList(
            *stringBuilder.reverse().toString().split("".toRegex()).dropLastWhile { it.isEmpty() }
                .toTypedArray())
        val list: ArrayList<String> = ArrayList(lis)
        list.removeAt(0)
        Log.d(TAG, "M208: " + list)
        _paramDataListM208.value = list
    }

    private fun M198(hex: String) {
        //    转成2进制
        val s = HexadecimalUtil.hexStringToByte(hex)
        //翻转后的数据
        val s1 = HexadecimalUtil.flipString(s, 8)
        val stringBuilder = StringBuilder(s1)
        val lis = Arrays.asList(
            *stringBuilder.reverse().toString().split("".toRegex()).dropLastWhile { it.isEmpty() }
                .toTypedArray())
        val list: ArrayList<String> = ArrayList(lis)
        list.removeAt(0)
        Log.d(TAG, "M198: " + list)
        _paramDataListM198.value = list
    }

    private fun M178(hex: String) {
        //    转成2进制
        val s = HexadecimalUtil.hexStringToByte(hex)
        //翻转后的数据
        val s1 = HexadecimalUtil.flipString(s, 8)
        val lis = Arrays.asList(*s1.split("".toRegex()).dropLastWhile { it.isEmpty() }
            .toTypedArray())
        val list: ArrayList<String> = ArrayList(lis)
        list.removeAt(0)
        Log.d(TAG, "M178: " + list)
        _paramDataListM178.value = list
    }

    private fun M171(hex: String) {
        //    转成2进制
        val s = HexadecimalUtil.hexStringToByte(hex)
        //翻转后的数据
        val s1 = HexadecimalUtil.flipString(s, 8)
        val lis = Arrays.asList(*s1.split("".toRegex()).dropLastWhile { it.isEmpty() }
            .toTypedArray())
        val list: ArrayList<String> = ArrayList(lis)
        list.removeAt(0)
        Log.d(TAG, "M171: " + list)
        _paramDataListM171.value = list
    }

    private fun M166(hex: String) {
        //    转成2进制
        val s = HexadecimalUtil.hexStringToByte(hex)
        //翻转后的数据
        val s1 = HexadecimalUtil.flipString(s, 8)
        val stringBuilder = StringBuilder(s1)
        val lis = Arrays.asList(
            *stringBuilder.reverse().toString().split("".toRegex()).dropLastWhile { it.isEmpty() }
                .toTypedArray())
        val list: ArrayList<String> = ArrayList(lis)
        list.removeAt(0)
        Log.d(TAG, "M166: " + list)
        _paramDataListM166.value = list
    }

    private fun M111(hex: String) {
        //    转成2进制
        val s = HexadecimalUtil.hexStringToByte(hex)
        //翻转后的数据
        val s1 = HexadecimalUtil.flipString(s, 8)
        val lis = Arrays.asList(*s1.split("".toRegex()).dropLastWhile { it.isEmpty() }
            .toTypedArray())
        val list: ArrayList<String> = ArrayList(lis)
        list.removeAt(0)
        Log.d(TAG, "M111: " + list)
        _paramDataListM111.value = list

    }

    //按鈕置位复位
    fun setBtnParam(data: String, checked: Boolean, position: Int) {
        //   val plcDebugAddressEnum: PlcDebugAddressEnum = mRepo.arrayList.get(position)
        //Log.d(TAG, "setBtnParam: "+plcDebugAddressEnum.aName+":"+plcDebugAddressEnum.address+":"+checked)
        Log.d("backinfo", "ssssssssssssssssssssssssss:" + data)
        if (checked) {
            threadDebugParamParam.setBtn(data)
        } else {
            threadDebugParamParam.rstBtn(data)

        }
    }

    fun setLutou(data: String, checked: Boolean, type: Int) {
        threadDebugParamParam.lutou(data, checked, type)
    }

    fun openClean(data: String, checked: Boolean) {
        threadDebugParamParam.openClean(data, checked)
    }

    fun stuck(data: String) {
        Log.d("backinfo", "炉头卡死测试：" + data)
        threadDebugParamParam.stuck(data)
    }

    fun xReset(data: String) {
        threadDebugParamParam.xReset(data)
    }

    fun disposeData(messageEvent: VBoxMessage) {
        when (messageEvent.cmd) {
            VboxCommand.CMD_HEARTBEAT -> {
                Log.d("backinfo", "心跳包数据：" + messageEvent.data)
                cmdHeartbeat(messageEvent)
            }

            VboxCommand.CMD_IO -> {
                // cmdHeartbeat(messageEvent)
            }
        }

    }


    private fun cmdHeartbeat(messageEvent: VBoxMessage) {

        val data1 = messageEvent.data.substring(52, 58)//高电平激活
        val statadata = messageEvent.data.substring(58, 62)//主核IO输入状态信息
        val pwm1 = messageEvent.data.substring(62, 64)//炉头状态
        val clean = messageEvent.data.substring(70, 72)
        val hexStr2BinStr = HexUtils.hexStr2BinStr(data1)
        lutouC.postValue(SBCHeartbeat.headTemp + "°C")
        Log.d("backinfo", "pwm1:" + pwm1)
        Log.d("backinfo", "clean:" + clean)
        val pwm12BinStr = HexUtils.hexStr2BinStr(pwm1)
        val clean2BinStr = HexUtils.hexStr2BinStr(clean)
        if (!checkAndUpdate(allData, hexStr2BinStr, pwm12BinStr)) {
            allData = hexStr2BinStr + pwm12BinStr
            val mutableList: MutableList<String> = mutableListOf()
            Log.d("backinfo", "allData:" + allData)
            val setioList = getList(hexStr2BinStr)
            val getCleanList = getList(clean2BinStr)
            mutableList.addAll(setioList)
            mutableList.add(pwm1)
            mutableList.add(getCleanList.get(0))//炉头清洗
            _refreshPage.value = mutableList
        }

        val statadataBinStr = HexUtils.hexStr2BinStr(statadata)
        if (!checkAndUpdate(stataData, statadataBinStr)) {
            stataData = statadataBinStr
            val split = stataData.split("")//3位字节转成16进制得到24个状态
            val inputioList = split.subList(1, split.size - 1)
            _refreshStataPage.value = inputioList
        }
//       /* Log.d("debug","messageEvent.data:"+messageEvent.data)
//        //调试页的内容
//        val data = messageEvent.data.substring(26,32)
//
//        val hexStr2BinStr = HexUtils.hexStr2BinStr(data)
//        val split = hexStr2BinStr.split("")
//        _paramDataMap.clear()
//        for ((index, plcDebugAddressEnum) in mRepo.arrayList.withIndex()) {
//            _paramDataMap[plcDebugAddressEnum.address] = split[index+1]
//        }
//        _refreshPage.value = true*/
    }

    fun getList(data: String): MutableList<String> {
        val split = data.split("")//3位字节转成16进制得到24个状态
        var setioList = split.subList(1, split.size - 1).toMutableList()
        return setioList
    }

    fun checkAndUpdate(original: String, vararg parts: String): Boolean {
        var original = original
        val builder = StringBuilder()
        for (s in parts) {
            builder.append(s)
        }

        if (original == builder.toString()) {
            return true
        } else {
            return false
        }
    }
}