package com.doverfuelingsolutions.issp.view.fragment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.lifecycleScope
import com.doverfuelingsolutions.issp.R
import com.doverfuelingsolutions.issp.api.SystemApi
import com.doverfuelingsolutions.issp.databinding.FragmentPayScanCodeBinding
import com.doverfuelingsolutions.issp.driver.lib.ScanCodeManager
import com.doverfuelingsolutions.issp.fusion.FusionManager
import com.doverfuelingsolutions.issp.utils.DFSToastUtil
import com.doverfuelingsolutions.issp.utils.StringUtil
import com.doverfuelingsolutions.issp.utils.log.DFSLog
import com.doverfuelingsolutions.issp.utils.sp.SPUtil
import com.doverfuelingsolutions.issp.view.MainActivity
import com.wayne.www.waynelib.fdc.message.DeviceClass
import com.wayne.www.waynelib.webservice.entity.PosTrx
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.launch

class FragmentPayScanCode(private val dc: DeviceClass, private val posTrx: PosTrx) : FragmentBasic() {

    companion object {
        fun build(dc: DeviceClass, posTrx: PosTrx) = FragmentPayScanCode(dc, posTrx)
    }

    private lateinit var binding: FragmentPayScanCodeBinding
    private val viewModel = PayScanCodeViewModel()

    private val scanCodeManager = ScanCodeManager()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        lifecycleScope.launch { scanCodeManager.create() }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        if (!this::binding.isInitialized) {
            binding = DataBindingUtil.inflate(inflater, R.layout.fragment_pay_scan_code, container, false)
            binding.lifecycleOwner = this
            binding.viewModel = viewModel.apply {
                nozzle.value = dc.nozzleNo
                amount.value = dc.amount.toDouble()
                amountText.value = StringUtil.get(R.string.amount_rmb, dc.amount.toString())
                volume.value = dc.volume
                oil.value = dc.productName
                time.value = dc.endTimeStamp.substring(5)
            }
            setToolBar(binding.fragmentToolbar)
        }
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        viewModel.amountText.value = StringUtil.get(R.string.amount_with_discount, posTrx.netAmount.toString(), posTrx.discount.toString())

        startPay()
    }

    override fun onDestroy() {
        super.onDestroy()

        scanCodeManager.destroy()
    }

    private fun startPay() {
        lifecycleScope.launch {
            if (!scanCodeManager.isAvailable) {
                DFSToastUtil.fail(StringUtil.get(R.string.fail_behave_reason, StringUtil.get(R.string.init_scanner), StringUtil.get(R.string.plz_check_scanner)))
                return@launch
            }

            // TODO 处理扫描成功后倒计时不足的问题
            val scanValue = scanCodeManager.start()
            if (scanValue == null) {
                DFSToastUtil.fail(R.string.plz_correct_pay_code)
                startPay()
                return@launch
            }

            loading(R.string.in_pay)
            val result = SystemApi.pay(posTrx, scanValue)
            hideLoading()
            DFSLog.i(result)

            if (result.success && result.data != null) {
                // 支付成功后，移除本地云订单，清单
                GlobalScope.launch(Dispatchers.IO) {
                    SPUtil.removeWayneOrder(dc)
                    SPUtil.removeLockOrder(dc)
                    val resultClear = FusionManager.clearOrder(dc)
                    if (resultClear.success) {
                        dc.state = "Cleared"
                        SPUtil.removeUnclearedOrder(dc)
                    } else {
                        // 失败则记下来，后续再尝试消单
                        // TODO 如果后续仍然失败呢？包括锁单！！！！！
                        SPUtil.addUnclearedOrder(dc)
                    }
                }

                (activity as MainActivity).setFragment(FragmentPayResult.build(dc, result.data.PosTrx), true)
            } else {
                // TODO 倒计时不足的问题
                DFSToastUtil.fail(result.message)
                viewModel.scanTip.value = StringUtil.get(R.string.plz_scan_again)
                startPay()
            }
        }
    }

    class PayScanCodeViewModel : ViewModel() {
        val nozzle = MutableLiveData(1)
        val amount = MutableLiveData(0.0)
        val amountText = MutableLiveData("￥0.00")
        val scanTip = MutableLiveData(StringUtil.get(R.string.plz_scan))
        val volume = MutableLiveData("0.00")
        val oil = MutableLiveData("")
        val time = MutableLiveData("12-12")
    }
}