package com.dlc.chemical.ui.input

import android.annotation.SuppressLint
import android.content.Intent
import android.content.IntentFilter
import android.hardware.usb.UsbManager
import android.os.Bundle
import android.view.View
import com.dlc.chemical.ChemicalApp
import com.dlc.chemical.R
import com.dlc.chemical.databinding.ActivityInputStoreBinding
import com.dlc.chemical.iflytek.AudioPlayerManager
import com.dlc.chemical.print.PrinterListener
import com.dlc.chemical.print.PrinterStateReceiver
import com.dlc.chemical.print.UsbPrinterManager
import com.dlc.chemical.ui.MainActivity
import com.dlc.chemical.ui.common.*
import com.dlc.chemical.ui.dialog.*
import com.dlc.chemical.ui.msds.MsdsDetailActivity
import com.dlc.chemical.ui.unlock.SelectAuthMethodActivity
import com.dlc.chemical.ui.widget.TitleBar
import com.print.usbprint.util.USBUtil
import com.rc.core.log.RcLog
import com.rc.core.util.DateUtils
import com.rc.httpcore.client.ApiRepository
import com.rc.httpcore.vo.response.CabinetLockVo
import com.rc.httpcore.vo.response.ChemicalBean
import com.rc.httpcore.vo.response.LockRespBean
import java.util.*

/**
 * 化学品入库
 * MainActivity > QueryChemicalsActivity > InputStoreActivity > SteelyardVideoActivity(finish)
 *  [ > SelectAuthMethodActivity(finish) > TagScanActivity(finish) > ChemicalUnlockActivity(finish)]
 *  > (finish) > InputStoreCompletedActivity
 *
 * @author ReiChin_
 */
