package com.adealink.weparty.room.gift

import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.adealink.frame.aab.util.getCompatString
import com.adealink.frame.base.Rlt
import com.adealink.frame.base.fastLazy
import com.adealink.frame.mvvm.view.viewBinding
import com.adealink.frame.router.Router
import com.adealink.frame.util.onClick
import com.adealink.weparty.commonui.ext.dp
import com.adealink.weparty.commonui.ext.gone
import com.adealink.weparty.commonui.ext.show
import com.adealink.weparty.commonui.recycleview.adapter.MultiTypeListAdapter
import com.adealink.weparty.commonui.recycleview.diffutil.BaseListDiffUtil
import com.adealink.weparty.commonui.recycleview.itemdecoration.GridSpacingItemDecoration
import com.adealink.weparty.commonui.recycleview.itemdecoration.HorizontalItemDecoration
import com.adealink.weparty.commonui.toast.util.showFailedToast
import com.adealink.weparty.commonui.toast.util.showToast
import com.adealink.weparty.commonui.widget.BottomDialogFragment
import com.adealink.weparty.commonui.widget.CommonDialog
import com.adealink.weparty.commonui.widget.NumberIncreaseView
import com.adealink.weparty.module.gift.GiftModule
import com.adealink.weparty.module.gift.data.GiftInfo
import com.adealink.weparty.module.profile.ProfileModule
import com.adealink.weparty.module.room.data.isSeatEmpty
import com.adealink.weparty.module.wallet.Wallet
import com.adealink.weparty.module.wallet.WalletModule
import com.adealink.weparty.module.wallet.data.Currency
import com.adealink.weparty.room.R
import com.adealink.weparty.room.databinding.DialogRoomGiftPanelBinding
import com.adealink.weparty.room.datasource.local.RoomLocalService
import com.adealink.weparty.room.gift.adapter.RoomGiftItemViewBinder
import com.adealink.weparty.room.gift.adapter.RoomGiftTargetUserItemViewBinder
import com.adealink.weparty.room.gift.adapter.RoomGiftUserItemViewBinder
import com.adealink.weparty.room.gift.data.RoomGiftItemData
import com.adealink.weparty.room.gift.data.RoomGiftUserItemData
import com.adealink.weparty.room.gift.dialog.DiamondRechargeDialog
import com.adealink.weparty.room.gift.viewmodel.RoomGiftPanelViewModel
import com.adealink.weparty.room.sdk.service.roomService
import com.adealink.weparty.util.formatNumberStr
import kotlinx.coroutines.launch

class RoomGiftPanelDialog : BottomDialogFragment(R.layout.dialog_room_gift_panel) {

    private val binding by viewBinding(DialogRoomGiftPanelBinding::bind)
    private val roomGiftViewModel by fastLazy { GiftModule.getGiftViewModel(requireActivity()) }

    private val giftPanelViewModel by viewModels<RoomGiftPanelViewModel>()
    private val walletViewModel by fastLazy { WalletModule.getWalletViewModel(requireActivity()) }
    private val userAdapter by fastLazy { MultiTypeListAdapter(BaseListDiffUtil()) }
    private var userItemList = mutableListOf<RoomGiftUserItemData>()
    private val giftAdapter by fastLazy { MultiTypeListAdapter<RoomGiftItemData>(BaseListDiffUtil()) }
    private var giftItemList = mutableListOf<RoomGiftItemData>()
    private var targetUid: String? = null

    private var selectGift: GiftInfo? = null

    override val height: Int = 400.dp()

    fun setTargetUid(uid: String?) {
        this.targetUid = uid
    }

    private fun sendOnlyOne(): Boolean {
        return !targetUid.isNullOrEmpty()
    }

    override fun initViews() {
        super.initViews()
        binding.tvBalance.onClick {
            goDiamondExchangePage()
        }
        //顶部用户
        userAdapter.register(RoomGiftTargetUserItemViewBinder())
        userAdapter.register(RoomGiftUserItemViewBinder { clickedItem ->
            if (sendOnlyOne()) {
                return@RoomGiftUserItemViewBinder
            }
            userAdapter.notifyItemChanged<RoomGiftUserItemData> {
                if (it.userInfo?.uid == clickedItem.userInfo?.uid) {
                    it.isSelected = !it.isSelected
                    true
                } else {
                    false
                }
            }
            updateBottomPanel()
        })
        binding.rvUsers.layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
        binding.rvUsers.addItemDecoration(HorizontalItemDecoration(6.dp(), 0, 0))
        binding.rvUsers.adapter = userAdapter
        //礼物
        giftAdapter.register(RoomGiftItemViewBinder { clickedItem ->
            giftAdapter.notifyItemChanged<RoomGiftItemData> {
                val oldSelected = it.isSelected
                val nextSelected = it.giftInfo.id == clickedItem.giftInfo.id
                if (nextSelected) {
                    this@RoomGiftPanelDialog.selectGift = it.giftInfo
                }
                if (oldSelected == nextSelected) {
                    false
                } else {
                    it.isSelected = nextSelected
                    true
                }
            }
            binding.vNumber.setNumber(1)
            updateBottomPanel()
        })
        binding.rvGifts.layoutManager = GridLayoutManager(context, 4)
        binding.rvGifts.addItemDecoration(
            GridSpacingItemDecoration(4, 0, 10.dp(), false)
        )
        binding.rvGifts.adapter = giftAdapter

        binding.vNumber.setListener(object : NumberIncreaseView.OnNumberChangedListener {
            override fun onNumberChanged(number: Int) {
                updateBottomPanel()
            }
        })
        binding.btnSend.onClick {
            val toUids = if (sendOnlyOne()) {
                targetUid?.let {
                    listOf(it)
                }
            } else {
                userAdapter.getCurrentList()
                    .mapNotNull {
                        if (it is RoomGiftUserItemData && it.isSelected && it.userInfo?.uid != ProfileModule.getMyUid()) {
                            it.userInfo?.uid
                        } else {
                            null
                        }
                    }
            }
            if (toUids.isNullOrEmpty()) {
                showToast(R.string.room_send_gift_to_uids_empty)
                return@onClick
            }
            val selectedGift = giftAdapter.getCurrentList().find { it.isSelected }?.giftInfo
            if (selectedGift == null) {
                showToast(R.string.room_send_gift_gift_no_select)
                return@onClick
            }
            val giftCount = binding.vNumber.getNumber()
            if (giftCount <= 0) {
                showToast(R.string.room_send_gift_count_empty)
                return@onClick
            }
            val totalPrice = selectedGift.price * giftCount
            val diamond = walletViewModel?.getDiamond() ?: 0.0
            if (totalPrice > diamond) {
                //余额不足
                rechargeDiamond(totalPrice.toDouble(), sendGift = {
                    sendGiftInner(toUids.toSet(), selectedGift, giftCount, true)
                })
                return@onClick
            }
            sendGiftInner(toUids.toSet(), selectedGift, giftCount)
        }
        updateBottomPanel()
    }

