package com.doverfuelingsolutions.issp.view.fragment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import com.doverfuelingsolutions.issp.BuildConfig
import com.doverfuelingsolutions.issp.R
import com.doverfuelingsolutions.issp.api.FuelInfoApi
import com.doverfuelingsolutions.issp.api.SystemApi
import com.doverfuelingsolutions.issp.data.GlobalData
import com.doverfuelingsolutions.issp.databinding.FragmentNozzleOrdersBinding
import com.doverfuelingsolutions.issp.fusion.FusionManager
import com.doverfuelingsolutions.issp.utils.DFSToastUtil
import com.doverfuelingsolutions.issp.utils.StringUtil
import com.doverfuelingsolutions.issp.utils.sp.SPKeys
import com.doverfuelingsolutions.issp.utils.sp.SPUtil
import com.doverfuelingsolutions.issp.view.MainActivity
import com.doverfuelingsolutions.issp.view.adapter.ChooseListAdapter
import com.doverfuelingsolutions.issp.view.adapter.OrderListAdapter
import com.doverfuelingsolutions.issp.view.fragment.callback.RefreshOrder
import com.doverfuelingsolutions.issp.view.util.ClickUtils
import com.scwang.smart.refresh.header.ClassicsHeader
import com.wayne.www.waynelib.fdc.message.DeviceClass
import com.wayne.www.waynelib.util.log.DFSLog
import com.wayne.www.waynelib.webservice.entity.PosTrx
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.math.BigDecimal

class FragmentOrderList private constructor() : FragmentBasic(),RefreshOrder {

    companion object {
        fun build(pumpId: Int): FragmentOrderList {
            return FragmentOrderList().apply {
                arguments = bundleOf(Pair("pumpId", pumpId))
            }
        }
    }

    private var pumpId: Int = -1

    override val title = StringUtil.get(R.string.select_pay_order)
    override val countdownTime: Int = 80

    private lateinit var binding: FragmentNozzleOrdersBinding
    val viewModel = FragmentNozzleViewModel().apply {
        pump.value = pumpId
        isNozzle.value = pumpId != -1
    }

    private val orderList = arrayListOf<DeviceClass>()
    private val orderListAfterFilter = arrayListOf<DeviceClass>()
    private val orderListAdapter: OrderListAdapter by lazy {
        OrderListAdapter(if (pumpId != -1) orderList else orderListAfterFilter, this::selectOrder)
    }
    private var selectedPosition: Int? = null

    private var selectedName = ""
    private val oilNameList = FusionManager.nozzles.map { it.barcodeName }.toSet().toList()
    private val chooseListAdapter = ChooseListAdapter(oilNameList, this::selectOilName, true)

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

        FusionManager.onRefreshOrderUi = this
        pumpId = arguments?.getInt("pumpId") ?: -1
        loadListData()
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        if (!this::binding.isInitialized) {
            binding = DataBindingUtil.inflate(inflater, R.layout.fragment_nozzle_orders, container, false)

            // 油品模式
            if (pumpId == -1) {
                binding.oilList.layoutManager = GridLayoutManager(context, 4)
                binding.oilList.adapter = chooseListAdapter
            }

            if (binding.orderListView.layoutManager == null) {
                binding.orderListView.layoutManager = GridLayoutManager(context, 2)
            }
            if (binding.orderListView.adapter == null) {
                binding.orderListView.adapter = orderListAdapter
            }

            binding.smartRefreshLayout.setEnableLoadMore(false)
            binding.smartRefreshLayout.setEnableRefresh(true)
            binding.smartRefreshLayout.setRefreshHeader(ClassicsHeader(requireContext()))
            binding.smartRefreshLayout.setOnRefreshListener { handleRefresh() }

            binding.lifecycleOwner = this
            binding.viewModel = viewModel
        }

        // Adapter has to update if dc is changed in FragmentPayType and route back.
        selectedPosition?.let { orderListAdapter.notifyItemChanged(it) }

        return binding.root
    }

