package com.cheng.blzb.ui.dialog

import android.annotation.SuppressLint
import android.app.Dialog
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import com.bytedance.ads.convert.event.ConvertReportHelper
import com.cheng.blzb.R
import com.cheng.blzb.bean.OrderPayEntity
import com.cheng.blzb.bean.VipGoodsEntity
import com.cheng.blzb.common.Constants
import com.cheng.blzb.common.EventConstants
import com.cheng.blzb.databinding.DialogBuySeatBinding
import com.cheng.blzb.event.PayStatusEnum
import com.cheng.blzb.event.PayStatusEvent
import com.cheng.blzb.event.PaySuccessEvent
import com.cheng.blzb.manager.DialogEnum
import com.cheng.blzb.manager.EventReportManager
import com.cheng.blzb.manager.LoginManager
import com.cheng.blzb.manager.UserConfigManager
import com.cheng.blzb.net.ApiFactory
import com.cheng.blzb.utils.pay.PayUtils
import com.example.base.common.RxBus
import com.example.base.dialog.LoadingDialog
import com.example.base.extensions.gone
import com.example.base.extensions.onClick
import com.example.base.extensions.toast
import com.example.base.extensions.visible
import com.example.base.utils.L
import com.example.base.utils.ScreenUtils
import com.example.base.utils.SpanUtils
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.tencent.mm.opensdk.openapi.IWXAPI
import com.tencent.mm.opensdk.openapi.WXAPIFactory
import io.reactivex.disposables.Disposable
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import okhttp3.RequestBody.Companion.toRequestBody
import java.text.DecimalFormat

class BuySeatDialog : DialogFragment() {
    private lateinit var api: IWXAPI

    private var payType = 0 // 0 微信 1 支付宝

    private var goodsEntity: VipGoodsEntity? = null
    private var orderEntity: OrderPayEntity? = null

    private var count = 1
    private var totalPrice = 0f

    private val loadingDialog by lazy { LoadingDialog(requireContext()) }

    private var payStatusDisposable: Disposable? = null

    //是否显示订单支付结果查询提示
    private var showQueryTip = false

    var queryOrderJob: Job? = null

    private var mOnBackListener: (() -> Unit)? = null     //回调事件

    private lateinit var binding: DialogBuySeatBinding

    override fun onStart() {
        super.onStart()
        val window = dialog?.window
        val windowParams = window?.attributes
        windowParams?.dimAmount = 0.7f
        windowParams?.width = ScreenUtils.getWindowSize().x
        windowParams?.gravity = Gravity.BOTTOM
        windowParams?.windowAnimations = R.style.dialog_bottom
        dialog?.window?.attributes = windowParams

        showQueryTipDialog()
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        isCancelable = false
        return super.onCreateView(inflater, container, savedInstanceState)
    }

    @SuppressLint("NotifyDataSetChanged")
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val view = layoutInflater.inflate(R.layout.dialog_buy_seat, null)

        binding = DialogBuySeatBinding.bind(view)

        initView()
        initListener()
        initObserver()
        initData()

