package com.sixin.module_p.ui.gnc.shouyun.add

import android.app.Activity
import android.bluetooth.BluetoothAdapter
import android.content.Intent
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.observe
import androidx.lifecycle.viewModelScope
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.GncShouYunBean
import com.lukouguoji.module_base.bean.ShouYunSyncBean
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.common.DetailsPageType
import com.lukouguoji.module_base.db.perference.SharedPreferenceUtil
import com.lukouguoji.module_base.http.net.DiBangWeightModel
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.ktx.getLifecycleOwner
import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.launchLoadingCollect
import com.lukouguoji.module_base.ktx.limit
import com.lukouguoji.module_base.ktx.loge
import com.lukouguoji.module_base.ktx.noNull
import com.lukouguoji.module_base.ktx.showConfirmDialog
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toJson
import com.lukouguoji.module_base.ktx.toRequestBody
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import com.lukouguoji.module_base.model.BluetoothDialogModel
import com.lukouguoji.module_base.model.ScanModel
import com.lukouguoji.module_base.util.DictUtils
import com.lukouguoji.module_base.util.PrinterUtils
import com.sixin.module_p.ui.gnc.shouyun.dialog.GncPdaShouYunSyncDialogModel
import dev.DevUtils
import dev.utils.app.info.KeyValue
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import okhttp3.RequestBody
import kotlin.math.abs
import kotlin.math.roundToInt

class PdaShouYunAddViewModel : BaseViewModel() {

    val pageType = MutableLiveData(DetailsPageType.Add)

    // 通道
    val channel = MutableLiveData("")

    // 重量
    val showWeightEdit = MutableLiveData(false)

    // 通道列表
    val passageList = MutableLiveData(listOf(KeyValue("通道1", "001"))).apply {
        DictUtils.getChannelList {
            value = it
        }
    }

    // 代理人列表
    val agentList = MutableLiveData(emptyList<KeyValue>()).apply {
        DictUtils.getGncAgentList(addAll = false) {
            value = listOf(KeyValue("", "")) + it
        }
    }

    // 特码列表
    val spCodeList = MutableLiveData(emptyList<KeyValue>()).apply {
        DictUtils.getSpecialCodeList(addAll = false) {
            value = listOf(KeyValue("", "")) + it
        }
    }

    // 业务类型列表
    val businessTypeList = MutableLiveData(emptyList<KeyValue>()).apply {
        DictUtils.getBusinessTypeList(type = "CO", addAll = false) {
            value = listOf(KeyValue("", "")) + it
        }
    }

    // 危险品库列表
    val dangerousGoodsList = MutableLiveData(emptyList<KeyValue>()).apply {
        DictUtils.getWxKuList {
            value = listOf(KeyValue("", "")) + it
        }
    }

    // 危险品描述
    val dangerousGoodsDescList = MutableLiveData(emptyList<KeyValue>()).apply {
        DictUtils.getWxDescListValue {
            value = listOf(KeyValue("", "")) + it
        }
    }

    // 包装类型
    val packageTypeList =  MutableLiveData(emptyList<KeyValue>()).apply {
        DictUtils.getShouYunPackageTypeList {
            value = listOf(KeyValue("", "")) + it
        }
    }

    val dataBean = MutableLiveData(GncShouYunBean())

    val print = MutableLiveData(true)


    val diBangModel = DiBangWeightModel()

    ///////////////////////////////////////////////////////////////////////////
    // 方法区
    ///////////////////////////////////////////////////////////////////////////

    fun init(intent: Intent) {
        dataBean.value!!.wbNo = intent.getStringExtra(Constant.Key.WAYBILL) ?: ""
        pageType.value =
            if (dataBean.value!!.wbNo.isEmpty()) DetailsPageType.Add else DetailsPageType.Modify

        getDetails()

        // 监听重量改变
        diBangModel.weight.observe(getTopActivity() as LifecycleOwner) {
            if (it.isNotEmpty()) {
                dataBean.value?.weight = it
            }
        }
        channel.observe(getTopActivity() as LifecycleOwner) {
            diBangModel.key = it
        }

        // 监听扫描信息
        FlowBus.with<String>(ConstantEvent.SCAN_CODE_RESULT)
            .onEach {
                if (it.length == 11) {
                    dataBean.value!!.wbNo = it
                    getDetails()
                } else {
                    dataBean.value!!.carNo = it
                    getCarInfo()
                }
            }
            .launchIn(viewModelScope)
    }

    fun onPassageSelected(position: Int) {
        channel.value = passageList.value!!.getOrNull(position)?.value ?: ""
    }

