package com.adealink.weparty.order.dialog

import android.annotation.SuppressLint
import android.os.Bundle
import androidx.fragment.app.activityViewModels
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.router.annotation.BindExtra
import com.adealink.frame.router.annotation.RouterUri
import com.adealink.frame.util.onClick
import com.adealink.weparty.commonui.ext.gone
import com.adealink.weparty.commonui.ext.show
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.NumberIncreaseView
import com.adealink.weparty.constant.ORDER_REMARK_MAX_LENGTH
import com.adealink.weparty.module.im.IM
import com.adealink.weparty.module.order.Order
import com.adealink.weparty.module.order.OrderModule
import com.adealink.weparty.module.order.data.CreateOrderRes
import com.adealink.weparty.module.order.data.ORDER_SOURCE_DEFAULT
import com.adealink.weparty.module.order.data.discountLD
import com.adealink.weparty.module.order.data.getFinalPrice
import com.adealink.weparty.module.playmate.PlaymateModule
import com.adealink.weparty.module.playmate.data.PlaymateDetailData
import com.adealink.weparty.module.wallet.WalletModule
import com.adealink.weparty.module.wallet.data.Currency
import com.adealink.weparty.order.R
import com.adealink.weparty.order.databinding.DialogCreateOrderBinding
import com.adealink.weparty.order.viewmodel.OrderViewModel
import com.adealink.weparty.order.viewmodel.OrderViewModelFactory
import com.adealink.weparty.util.formatNumber
import com.adealink.weparty.util.formatNumberStr
import kotlin.math.max
import com.adealink.weparty.R as APP_R

@RouterUri(path = [Order.CreateDialog.PATH], desc = "订单确认弹窗")
class CreateOrderDialog : BottomDialogFragment(R.layout.dialog_create_order) {

    @BindExtra(Order.CreateDialog.EXTRA_MODIFY)
    var canModify: Boolean = false

    @BindExtra(Order.CreateDialog.EXTRA_SHOW_REMARK)
    var showRemark: Boolean = false

    @BindExtra(Order.CreateDialog.EXTRA_PLAYMATE_ID)
    var playmateId: String? = null

    @BindExtra(Order.CreateDialog.EXTRA_PLAYMATE)
    var playmateData: PlaymateDetailData? = null

    @BindExtra(Order.CreateDialog.EXTRA_ORDER_COUNT)
    var orderCount: Int = 1

    @BindExtra(Order.CreateDialog.EXTRA_ORDER_REMARK)
    var remark: String? = null

    @BindExtra(Order.CreateDialog.EXTRA_ORDER_SOURCE)
    var source: Int = ORDER_SOURCE_DEFAULT

    private val binding by viewBinding(DialogCreateOrderBinding::bind)

    private val viewModel by activityViewModels<OrderViewModel> { OrderViewModelFactory() }