//    override fun onDestroy() {
//        super.onDestroy()
//        FusionManager.onRefreshOrderUi = null
//    }

    private fun selectOrder(dc: DeviceClass, type: Int, position: Int) {
        if (ClickUtils.isFastClick()) return
        lifecycleScope.launchWhenStarted {
            when {
                dc.releaseTokenElement == null || dc.releaseTokenAttribute == null -> {
                    DFSToastUtil.fail(R.string.wrong_order_info)
                }
                type == 0 -> {
                    if (dc.isLock && dc.lockingApplicationSender != GlobalData.workStationId.get()) {
                        DFSToastUtil.warn(R.string.order_lock_by_other)
                    } else {
                        selectedPosition = position
                        prepareBeforePay(dc)
//                        (activity as MainActivity).fragmentRouter.push(FragmentPayType.build(dc))
                    }
                }
                type == 1 && dc.isLock -> {
                    if (dc.lockingApplicationSender == GlobalData.workStationId.get() || BuildConfig.DEBUG) {
                        val checkResult = SystemApi.getOrderStateForClound(dc)
                        if (checkResult.success) {
                            val results = checkResult.data?.iListResult
                            val find = results?.find { it.resultCode == "0" }
                            if (find != null) { //表示这边订单已经支付过，接下来直接消单即可
                                DFSToastUtil.info("此订单已支付，请勿重复支付")
                                SPUtil.removeLockOrder(dc)
                                val resultClear = FusionManager.clearOrder(dc)
                                if (resultClear.success) {
                                    dc.state = "Cleared"
                                    SPUtil.removeUnclearedOrder(dc)
                                    SPUtil.removeWayneOrder(dc)
                                } else {
                                    // 失败则记下来，后续再尝试消单
                                    SPUtil.addUnclearedOrder(dc)
                                }
                                return@launchWhenStarted
                            }
                        }

                        val result = FusionManager.lockOrder(dc, false)
                        if (result.success) {
                            dc.state = "Payable"
                            orderListAdapter.notifyItemChanged(position)
                            SPUtil.removeLockOrder(dc)
                            DFSToastUtil.success(R.string.unlock_order_success)
                        } else {
                            DFSToastUtil.fail(R.string.fail_unlock_order)
                        }
                    } else {
                        DFSToastUtil.warn(R.string.cant_unlock_others)
                    }
                }
            }
        }
    }

    private fun prepareBeforePay(dc: DeviceClass) {
        val dialog = loading(R.string.in_process_order)
        (requireActivity() as MainActivity).fragmentRouter.stopFragmentToolbarTimer()

        lifecycleScope.launchWhenStarted {

            //先查找当前订单是否已支付
            val checkResult = SystemApi.getOrderStateForClound(dc)
            if (checkResult.success) {
                val results = checkResult.data?.iListResult
                val find = results?.find { it.resultCode == "0" }
                if (find != null) { //表示这边订单已经支付过，接下来直接消单即可
                    dialog.dismiss()
                    // 支付成功后，移除本地云订单，清单
                    GlobalScope.launch(Dispatchers.IO) {
                        SPUtil.removeLockOrder(dc)
                        val resultClear = FusionManager.clearOrder(dc)
                        if (resultClear.success) {
                            dc.state = "Cleared"
                            SPUtil.removeUnclearedOrder(dc)
                            SPUtil.removeWayneOrder(dc)
                        } else {
                            // 失败则记下来，后续再尝试消单
                            SPUtil.addUnclearedOrder(dc)
                        }

                    }
                } else {            //表示这笔订单还没支付过，按正常流程走
                    // 累计数信息
                    val resultAccumulationInfo = if (SPUtil.getBoolean(SPKeys.USE_FCC2)) {
                        FuelInfoApi.accumulationInfoFromFCC2(dc)
                    } else {
                        FuelInfoApi.accumulationInfo(dc)
                    }
                    if (resultAccumulationInfo.success && resultAccumulationInfo.data != null) {
                        if (resultAccumulationInfo.data.State == "Paid" || resultAccumulationInfo.data.State == "Cleared") {
                            dialog.dismiss()
                            (requireActivity() as MainActivity).fragmentRouter.resumeFragmentToolbarTimer()
                            DFSToastUtil.info("此订单已支付，请勿重复支付")
                            return@launchWhenStarted
                        }

                        //2022-10-8号，春洲 token：80322，出现在创建订单时枪号传成 1，这里将订单的枪号赋值为订单详情中的枪号
                        dc.nozzleNo = resultAccumulationInfo.data.SiteLevelNozzleId
                        dc.amountTotalizer = BigDecimal(resultAccumulationInfo.data.AmountTotalizer)
                        dc.volumeTotalizer = BigDecimal(resultAccumulationInfo.data.VolumeTotalizer)
                        dc.saleEndTime = resultAccumulationInfo.data.SaleEndTime
                    } else {
                        dialog.dismiss()
                        (requireActivity() as MainActivity).fragmentRouter.resumeFragmentToolbarTimer()
                        DFSToastUtil.fail(R.string.fail_get_accumulation)
                        return@launchWhenStarted
                    }

                    // 查询油品 posItemUniqueId
                    // 枪数据中有缓存 posItemUniqueId
                    val nozzle = FusionManager.nozzles.find { it.physicalId == dc.nozzleNo }
                    var posItemUniqueId = nozzle?.posItemUniqueId
                    if (posItemUniqueId.isNullOrEmpty()) {
                        val barcodeId = nozzle?.barcodeId ?: dc.productNo1.toInt()
                        val resultBarcodeInfo = SystemApi.barcodeName(barcodeId)
                        if (!resultBarcodeInfo.success || resultBarcodeInfo.data == null) {
                            dialog.dismiss()
                            // (requireActivity() as MainActivity).fragmentRouter.resumeFragmentToolbarTimer()
                            DFSToastUtil.fail("查询油品 posItemUniqueId 失败")
                            return@launchWhenStarted
                        }
                        posItemUniqueId = resultBarcodeInfo.data.Id
                        DFSLog.w("barcodeId：$barcodeId")
                    }

                    // 获取云订单（本地需要缓存，避免重复生成订单），2025-07 ，从接口处理，不需要再缓存
//                    var posTrx: PosTrx? = SPUtil.findWayneOrder(dc)
//                    if (posTrx == null) {
//
//                    }
                    var posTrx:PosTrx? = null
                    val resultReportPayment = SystemApi.generateOrder(dc, posItemUniqueId)
                    if (resultReportPayment.success && resultReportPayment.data != null && !resultReportPayment.data.id.isNullOrEmpty()) {
                        posTrx = resultReportPayment.data
                    } else {
                        dialog.dismiss()
                        (requireActivity() as MainActivity).fragmentRouter.resumeFragmentToolbarTimer()
                        DFSToastUtil.fail(StringUtil.get(R.string.fail_behave_reason, StringUtil.get(R.string.make_cloud_order), resultReportPayment.message))
                    }

                    // 锁定订单
                    if (posTrx == null) return@launchWhenStarted
                    val resultLock = FusionManager.lockOrder(dc, true)
                    (requireActivity() as MainActivity).fragmentRouter.resumeFragmentToolbarTimer()
                    if (resultLock.success) {
                        dc.state = "Locked"
                        SPUtil.addLockOrder(dc)
                        (activity as MainActivity).fragmentRouter.push(FragmentPayScanCode.build(dc, posTrx))
                    } else {
                        DFSToastUtil.fail(StringUtil.get(R.string.fail_behave_reason, StringUtil.get(R.string.lock_order), resultLock.message))
                    }
                    dialog.dismiss()
                }
            } else {
                dialog.dismiss()
                DFSToastUtil.fail("查询云端订单状态失败 ${checkResult.message}")
            }



        }
    }

    private fun selectOilName(oilName: String, refreshView: Boolean = true) {
        selectedName = oilName
        filterOrderListByOilName()
        if (refreshView) {
            orderListAdapter.notifyDataSetChanged()
        }
    }

    private fun handleRefresh() {
        lifecycleScope.launchWhenStarted {
            loadRemoteData()
            binding.smartRefreshLayout.finishRefresh(200, true, false)
        }
    }

    private fun loadListData() {
        lifecycleScope.launchWhenStarted {
            val dialog = loading(R.string.in_get_order)
            (requireActivity() as MainActivity).fragmentRouter.stopFragmentToolbarTimer()
            binding.orderListView.scrollTo(0, 0)

            // local cache
            orderList.clear()
            if (pumpId == -1) {
                val allPumps = FusionManager.nozzles.map { it.pumpId }.toSet().toList()
                val allPumpOrderList = allPumps.map {
                    SPUtil.getOrderListByPump(it)
                }
                val sum = allPumpOrderList.reduce { acc, list ->
                    acc.addAll(list)
                    acc
                }
                sum.sortByDescending { it.releaseTokenAttribute }
                orderList.addAll(sum)
                selectOilName(oilNameList[0], false)
            } else {
                orderList.addAll(SPUtil.getOrderListByPump(pumpId))
            }
            orderListAdapter.notifyDataSetChanged()

            // remote data
//            loadRemoteData()
            dialog.dismiss()
            (requireActivity() as MainActivity).fragmentRouter.resumeFragmentToolbarTimer()
        }
    }

    private suspend fun loadRemoteData() {
        val result = FusionManager.getAllUnsettledOrder(pumpId)
        if (result.success && result.data != null) {
            if (pumpId == -1) {
                SPUtil.setAllOrderList(result.data)
            } else {
                SPUtil.setOrderListByPump(pumpId, result.data)
            }
            if (result.data.isEmpty()) {
                DFSToastUtil.info(R.string.no_unpaid_order)
                back()
            } else {
                orderList.clear()
                orderList.addAll(result.data)
                filterOrderListByOilName()
                orderListAdapter.notifyDataSetChanged()
            }
        }
    }

    private fun filterOrderListByOilName() {
        if (orderListAfterFilter.isNotEmpty()) orderListAfterFilter.clear()
        orderListAfterFilter.addAll(orderList.filter { it.productName == selectedName })
    }

    class FragmentNozzleViewModel() : ViewModel() {
        val pump = MutableLiveData(-1)
        val isNozzle = MutableLiveData(true)
    }

    override fun onRefreshOrderUi(pump: Int,orders: List<DeviceClass>) {
        lifecycleScope.launchWhenStarted {
//            loadRemoteData()
            if (pump == pumpId) {
                orderList.clear()
                orderList.addAll(orders)
                orderListAdapter.notifyDataSetChanged()
            }

        }


    }
}