class InputStoreActivity : BaseCountDownActivity<ActivityInputStoreBinding>(),
    TitleBar.TitleListener {

    companion object {
        private const val REQ_PERSON_AUTH = 10
        private const val REQ_TAG_SCAN = 11
        private const val REQ_TARE = 12
        private const val REQ_STEELYARD_VIDEO = 13
    }

    private lateinit var mChemicalBean: ChemicalBean
    private var mSaveChemicalBean: ChemicalBean? = null

    private var mExpirationTime: Calendar? = null // 过期时间

    override fun beforeSetContentView() {
        mChemicalBean = intent.getParcelableExtra("chemicalBean")!!
    }

    override fun createViewBinding() = ActivityInputStoreBinding.inflate(layoutInflater)

    @SuppressLint("SetTextI18n")
    override fun initViews(savedInstanceState: Bundle?) {
        viewBinding.titleBar.setTitleListener(this)
        viewBinding.titleBar.setTitleInfoFromSp()

        // 过期时间
        viewBinding.expirationTime.setOnClickListener {
            val defDate = viewBinding.expirationTime.text.toString().split("|")[0]
            DatePickerDialog(this,
                defDate = defDate,
                dialogListener = { pickerDate ->
                    if (DateUtils.compareToYMD(pickerDate, Calendar.getInstance()) < 1) {
                        showToast("过期时间不正确！")
                        false
                    } else {
                        mExpirationTime = pickerDate
                        viewBinding.expirationTime.text =
                            "${DateUtils.formatDate(pickerDate)} | 30天前提醒"
                        true
                    }
                }).show()
        }

        // MSDS
        viewBinding.msds.setOnClickListener {
            if (mChemicalBean.hazardId.isNullOrEmpty()) {
                showToast("暂无MSDS信息")
                return@setOnClickListener
            }
            MsdsDetailActivity.startAction(this, mChemicalBean.hazardId)
        }

        // 容器重量
        viewBinding.tareSetting.visibility = if ("g" == mChemicalBean.chemicalUnit) View.VISIBLE else View.GONE
        viewBinding.tareSetting.setOnClickListener {
            val intent = Intent(this, TareSettingActivity::class.java)
            startActivityForResult(intent, REQ_TARE)
        }

        // 取消
        viewBinding.cancel.setOnClickListener {
            finish()
        }

        // 确定
        viewBinding.save.setOnClickListener {
            dispatchSaveClicked()
        }
    }

    private fun dispatchSaveClicked() {
        if (verifySaveParam()) {
            val extraParam = ExtraParam(
                chemicalName = mChemicalBean.chemicalName, // 化学品名称
                tareWeight = viewBinding.tare.getTag(R.id.tag_join_weight) as String?
                    ?: mChemicalBean.tare, // 容器重量
                chemicalAmount = mChemicalBean.chemicalAmount // 化学品规格
            )
            val intent = Intent(this, SteelyardVideoActivity::class.java)
            intent.putExtra("moduleEnum", ModuleEnum.INPUT_STORE)
            intent.putExtra("extraParam", extraParam)
            intent.putExtra("chemicalUnit", mChemicalBean.chemicalUnit)
            startActivityForResult(intent, REQ_STEELYARD_VIDEO)
        }
    }

    private fun startTagScanActivity() {
        val intent = Intent(this, TagScanActivity::class.java)
        intent.putExtra("moduleEnum", ModuleEnum.INPUT_STORE)
        startActivityForResult(intent, REQ_TAG_SCAN)
    }

    private fun onPrinterEvent(success: Boolean, message: String) {
        if (success) {
            AudioPlayerManager.speakVoice(R.raw.audio_paste_qrcode)
            SimpleTipsDialog(this, "请将二维码粘在化学品瓶身上。").apply {
                setOnDismissListener {
                    dispatchInputSuccess()
                }
            }.show()
        } else {
            showToast("${message}, 入库已完成，请在‘标签管理’模块重新打印！")
            dispatchInputSuccess()
        }
    }

    private var mPrinterStateReceiver: PrinterStateReceiver? = null

    override fun onResume() {
        super.onResume()
        mSendPrintCmd = false
        registerPrinterStateReceiver()
    }

    private var mSendPrintCmd = false

    private fun registerPrinterStateReceiver() {
        if (mPrinterStateReceiver == null) {
            val filter = IntentFilter()
            mPrinterStateReceiver = PrinterStateReceiver(printerListener = object : PrinterListener {

                private var prevSuccess: Boolean = true

                override fun onPrintResult(success: Boolean, message: String) {
                    RcLog.info("mSendPrintCmd:${mSendPrintCmd}, success:${success}, prevSuccess=${prevSuccess}")
                    if (mSendPrintCmd && (success || prevSuccess != success)) {
                        onPrinterEvent(success, message)
                        prevSuccess = success
                    }
                }

            })
            filter.addAction(PrinterStateReceiver.ACTION_PRINTER_STATE)
            filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
            this.registerReceiver(mPrinterStateReceiver, filter)
        }
    }

    override fun onPause() {
        super.onPause()
        if (mPrinterStateReceiver != null) {
            unregisterReceiver(mPrinterStateReceiver)
            mPrinterStateReceiver = null
        }
    }

    private fun handleSaveChemical(rfidCode: String? = null) {
        callSaveChemicalApi(generateChemicalBean(rfidCode))
    }

    private fun callSaveChemicalApi(param: ChemicalBean) {
        showLoading("保存中...")
        val disposable = ApiRepository.addStock(param)
            .subscribe({ data ->
                mSaveChemicalBean = data
                dismissLoading()
                if (null == param.rfidCode) {
                    // 打印二维码
                    param.tagCode = data.tagCode
                    printLabel(param)
                } else {
                    AudioPlayerManager.speakVoice(R.raw.audio_paste_rfid)
                    SimpleDialog(
                        context = this,
                        titleText = "标签编号：${param.rfidCode}",
                        message = "识别绑定成功，请将RFID标签粘在化学品瓶身上。",
                        messageTextColor = "#FF333333",
                        showCancelBtn = false
                    ).apply {
                        setOnDismissListener {
                            val printLabelParam = if ("1" == param.printCode) {
                                param.tagCode = data.tagCode
                                param
                            } else null
                            dispatchInputSuccess(printLabelParam)
                        }
                    }.show()
                }
            }, { throwable ->
                dismissLoading()
                showNetError(throwable)
                throwable.printStackTrace()
            })
        addDisposable(disposable)
    }

    private fun printLabel(param: ChemicalBean) {
        val device = USBUtil.getInstance()
            .getUsbDevice(UsbPrinterManager.DEVICE_VID, UsbPrinterManager.DEVICE_PID)
        if (null != device && USBUtil.getInstance().IsOpen(device, this)) {
            mSendPrintCmd = true
            UsbPrinterManager.printLabel(param)
        } else {
            showToast("未连接打印设备！")
        }
    }

    private fun verifySaveParam(): Boolean {
        // 容器重量
        if ("g" == mChemicalBean.chemicalUnit) {
            val tareWeight =
                viewBinding.tare.getTag(R.id.tag_join_weight) as String? ?: mChemicalBean.tare
            if (tareWeight.isNullOrEmpty()) {
                showToast("请设置容器重量！")
                return false
            }
        }

        if (null == mExpirationTime) {
            showToast("请设置过期时间！")
            return false
        }
        return true
    }

    private fun generateChemicalBean(rfidCode: String? = null): ChemicalBean {
        val data = mChemicalBean
        // 过期时间
        data.expirationTime = DateUtils.formatDate(mExpirationTime!!)
        // 入库重量
        data.usages = mWeight
        // 入库方式（1 称重，2 录入）
        data.joinType = mJoinType
        // 入库视频
        data.joinVideo = mRemoteFileUrl
        // 容器重量
        val tareWeight = viewBinding.tare.getTag(R.id.tag_join_weight) as String?
        if (!tareWeight.isNullOrEmpty()) {
            mChemicalBean.tare = tareWeight
        }

        data.joinOneUser = mJoinOneUser
        data.joinTwoUser = mJoinTwoUser
        data.rfidCode = rfidCode
        data.chemicalNum = mChemicalBean.joinNum
        data.measuringMethod = "1"
//        data.chemicalUnit = "g"
        data.status = "1"
        return data
    }

    @SuppressLint("SetTextI18n")
    override fun initData() {
        // 名称
        viewBinding.chemicalName.text = mChemicalBean.chemicalName
        // 别名
        viewBinding.anotherName.text = mChemicalBean.anotherName
        // 分类
        viewBinding.classifyName.text = mChemicalBean.classifyName
        // 编号
        viewBinding.chemicalNum.text = mChemicalBean.joinNum
        // CAS号
        viewBinding.casNum.text = mChemicalBean.casNum
        // 形态
        viewBinding.chemicalShape.text = mChemicalBean.chemicalShapeName
        // 生产厂家
        viewBinding.factory.text = mChemicalBean.factory
        // 负责人
        viewBinding.safeUserName.text = mChemicalBean.safeUserName
        // 所在位置
        viewBinding.cabinetName.text = mChemicalBean.cabinetName
        // 纯度
        viewBinding.purity.text = mChemicalBean.purity
        // 规格
        viewBinding.chemicalAmount.text =
            "${mChemicalBean.chemicalAmount ?: ""}${mChemicalBean.chemicalAmountUnit ?: ""}"
        // 容器重量
        if ("g" == mChemicalBean.chemicalUnit) {
            viewBinding.tare.text = "${mChemicalBean.tare ?: 0.0}g"
        } else {
            viewBinding.tare.text = "--"
        }
    }

    private fun dispatchInputSuccess(printLabelParam: ChemicalBean? = null) {
        if (null != printLabelParam) {
            printLabel(printLabelParam)
            return
        }

        if (true == ChemicalApp.sLearnLoginVo?.cabinetLock) {
            // 有智能锁，开锁/关锁流程 -> 入库完成画面
            callOpenLockApi()
        } else {
            // 没有智能锁，直接进入入库完成画面
            val intent = Intent(this, InputStoreCompletedActivity::class.java)
            intent.putExtra("chemicalBean", mSaveChemicalBean)
            startActivity(intent)
            finish()
        }
    }

    private fun callOpenLockApi() {
        showLoading("开锁中...")
        val param = CabinetLockVo()
        param.lockType = LockType.IN_STOCK.code
        param.joinId = mSaveChemicalBean!!.joinId
        val disposable = ApiRepository.openLock(param)
            .subscribe({ data ->
                dismissLoading()
                if (data.success) {
                    // 开锁成功
                    dispatchOpenLockSuccess(param, data)
                } else {
                    showToast("开锁失败")
                }
            }, { throwable ->
                dismissLoading()
                showNetError(throwable)
                throwable.printStackTrace()
            })
        addDisposable(disposable)
    }

    private fun dispatchOpenLockSuccess(cabinetLock: CabinetLockVo, lockRespBean: LockRespBean) {
        AudioPlayerManager.speakVoice(R.raw.audio_success_open_lock)
        SuccessDialog(this, "开锁成功").apply {
            setCancelable(false)
            setOnDismissListener {
                cabinetLock.stockId = mSaveChemicalBean?.id
                val intent = Intent(this@InputStoreActivity, ChemicalUnlockActivity::class.java)
                intent.putExtra("cabinetLock", cabinetLock)
                intent.putExtra("lockRespBean", lockRespBean)
                intent.putExtra("chemicalBean", mSaveChemicalBean)
                startActivity(intent)
                finish()
            }
        }.show()
    }

    private var mJoinOneUser: String? = null
    private var mJoinTwoUser: String? = null

    @SuppressLint("SetTextI18n")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            REQ_PERSON_AUTH -> {
                if (RESULT_OK == resultCode) {
                    val authResult = data?.getBooleanExtra("auth_result", false) ?: false
                    if (authResult) {
                        mJoinOneUser = data?.getStringExtra("joinOneUser")
                        mJoinTwoUser = data?.getStringExtra("joinTwoUser")
                        if (TagType.RFID.type == mChemicalBean.labelType) {
                            // 绑定RFID >>> 入库
                            startTagScanActivity()
                        } else {
                            // 入库
                            handleSaveChemical()
                        }
                    }
                }
            }
            REQ_TAG_SCAN -> {
                if (RESULT_OK == resultCode) {
                    data?.getStringExtra("rfidCode")?.let { rfidCode ->
                        handleSaveChemical(rfidCode)
                    }
                }
            }
            REQ_TARE -> {
                if (RESULT_OK == resultCode) {
                    data?.getStringExtra("tare")?.let { tare ->
                        viewBinding.tare.setTag(R.id.tag_join_weight, tare)
                        viewBinding.tare.text = "${tare}g"
                    }
                }
            }
            REQ_STEELYARD_VIDEO -> {
                if (RESULT_OK == resultCode) {
                    data ?: return
                    mWeight = data.getStringExtra("weight")
                    mJoinType = data.getStringExtra("joinType")
                    mRemoteFileUrl = data.getStringExtra("remoteFileUrl")

                    if ("2" == mChemicalBean.classifyConfig.joinStatus) {
                        // 2-双人双卡
                        val intent = Intent(this, SelectAuthMethodActivity::class.java)
                        intent.putExtra("lockType", LockType.IN_STOCK.code)
                        startActivityForResult(intent, REQ_PERSON_AUTH)
                    } else {
                        // 1-单人验证
                        if (TagType.RFID.type == mChemicalBean.labelType) {
                            // 绑定RFID >>> 入库
                            startTagScanActivity()
                        } else {
                            // 入库
                            handleSaveChemical()
                        }
                    }

                }
            }
        }
    }

    private var mWeight: String? = null // 化学品重量
    private var mJoinType: String? = null // 入库方式（1 称重，2 录入）
    private var mRemoteFileUrl: String? = null // 视频文件服务器地址

    override fun onHomeViewClicked(view: View) {
        startActivity(Intent(this, MainActivity::class.java))
    }

    override fun onBackViewClicked(view: View) {
        finish()
    }

}