    private val playmateViewModel by fastLazy { PlaymateModule.getPlaymateViewModel(this) }
    private val walletViewModel by fastLazy { WalletModule.getWalletViewModel(requireActivity()) }
    private var totalPrice: Float? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Router.bind(this)
    }

    @SuppressLint("SetTextI18n")
    override fun initViews() {
        super.initViews()
        binding.tvCategory.text = playmateData?.categoryName
        binding.ivAvatar.setImageUrl(playmateData?.avatar)
        binding.tvName.text = playmateData?.nickname

        val priceStr = formatNumberStr(playmateData?.price ?: 0f, false)
        binding.tvPrice.text = "${priceStr}/${playmateData?.unit ?: ""}"

        if (canModify) {
            binding.tvCount.gone()
            binding.vCount.show()
            binding.vCount.setNumber(orderCount)
            binding.vCount.setListener(object : NumberIncreaseView.OnNumberChangedListener {
                override fun onNumberChanged(number: Int) {
                    orderCount = number
                    updatePlaymateInfo()
                }
            })

            binding.tvRemarkInput.isEnabled = true
        } else {
            binding.tvCount.show()
            binding.tvCount.text = orderCount.toString()
            binding.vCount.gone()

            binding.tvRemarkInput.isEnabled = false
        }

        binding.tvRemarkInput.text = remark
        binding.tvRemarkInput.hint =
            getCompatString(R.string.order_remark_hint, ORDER_REMARK_MAX_LENGTH.toString())
        binding.tvRemarkInput.onClick {
            showEditRemarkDialog()
        }
        if (showRemark) {
            binding.clRemark.show()
        } else {
            binding.clRemark.gone()
        }

        binding.btnPay.onClick {
            pay()
        }
    }

    override fun loadData() {
        super.loadData()
        OrderModule.queryDiscountInfo()
        walletViewModel?.refreshWalletData()

        val playmateData = playmateData
        val playmateId = playmateId
        if (playmateData != null) {
            updatePlaymateInfo()
        } else if (!playmateId.isNullOrEmpty()) {
            playmateViewModel?.loadPlaymateDetail(playmateId)?.observe(this) { rlt ->
                when (rlt) {
                    is Rlt.Failed -> {
                        showFailedToast(rlt)
                    }

                    is Rlt.Success -> {
                        this@CreateOrderDialog.playmateData = rlt.data
                        updatePlaymateInfo()
                    }
                }
            }
        }
    }

    @SuppressLint("SetTextI18n")
    private fun updatePlaymateInfo() {
        //用户信息
        binding.ivAvatar.setImageUrl(playmateData?.avatar)
        binding.tvName.text = playmateData?.nickname

        //陪玩信息
        binding.tvCategory.text = playmateData?.categoryName
        binding.tvPrice.text =
            "${formatNumberStr((playmateData?.price ?: 0f), false)}/${playmateData?.unit ?: ""}"

        updatePrice()
    }

    private fun updatePrice() {
        val data = playmateData
        val finalPrice = getFinalPrice(data?.price)
        if (finalPrice.hasDiscount()) {
            binding.clDiscount.show()
            binding.vDiscount.text = getCompatString(
                APP_R.string.common_price_discount_new_only,
                formatNumber(finalPrice.discountPercent, true)
            )
            binding.vPriceDiscount.setDiscount(
                -finalPrice.discount, null
            )
            //首单第一个免费
            totalPrice = finalPrice.discountPrice + (playmateData?.price ?: 0f) * max((orderCount - 1), 0)
            binding.tvTotalDetail.text = formatNumberStr(totalPrice ?: 0f, false)

        } else {
            binding.clDiscount.gone()
            totalPrice = (playmateData?.price ?: 0f) * orderCount
            binding.tvTotalDetail.text = formatNumberStr(totalPrice ?: 0f, false)
        }
    }

    override fun observeViewModel() {
        super.observeViewModel()
        walletViewModel?.coinLD?.observe(viewLifecycleOwner) {
            binding.tvWalletCoin.text = formatNumberStr(it, false)
        }
        discountLD.observe(this) {
            updatePrice()
        }
    }

    private fun showEditRemarkDialog() {
        EditRemarkDialog().apply {
            setRemark(binding.tvRemarkInput.text?.toString())
            setCallback(object : EditRemarkDialog.IEditRemarkCallback {
                override fun onEditRemark(remark: String?) {
                    this@CreateOrderDialog.remark = remark
                    binding.tvRemarkInput.text = remark
                }
            })
        }.show(childFragmentManager, "EditRemarkDialog")

    }

    private fun pay() {
        val playmateData = playmateData ?: return
        //检查余额
        val coinBalance = WalletModule.getBalance(Currency.COIN)
        val totalPrice = totalPrice
        if (totalPrice != null && coinBalance < totalPrice) {
            //余额不足
            WalletModule.showRechargeDialog(childFragmentManager, Currency.COIN)
            return
        }
        showLoading()
        viewModel.createOrder(
            playmateData.playmateId,
            orderCount,
            remark,
            source
        ).observe(this) { rlt ->
            dismissLoading()
            when (rlt) {
                is Rlt.Failed -> {
                    showToast(rlt)
                }

                is Rlt.Success<CreateOrderRes> -> {
                    handleOrderSuccess(playmateData)
                }
            }
        }
    }

    private fun handleOrderSuccess(data: PlaymateDetailData) {
        val activity = activity ?: return
        Router.build(activity, IM.Session.PATH)
            .putExtra(IM.Session.EXTRA_CHAT_ID, data.uid)
            .start()
        dismiss()
    }

}