package com.adealink.weparty.wallet.recharge.fragment

import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.GridLayoutManager
import com.adealink.frame.base.Rlt
import com.adealink.frame.base.fastLazy
import com.adealink.frame.mvvm.view.viewBinding
import com.adealink.frame.util.onClick
import com.adealink.weparty.commonui.BaseFragment
import com.adealink.weparty.commonui.ext.dp
import com.adealink.weparty.commonui.recycleview.adapter.MultiTypeListAdapter
import com.adealink.weparty.commonui.recycleview.itemdecoration.GridSpacingItemDecoration
import com.adealink.weparty.commonui.toast.util.showToast
import com.adealink.weparty.module.profile.ProfileModule
import com.adealink.weparty.module.wallet.data.Currency
import com.adealink.weparty.module.wallet.data.PayChannel
import com.adealink.weparty.util.formatNumberStr
import com.adealink.weparty.wallet.R
import com.adealink.weparty.wallet.databinding.FragmentRechargeCoinBinding
import com.adealink.weparty.wallet.pay.PayRes
import com.adealink.weparty.wallet.recharge.adapter.RechargeErrorItemViewBinder
import com.adealink.weparty.wallet.recharge.adapter.RechargeItemViewBinder
import com.adealink.weparty.wallet.recharge.data.BaseRechargeListItemData
import com.adealink.weparty.wallet.recharge.data.RechargeErrorItemData
import com.adealink.weparty.wallet.recharge.data.RechargeItemData
import com.adealink.weparty.wallet.recharge.data.RechargeListErrorType
import com.adealink.weparty.wallet.recharge.dialog.ConvertCurrencyDialog
import com.adealink.weparty.wallet.recharge.viewmodel.RechargeViewModel
import com.adealink.weparty.wallet.stat.ClickCoinRechargeEvent
import com.adealink.weparty.wallet.stat.ViewCoinPageEvent
import com.adealink.weparty.wallet.viewmodel.WalletViewModel
import com.adealink.weparty.wallet.viewmodel.WalletViewModelFactory

class CoinRechargeFragment : BaseFragment(R.layout.fragment_recharge_coin) {

    companion object {
        private const val SPAN = 3
    }

    private val binding by viewBinding(FragmentRechargeCoinBinding::bind)

    private val walletViewModel by viewModels<WalletViewModel> { WalletViewModelFactory() }
    private val rechargeViewModel by viewModels<RechargeViewModel> { WalletViewModelFactory() }

    private val adapter by fastLazy { MultiTypeListAdapter<BaseRechargeListItemData>() }
    override fun initViews() {
        super.initViews()

        adapter.register(RechargeItemViewBinder(Currency.COIN) { it ->
            selectRecharge(it)
        })
        adapter.register(RechargeErrorItemViewBinder())

        binding.rvTopUp.adapter = adapter
        binding.rvTopUp.layoutManager = GridLayoutManager(context, SPAN).apply {
            spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
                override fun getSpanSize(position: Int): Int {
                    return if (adapter.items[position] is RechargeErrorItemData) {
                        3
                    } else {
                        1
                    }
                }
            }
        }
        binding.rvTopUp.addItemDecoration(
            GridSpacingItemDecoration(SPAN, 10.dp(), 16.dp(), false)
        )

        binding.vCoinCard.btnConvert.onClick {
            convertToDiamond()
        }
        binding.btnRecharge.onClick {
            goRecharge()
        }

        ViewCoinPageEvent().apply {
            userId to ProfileModule.getMyUid()
        }.send()
    }

    override fun observeViewModel() {
        super.observeViewModel()
        walletViewModel.coinLD.observe(viewLifecycleOwner) {
            binding.vCoinCard.tvBalance.text = formatNumberStr(it, false)
        }
        rechargeViewModel.rechargeListRltLD.observe(viewLifecycleOwner) { rlt ->
            when (rlt) {
                is Rlt.Failed -> {
                    adapter.submitList(
                        listOf(
                            RechargeErrorItemData(RechargeListErrorType.NetError, rlt.error)
                        ), true
                    )
                }

                is Rlt.Success -> {
                    //Ntd.
                }
            }
        }
        rechargeViewModel.rechargeListLD.observe(viewLifecycleOwner) {
            if (it.isNullOrEmpty()) {
                adapter.submitList(
                    listOf(
                        RechargeErrorItemData(RechargeListErrorType.RechargeListEmpty)
                    ), true
                )
            } else {
                adapter.submitList(it, true)
            }

        }
    }

    override fun loadData() {
        super.loadData()
        walletViewModel.getWalletData()
        rechargeViewModel.setupPayChannel(PayChannel.Google).observe(viewLifecycleOwner) { rlt ->
            when (rlt) {
                is Rlt.Failed -> {
                    when (rlt.error.serverCode) {
                        PayRes.FEATURE_NOT_SUPPORTED -> {
                            adapter.submitList(
                                listOf(
                                    RechargeErrorItemData(
                                        RechargeListErrorType.GoogleNoInstall,
                                        rlt.error
                                    )
                                ), true
                            )
                        }

                        else -> {
                            adapter.submitList(
                                listOf(
                                    RechargeErrorItemData(
                                        RechargeListErrorType.NetError,
                                        rlt.error
                                    )
                                ), true
                            )
                        }
                    }
                }

                is Rlt.Success -> {
                    rechargeViewModel.pullRechargeList(PayChannel.Google, Currency.COIN)
                }
            }
        }
    }

    private fun selectRecharge(item: RechargeItemData) {
        rechargeViewModel.selectItem(item)
    }

    private fun convertToDiamond() {
        ConvertCurrencyDialog().apply {
            fromCurrency = Currency.COIN
            toCurrency = Currency.DIAMOND
        }.show(childFragmentManager, "ConvertCurrencyDialog")
    }

    private fun goRecharge() {
        val act = activity ?: return
        val selectItem = rechargeViewModel.getSelectedItem()
        if (selectItem == null) {
            showToast(R.string.wallet_recharge_not_selected)
            return
        }

        ClickCoinRechargeEvent().apply {
            userId to ProfileModule.getMyUid()
        }.send()

        showLoading()
        rechargeViewModel.buyProduct(act, selectItem.data).observe(viewLifecycleOwner) {
            dismissLoading()
        }
    }
}