    fun onAgentSelected(position: Int) {
        dataBean.value!!.agentCode = agentList.value!!.getOrNull(position)?.value ?: ""
    }

    fun onSpCodeSelected(position: Int) {
        dataBean.value!!.spCode = spCodeList.value!!.getOrNull(position)?.value ?: ""
    }

    fun onBusinessTypeSelected(position: Int) {
        dataBean.value!!.businessType = businessTypeList.value!!.getOrNull(position)?.value ?: ""
    }

    fun onDangerousGoodsSelected(position: Int) {
        dataBean.value!!.dgrLocation = dangerousGoodsList.value!!.getOrNull(position)?.value ?: ""
    }

    fun onDangerousGoodsDescSelected(position: Int) {
        dataBean.value!!.dgrDetail = dangerousGoodsDescList.value!!.getOrNull(position)?.value ?: ""
    }

    fun onPackageTypeSelected(position: Int) {
        dataBean.value!!.packageType = packageTypeList.value!!.getOrNull(position)?.value ?: ""
    }

    fun onWeightLoginClick(): Boolean {
        showWeightEdit.value = true
        return true
    }

    fun getDetails() {
        val waybill = dataBean.value!!.wbNo
        if (dataBean.value!!.wbNo.isEmpty() || dataBean.value!!.wbNo.length != 11) return
        launchLoadingCollect({
            NetApply.api.getGncShouYunDetails(waybill)
        }) {
            onSuccess = {
                it.data?.let { bean ->
                    bean.weight = ""
                    bean.pc = ""
                    bean.volume = ""
                    dataBean.value = bean
                }
            }
        }
    }

    /**
     * 获取平板车信息
     */
    fun getCarInfo() {
        if (dataBean.value!!.carNo.isEmpty()) {
            return
        }
        launchCollect({
            NetApply.api.getCarDetails(dataBean.value!!.carNo)
        }) {
            onSuccess = {
                dataBean.value?.carWeight = it.data?.carWeight ?: ""
            }

            onFailed = { _, message ->
                showToast(message)
                dataBean.value?.carWeight = ""
            }
        }
    }

    fun getUldInfo() {
        if (dataBean.value!!.uld.isEmpty()) {
            return
        }
        launchCollect({
            NetApply.api.getUldDetails(dataBean.value!!.uld)
        }) {
            onSuccess = {
                it.data?.let { data ->
                    dataBean.value?.uldWeight = data.uldWeight
                }
            }
            onFailed = { _, message ->
                showToast(message)
                dataBean.value?.uldWeight = ""
            }
        }
    }


    /**
     * 打印挂签 点击
     */
    fun printClick () {

        if (!BluetoothAdapter.getDefaultAdapter().isEnabled) {
            showToast("请打开设备蓝牙")
            return
        }
        printShouYun(dataBean.value!!, false)
    }

    /**
     * 校验 点击
     */
    fun onVerifyClick() {
        if (dataBean.value!!.carWeight.isEmpty()) {
            showToast("平板车信息未维护，设备不可用！")
            return
        }
        val wFloat = dataBean.value?.weight.orEmpty().toFloatOrNull() ?: 0f
        val carFloat = dataBean.value?.carWeight.orEmpty().toFloatOrNull() ?: 0f
        if (abs(wFloat - carFloat) > (carFloat * 0.03)) {
            getTopActivity().showConfirmDialog("误差超过3%，是否覆盖？") {
                launchLoadingCollect({
                    NetApply.api.simplePost(
                        "eqm/flatcar/updateFlatcar", mapOf(
                            "carId" to dataBean.value!!.carNo,
                            "carWeight" to wFloat.roundToInt(),
                        ).toRequestBody()
                    )
                }) {
                    onSuccess = {
                        getCarInfo()
                    }
                }
            }
        } else {
            showToast("数据在误差范围内")
        }
    }


    /**
     * 分斗 点击
     */
    fun onSplitClick() {
        if (!verifyData()) {
            return
        }
        launchLoadingCollect({
            NetApply.api.anyPost("DomExpCheckIn/divided", dataBean.value!!.toRequestBody(true))
        }) {
            onSuccess = {
                showToast(it.msg.noNull("分斗成功"))
                dataBean.value?.carNo = ""
                dataBean.value?.pc = ""
                dataBean.value?.weight = ""
                dataBean.value?.volume = ""
            }
        }
    }

    fun onConfirmClick() {
        if (!verifyData()) {
            return
        }
        showSyncDialog(dataBean.value!!.wbNo)
    }