    override fun observeViewModel() {
        super.observeViewModel()
        roomGiftViewModel?.giftsLD?.observe(viewLifecycleOwner) { gifts ->
            val itemList = gifts?.map {
                RoomGiftItemData(it)
            } ?: emptyList()
            giftItemList.clear()
            giftItemList.addAll(itemList)
            giftAdapter.submitList(giftItemList)
        }
        walletViewModel?.diamondLD?.observe(viewLifecycleOwner) {
            binding.tvBalance.text = formatNumberStr(it)
        }

        giftPanelViewModel.userInfoListLD.observe(viewLifecycleOwner) { itemLIst ->
            if (sendOnlyOne()) {
                val userItem = itemLIst?.firstOrNull()
                if (userItem == null) {
                    userAdapter.submitList(emptyList())
                } else {
                    userAdapter.submitList(listOf(userItem))
                }
            } else {
                val itemList = itemLIst.mapNotNull { it as? RoomGiftUserItemData }.onEach { item ->
                    item.isSelected = userItemList.find { it.userInfo?.uid == item.userInfo?.uid }?.isSelected ?: false
                }
                userItemList.clear()
                userItemList.addAll(itemList)
                userAdapter.submitList(userItemList)
            }
        }
    }

    override fun loadData() {
        super.loadData()
        val roomId = roomService.joinController.getJoinedRoomId()
        if (roomId.isNullOrEmpty()) {
            return
        }
        roomGiftViewModel?.getGifts(roomId)
        walletViewModel?.refreshWalletData()

        val tagetUid = targetUid
        if (tagetUid.isNullOrEmpty()) {
            lifecycleScope.launch {
                roomService.seatController.micSeatsFlow.collect { seatInfos ->
                    val seatInfoList = seatInfos.entries.filter {
                        !it.value.isSeatEmpty() && it.value.userInfo.userID != ProfileModule.getMyUid()
                    }.sortedBy { it.key }
                    giftPanelViewModel.updateSeatUser(seatInfoList)
                }
            }
        } else {
            giftPanelViewModel.setTargetUser(tagetUid)
        }
    }

    private fun updateBottomPanel() {
        if (selectGift != null) {
            binding.vNumber.show()
            binding.btnSend.isEnabled = true
            binding.btnSend.alpha = 1f
        } else {
            binding.vNumber.gone()
            binding.btnSend.isEnabled = false
            binding.btnSend.alpha = 0.4f
        }
    }

    private fun rechargeDiamond(totalPrice: Double, sendGift: () -> Unit) {
        val diamond = walletViewModel?.getDiamond() ?: 0.0
        val coin = walletViewModel?.getCoin() ?: 0.0
        val totalDiamond = diamond + coin * 1000
        if (totalPrice < totalDiamond) {
            //兑换后能满足送礼金额
            val showRemind = RoomLocalService.showDiamondRemind()
            if (showRemind) {
                DiamondRechargeDialog().apply {
                    setOnConfirmClick { sendGift.invoke() }
                }.show(childFragmentManager)
            } else {
                sendGift.invoke()
            }
            return
        }
        //金币兑换后也不足, 提示充值
        CommonDialog.Builder()
            .title(getCompatString(R.string.room_send_gift_balance_not_enough))
            .setShowDefaultCancel(true)
            .showTopClosetButton(true)
            .onPositive {
                WalletModule.showRechargeDialog(childFragmentManager, Currency.DIAMOND)
            }
            .show(childFragmentManager)
    }

    private fun sendGiftInner(toUids: Set<String>, gift: GiftInfo, count: Int, useCoinIfLess: Boolean = true) {
        roomGiftViewModel?.sendGift(toUids, gift, count, useCoinIfLess)?.observe(viewLifecycleOwner) { rlt ->
            when (rlt) {
                is Rlt.Failed -> {
                    showFailedToast(rlt)
                }

                is Rlt.Success<*> -> {
                    walletViewModel?.refreshWalletData()
                }
            }
        }
    }

    private fun goDiamondExchangePage() {
        val act = activity ?: return
        Router.build(act, Wallet.Recharge.PATH)
            .putExtra(Wallet.Common.EXTRA_CURRENCY, Currency.DIAMOND.type)
            .start()
    }
}