package com.qmai.zqtoolkit

import android.content.Context
import android.os.Build
import com.qmai.zqtoolkit.base.AclasScaleKit
import com.qmai.zqtoolkit.base.GiLongScaleKit
import com.qmai.zqtoolkit.base.SllchKit
import com.qmai.zqtoolkit.base.SunmiScaleKit
import com.qmai.zqtoolkit.base.ZqScaleKit
import com.qmai.zqtoolkit.base.scale.ScaleBaseAction
import com.qmai.zqtoolkit.base.scale.ScaleBaseKit
import com.qmai.zqtoolkit.config.*
import com.qmai.zqtoolkit.utils.ScaleChecker
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import java.util.*
import kotlin.coroutines.EmptyCoroutineContext

/**
 * tongzi
 * 2022/4/28
 * 电子秤hub 提供给业务
 */
object ScaleHub : ScaleBaseAction {
    private const val TAG = "ScaleHub"
    private val _connectState = MutableSharedFlow<ConnectState>()
    val connectState: SharedFlow<ConnectState> = _connectState
    private val _livingWeight = MutableSharedFlow<LivingWeight>()
    val livingWeight: SharedFlow<LivingWeight> = _livingWeight
    private val _scaleLog = MutableSharedFlow<String>()
    val scaleLog: SharedFlow<String> = _scaleLog
    private var connectJob: CoroutineScope? = null
    private var weightJob: CoroutineScope? = null
    private var scaleKit: ScaleBaseKit? = null


    fun manualInitSDK(scale: ScaleInfo) {
        disconnect()
        scaleKit = when (scale.brand?.brand) {
            QmScaleBrand.ZQEB.brand -> ZqScaleKit
            QmScaleBrand.SUNMI.brand -> SunmiScaleKit
            QmScaleBrand.ACLAS.brand -> AclasScaleKit
            QmScaleBrand.GILONG.brand -> GiLongScaleKit
            else -> null
        }
    }

    private fun tryInitSDK2C() {
        scaleKit = when {
            ScaleChecker.isZQ() -> ZqScaleKit
            ScaleChecker.isSUNMI_S2CC() -> SunmiScaleKit
            ScaleChecker.isAclas() -> AclasScaleKit
            ScaleChecker.isSllch() -> SllchKit
            else -> ZqScaleKit
        }
    }

    /**
     * fix-20220707  中崎称类型多，通过DeviceUtils.getModel()判断不准确，现改为默认中崎
     */
    private fun tryInitSDK2B(
        scale: ScaleInfo
    ) {
        scaleKit = when (scale.brand?.brand) {
            QmScaleBrand.ZQEB.brand -> ZqScaleKit
            QmScaleBrand.SUNMI.brand -> SunmiScaleKit
            QmScaleBrand.ACLAS.brand -> AclasScaleKit
            QmScaleBrand.GILONG.brand -> GiLongScaleKit
            else -> when {
                ScaleChecker.isSUNMI_S2CC() -> SunmiScaleKit
                ScaleChecker.isAclas() -> AclasScaleKit
                else -> null
            }
        }
        //通过tryInitSDK连接的,如果没有指定brand和model,赋一个默认的,若连接成功会被保存
        if (scaleKit != null && (scale.brand == null || scale.model == null)) {
            scale.brand = QmScaleBrand.find(scaleKit)
            scale.model = QmScaleModel.find(scaleKit)
        }
    }

    override fun connect(cxt: Context?, scale: ScaleInfo) {
        when (scale.appType) {
            SHOP_ASSITANT_2C -> tryInitSDK2C()
            SHOP_ASSITANT_2B -> tryInitSDK2B(scale)
        }
        scaleKit?.run {
            if (connectJob == null) {
                connectJob = CoroutineScope(EmptyCoroutineContext)
            }
            //商米机器外接三方称 预处理串口
            scale.run {
                port = if (scale.appType == SHOP_ASSITANT_2B && ScaleChecker.isSUNMI())
                    SunmiPort.find()
                //如果是GILONG (巨隆)
                else if (Build.MODEL == "rk3288") {
                    "ttyS1"
                } else "ttyS4"
                buad = "9600"
            }
        }
        connectJob?.launch(context = Dispatchers.IO) {
            collectScaleInfo()
        }
        connectJob?.launch(context = Dispatchers.IO) {
            collectConnectData()
        }
        connectJob?.launch(context = Dispatchers.IO) {
            scaleKit?.connect(cxt, scale)
        }
    }


    private suspend fun collectConnectData() {
        scaleKit?.connectState?.collect {
            _connectState.emit(it)
            if (scaleKit is ZqScaleKit && it.isConnect) {
                LEDHub.connect()
            }
        }
    }

    private suspend fun collectScaleInfo() {
        scaleKit?.scaleLog?.collect {
            _scaleLog.emit(it)
        }
    }

    //断开连接
    override fun disconnect() {
        scaleKit?.disconnect()
        LEDHub.clearLED()
        weightJob?.cancel()
        weightJob = null
        connectJob?.cancel()
        connectJob = null
    }


    //置零
    override fun setZero() {
        scaleKit?.setZero()
    }

    //去皮
    override fun setNetWeight() {
        scaleKit?.setNetWeight()
    }

    //数字去皮
    override fun setNetWeightByElec(tare: Double) {
        scaleKit?.setNetWeightByElec(tare)
    }

    //清皮
    override fun clearTare() {
        scaleKit?.clearTare()
    }

    //读取电子秤参数
    override fun getParameter(): Array<String> {
        return scaleKit?.getParameter() ?: arrayOf()
    }

    //电子秤是否可用
    override fun isScaleSuccess(): Boolean {
        return scaleKit?.isScaleSuccess() ?: false
    }


    //读取重量、皮重
    override fun readData() {
        if (weightJob == null) {
            weightJob = CoroutineScope(EmptyCoroutineContext)

        }
        weightJob?.launch(context = Dispatchers.IO) {
            collectWeightData()
        }
        scaleKit?.readData()
    }

    private suspend fun collectWeightData() {
        scaleKit?.livingWeight?.collect {
            _livingWeight.emit(it)
            if (it.isReadErr == false) {
                LEDHub.sendLEDWeight(it.weight)
            } else LEDHub.clearLED()
        }
    }

    override fun getLastScale(): ScaleInfo? {
        return scaleKit?.getLastScale()
    }

    override fun stopReadData() {
        scaleKit?.stopReadData()
        LEDHub.clearLED()
    }
}