        val dialog = Dialog(requireContext())
        dialog.setContentView(view)
        return dialog
    }

    private fun initView() {
        binding.tvTitle.typeface = Constants.douyinsansB
        binding.tvPrice.typeface = Constants.dDIN_PRO_M
        binding.tvCount.typeface = Constants.dDIN_PRO_M
    }

    @SuppressLint("SetTextI18n")
    private fun initData() {
        api = WXAPIFactory.createWXAPI(requireContext(), Constants.WechatAppId)

        goodsEntity = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            arguments?.getSerializable("goods", VipGoodsEntity::class.java)
        } else {
            arguments?.getSerializable("goods") as? VipGoodsEntity
        }
        if (goodsEntity != null) {
            binding.tvName.text = goodsEntity!!.goods_name
            SpanUtils.with(binding.tvOriginPrice)
                .append("${DecimalFormat("0.##").format(goodsEntity!!.origin_price.toFloat())}元/次")
                .setStrikethrough()
                .create()
            totalPrice = goodsEntity!!.price.toFloat()
            binding.tvPrice.text = "￥${DecimalFormat("0.##").format(totalPrice)}"
            releasePayType()
        }
    }

    @SuppressLint("SetTextI18n")
    private fun initListener() {
        binding.ivClose.onClick { dismiss() }

        binding.ivAdd.onClick {
            count++
            binding.tvCount.text = "$count"
            totalPrice = goodsEntity!!.price.toFloat() * count
            binding.tvPrice.text = "￥${DecimalFormat("0.##").format(totalPrice)}"
            binding.ivSubtract.setImageResource(R.mipmap.ic_subtract_count_enable)
        }

        binding.ivSubtract.onClick {
            if (count > 1) {
                count--
                binding.tvCount.text = "$count"
                totalPrice = goodsEntity!!.price.toFloat() * count
                binding.tvPrice.text = "￥${DecimalFormat("0.##").format(totalPrice)}"
                binding.ivSubtract.setImageResource(if (count > 1) R.mipmap.ic_subtract_count_enable else R.mipmap.ic_subtract_count_disable)
            }
        }

        binding.tvWxPay.onClick {
            payType = 0
            checkPayType()
        }

        binding.tvAliPay.onClick {
            payType = 1
            checkPayType()
        }

        binding.btnPay.onClick {
            if (goodsEntity == null) return@onClick
            if (!UserConfigManager.getNoLoginPay() && !LoginManager.isLogin()) {
                toast("请登录后支付")
                return@onClick
            }
            if (payType == 0 && !api.isWXAppInstalled) {
                toast("您没有安装微信客户端,请先下载安装")
                return@onClick
            }
            if (payType == 0) {
                if (!TextUtils.isEmpty(goodsEntity!!.weixinMpOriId)) {
                    payCreateOrder("combo")
                } else {
                    payCreateOrder("weixin")
                }
            } else if (payType == 1) {
                payCreateOrder("alipay")
            }
            EventReportManager.eventReport(
                EventConstants.PAY_PAY,
                if (payType == 0) "weixin" else "alipay",
                Gson().toJson(goodsEntity)
            )
        }
    }

    private fun initObserver() {
        payStatusDisposable = RxBus.defaultInstance.toObservable(PayStatusEvent::class.java).subscribe {
            when (it.payStatus) {
                PayStatusEnum.PAY_SUCCESS -> {
                    getOrderInfo(orderEntity!!.orderId)
                }

                PayStatusEnum.PAY_CANCEL -> {
                    toast("已取消支付")
                    sendBDReport(false)
                    EventReportManager.eventReport(EventConstants.PAY_CANCEL, if (payType == 0) "weixin" else "alipay", "{orderId:${orderEntity?.orderId}")
                }

                else -> {
                    toast("已取消支付")
                    sendBDReport(true)
                    EventReportManager.eventReport(if (payType == 0) EventConstants.ERROR_CLIENT_WXPAY_ERR else EventConstants.ERROR_CLIENT_ALIPAY_ERR, "{orderId:${orderEntity?.orderId}", it.message)
                }
            }
        }
    }

    private fun payCreateOrder(payType: String) {
        loadingDialog.show()
        lifecycleScope.launch {
            try {
                val json = JsonObject()
                json.addProperty("goods_id", goodsEntity!!.goods_id)
                json.addProperty("pay_type", payType)
                json.addProperty("source", "corp")
                json.addProperty("pay_source", "app")
                val extra = JsonObject()
                extra.addProperty("add_corp_limit", "$count")
                json.add("extra", extra)

                val response = ApiFactory.apiService.payCreateOrder(json.toString().toRequestBody())
                if (response.status) {
                    orderEntity = response.data
                    if (this@BuySeatDialog.payType == 0) {
                        if (!TextUtils.isEmpty(goodsEntity?.weixinMpOriId)) {
                            PayUtils.toWXMPPay(requireActivity(), orderEntity!!.outTradeNo, goodsEntity!!.weixinMpOriId)
                            showQueryTip = true
                        } else {
                            PayUtils.toWXPay(requireActivity(), response.data)
                        }
                    } else if (this@BuySeatDialog.payType == 1) {
                        PayUtils.toAliPay(requireActivity(), response.data.payParam, "")
                    }
                } else toast(response.message, true)
                loadingDialog.dismiss()
            } catch (e: Exception) {
                loadingDialog.dismiss()
                L.d(e)
            }
        }
    }

    private fun getOrderInfo(orderId: String) {
        loadingDialog.show()
        loadingDialog.setMessage("支付结果查询中")
        cancelJob()
        queryOrderJob = lifecycleScope.launch {
            try {
                repeat(10) {
                    val response = ApiFactory.apiService.getOrderInfo(orderId)
                    if (response.status) {
                        if (response.data.status == "2") {
                            toast("支付成功")
                            sendBDReport(true)
                            EventReportManager.eventReport(
                                EventConstants.PAY_SUCCESS,
                                if (payType == 0) "weixin" else "alipay",
                                "{orderId:${orderEntity?.orderId}, meal:${Gson().toJson(goodsEntity)}}"
                            )
                            RxBus.defaultInstance.post(PaySuccessEvent())
                            cancel()
                        }
                        delay(2000)
                    } else {
                        toast(response.message, true)
                        cancel()
                    }
                }
                loadingDialog.dismiss()
            } catch (e: Exception) {
                loadingDialog.dismiss()
                L.d(e)
            }
        }
    }

    private fun cancelJob() {
        queryOrderJob?.cancel()
        queryOrderJob = null
    }

    private fun releasePayType() {
        val list = goodsEntity?.pay_type?.split(",")?.map { it.trim() }?.toList()
        val globalPayType = UserConfigManager.getPayType()
        if (list?.find { it == "alipay" } != null && globalPayType.find { it == "alipay" } != null) {
            binding.tvAliPay.visible()
        } else {
            binding.tvAliPay.gone()
        }
        if (list?.find { it == "weixin" } != null && globalPayType.find { it == "weixin" } != null) {
            binding.tvWxPay.visible()
        } else {
            binding.tvWxPay.gone()
        }

        if (goodsEntity?.pay_type!!.startsWith("weixin") && binding.tvWxPay.isVisible) {
            payType = 0
        }
        if (goodsEntity?.pay_type!!.startsWith("alipay") && binding.tvAliPay.isVisible) {
            payType = 1
        }

        checkPayType()
    }

    private fun checkPayType() {
        if (payType == 0) {
            val start1 = ContextCompat.getDrawable(requireContext(), R.mipmap.ic_wx_pay)
            val end1 = ContextCompat.getDrawable(requireContext(), R.mipmap.ic_pay_checked3)
            binding.tvWxPay.setCompoundDrawablesRelativeWithIntrinsicBounds(start1, null, end1, null)

            val start2 = ContextCompat.getDrawable(requireContext(), R.mipmap.ic_ali_pay)
            val end2 = ContextCompat.getDrawable(requireContext(), R.mipmap.ic_pay_default3)
            binding.tvAliPay.setCompoundDrawablesRelativeWithIntrinsicBounds(start2, null, end2, null)
        } else if (payType == 1) {
            val start1 = ContextCompat.getDrawable(requireContext(), R.mipmap.ic_ali_pay)
            val end1 = ContextCompat.getDrawable(requireContext(), R.mipmap.ic_pay_checked3)
            binding.tvAliPay.setCompoundDrawablesRelativeWithIntrinsicBounds(start1, null, end1, null)

            val start2 = ContextCompat.getDrawable(requireContext(), R.mipmap.ic_wx_pay)
            val end2 = ContextCompat.getDrawable(requireContext(), R.mipmap.ic_pay_default3)
            binding.tvWxPay.setCompoundDrawablesRelativeWithIntrinsicBounds(start2, null, end2, null)
        }
    }

    private fun sendBDReport(isSuccess: Boolean) {
        ConvertReportHelper.onEventPurchase(
            "corp",
            goodsEntity!!.goods_name,
            goodsEntity!!.goods_id,
            1,
            if (payType == 0) "weixin" else "alipay",
            "¥",
            isSuccess,
            totalPrice.toInt()
        )
    }

    private fun showQueryTipDialog() {
        if (showQueryTip) {
            val f = TipDialog.newInstance("温馨提示", "是否已完成支付", "未支付", "已支付", false)
            f.setOnSelectListener {
                if (it == DialogEnum.CLICK_OK) {
                    getOrderInfo(orderEntity!!.orderId)
                }
            }
            f.show(childFragmentManager, TipDialog::class.java.simpleName)
            showQueryTip = false
        }
    }

    fun setOnSelectListener(listener: () -> Unit) {
        mOnBackListener = listener
    }

    override fun onDestroy() {
        cancelJob()
        payStatusDisposable?.dispose()
        super.onDestroy()
    }

    companion object {
        fun newInstance(goods: VipGoodsEntity): BuySeatDialog {
            val arg = Bundle()
            arg.putSerializable("goods", goods)
            val fragment = BuySeatDialog()
            fragment.arguments = arg
            return fragment
        }
    }
}