    private fun showSyncDialog(waybill: String) {
        val data = dataBean.value!!
        launchLoadingCollect({
            NetApply.api.getShouYunSyncList(
                mapOf(
                    "wbNo" to waybill
                ).toRequestBody()
            )
        }) {
            onSuccess = {
                var isAdd = true
                var dbPc = 0
                var dbWeight = 0.0
                var dbVolume = 0.0
                if (!data.carNo.isNullOrEmpty()){
                    it.data?.forEach { t ->
                        if (t.location.equals(data.carNo)){
                            println("匹配到对应平板车，件数重量累加")
                            isAdd = false
                            dbPc = t.pc.toInt()
                            dbWeight = t.weight.toDouble()
                            dbVolume = t.volume.toDouble()
                            t.pc = ((t.pc.toInt()).plus(data.pc.toInt())).toString()
                            t.weight = ((t.weight.toDouble()).plus(data.weight.toDouble())).toString()
                            t.volume = (t.volume.toDouble().plus(data.volume.toDouble())).toString()
                        }

                    }
                }
                var list = (it.data ?: emptyList())
                if (isAdd){
                    list = (it.data ?: emptyList()) + listOf(
                        ShouYunSyncBean().apply {
                            location = data.carNo
                            pc = data.pc
                            weight = data.weight
                            volume = data.volume
                        }
                    )
                }

                GncPdaShouYunSyncDialogModel(waybill, list) { model ->
                    if (isAdd){
                        val last = list.last()
                        data.pc = last.pc
                        data.weight = last.weight
                        data.volume = last.volume
                        list = list.subList(0, list.size - 1)
                    }else{
                        list.forEach {t ->
                            if (t.location.equals(data.carNo)) {
                                val pc = (t.pc.toInt()).minus(dbPc)
                                val weight = (t.weight.toDouble()).minus(dbWeight)
                                if (pc <= 0){
                                    showToast("本次收运件数少于等于0！")
                                    return@GncPdaShouYunSyncDialogModel
                                    return@GncPdaShouYunSyncDialogModel
                                }
                                if (weight <= 0){
                                    showToast("本次收运重量少于等于0！")
                                    return@GncPdaShouYunSyncDialogModel
                                }
                                data.pc = pc.toString()
                                data.weight = weight.toString()
                                data.volume =  (weight / 220f).limit(2)
                                t.pc =dbPc.toString()
                                t.weight=dbWeight.toString()
                                t.volume = dbVolume.toString()
                            }
                        }
                    }
                    launchLoadingCollect({
                        NetApply.api.anyPost(
                            "DomExpCheckIn/updateWarehouseList",
                            mapOf(
                                "list" to list,
                                "wb" to data
                            ).toRequestBody()
                        )
                    }) {
                        onSuccess = { b ->
                            showToast(b.msg.noNull("同步成功"))
                            dataBean.value = GncShouYunBean()
                        }
                    }
                }.show()
            }
        }
    }

    /**
     * 打印挂签
     */
    private fun printShouYun(bean: GncShouYunBean, showSync: Boolean) {
        bean.location = bean.carNo
        bean.username = SharedPreferenceUtil.getString(Constant.Share.userName)
        BluetoothDialogModel()
            .showCallBack {
                PrinterUtils.printShouYun(bean)
                if (showSync) {
                    showSyncDialog(bean.wbNo)
                }
            }
    }

    private fun verifyData(): Boolean {
        val bean = dataBean.value!!
        if (bean.wbNo.length != 11 || bean.mawbId.isEmpty()) {
            showToast("请输入正确的运单号")
            return false
        }
        if (bean.pc.verifyNullOrEmpty("请输入件数")
            || bean.agentCode.verifyNullOrEmpty("请选择代理人")
            || bean.spCode.verifyNullOrEmpty("请选择特码")
            || bean.weight.verifyNullOrEmpty("请输入重量")
            || bean.volume.verifyNullOrEmpty("请输入体积")
        ) {
            return false
        }

        return true
    }

    fun carScanClick() {
        ScanModel.startScan(getTopActivity(), Constant.RequestCode.CAR)
    }

    fun waybillScanClick() {
        ScanModel.startScan(getTopActivity(), Constant.RequestCode.WAYBILL)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (data == null || resultCode != Activity.RESULT_OK) {
            return
        }
        when (requestCode) {
            Constant.RequestCode.CAR -> {
                dataBean.value!!.carNo = data.getStringExtra(Constant.Result.CODED_CONTENT).noNull()
                getCarInfo()
            }

            Constant.RequestCode.WAYBILL -> {
                dataBean.value!!.wbNo = data.getStringExtra(Constant.Result.CODED_CONTENT).noNull()
                getDetails()
            }

            else -> {}
        }
    }

    override fun onCleared() {
        super.onCleared()
        diBangModel.cancelLooperGet()
    }
}