package com.cheng.bole.ui.fragment.mine.vip

import android.annotation.SuppressLint
import android.text.TextUtils
import android.view.View
import android.window.OnBackInvokedDispatcher
import androidx.activity.addCallback
import androidx.core.content.ContextCompat
import androidx.core.os.BuildCompat
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.cheng.bole.R
import com.cheng.bole.common.EventConstants
import com.cheng.bole.databinding.FragmentVipBinding
import com.cheng.bole.event.PayStatusEnum
import com.cheng.bole.event.PayStatusEvent
import com.cheng.bole.event.VipPaySuccessEvent
import com.cheng.bole.manager.EventReportManager
import com.cheng.bole.manager.LoginManager
import com.cheng.bole.manager.UserConfigManager
import com.cheng.bole.ui.activity.MainActivity
import com.cheng.bole.ui.dialog.PayTipDialog
import com.cheng.bole.utils.UrlHelper
import com.cheng.bole.utils.pay.PayUtils
import com.bytedance.ads.convert.event.ConvertReportHelper
import com.example.base.common.RxBus
import com.example.base.decoration.FirstItemOffsetDecoration
import com.example.base.decoration.GridSpaceItemDecoration
import com.example.base.decoration.SpacesItemDecoration
import com.example.base.extensions.getColor
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.ui.BaseFragment
import com.example.base.utils.DensityUtils
import com.example.base.utils.SpanUtils
import com.google.gson.Gson
import com.tencent.mm.opensdk.openapi.IWXAPI
import com.tencent.mm.opensdk.openapi.WXAPIFactory
import com.cheng.bole.common.Constants
import org.jetbrains.anko.sdk27.listeners.onCheckedChange
import org.jetbrains.anko.startActivity
import java.text.DecimalFormat

class VipFragment : BaseFragment<FragmentVipBinding, VipViewModel>() {
    private val origin by lazy { arguments?.getString("origin") ?: "center" }
    private val isGuide by lazy { origin == "guide" }

    private lateinit var api: IWXAPI
    private var isAgree = false
    private var payType = 0 //0微信支付 1支付宝支付
    private var totalPrice = 0f

    private val mealAdapter by lazy { VipMealAdapter() }
    private val tipAdapter by lazy { VipTipAdapter() }

    private var userInfo: com.cheng.bole.bean.UserEntity? = null
    private var vipGoodsEntity: com.cheng.bole.bean.VipGoodsEntity? = null
    private var orderEntity: com.cheng.bole.bean.OrderPayEntity? = null

    override fun initView() {
        super.initView()
        mTitleBar?.background = null
        setBackColor(R.color.white)

        binding.tvPrice.typeface = Constants.dDIN_PRO_M
        binding.tvTipTitle.typeface = Constants.almmsht

        binding.rvMeal.adapter = mealAdapter

        binding.rvTip.adapter = tipAdapter
        tipAdapter.setList(com.cheng.bole.bean.VipTipItemEntity.getVipTipList())

        binding.cbAgree.visibility = if (UserConfigManager.isPayAgreementEnable()) View.VISIBLE else View.GONE
        binding.tvAgree.visibility = if (UserConfigManager.isPayAgreementEnable()) View.VISIBLE else View.GONE
    }

    override fun initData() {
        super.initData()
        api = WXAPIFactory.createWXAPI(requireContext(), Constants.WechatAppId)

        mViewModel.userInfo()
        mViewModel.getGoodsList()
    }

    @SuppressLint("NotifyDataSetChanged", "SetTextI18n")
    override fun initListener() {
        super.initListener()
        setBackPressed()
        mTitleBar?.setNavigationOnClickListener {
            if (isGuide) {
                requireActivity().startActivity<MainActivity>()
                EventReportManager.eventReport(EventConstants.GUIDE_SKIP, "icon", pageDuration())
            } else {
                requireActivity().finish()
            }
        }

        mealAdapter.setOnItemClickListener { _, _, i ->
            val item = mealAdapter.getItem(i)
            if (item.goods_id == vipGoodsEntity?.goods_id) return@setOnItemClickListener
            mealAdapter.data.forEach { it.checked = it.goods_id == item.goods_id }
            mealAdapter.notifyDataSetChanged()
            EventReportManager.eventReport(EventConstants.GOODS_SELECT, "${origin}:${item.goods_name}", Gson().toJson(item))

            vipGoodsEntity = item
            setPrice(vipGoodsEntity!!.price.toFloat())
            releasePayType()
        }
        binding.tvWxPay.onClick {
            payType = 0
            checkPayType()
            EventReportManager.eventReport(EventConstants.PAY_SELECT, "weixin", origin)
        }
        binding.tvAliPay.onClick {
            payType = 1
            checkPayType()
            EventReportManager.eventReport(EventConstants.PAY_SELECT, "alipay", origin)
        }
        binding.nextBtn.onClick {
            if (vipGoodsEntity == null) return@onClick
            if (!UserConfigManager.getNoLoginPay() && !LoginManager.isLogin()) {
                toast("请登录后支付")
                return@onClick
            }
            if (payType == 0 && !api.isWXAppInstalled) {
                toast("您没有安装微信客户端,请先下载安装")
                return@onClick
            }
            if (UserConfigManager.isPayAgreementEnable() && !isAgree) {
                val f = PayTipDialog.newInstance(!TextUtils.isEmpty(vipGoodsEntity?.sign_value) && payType == 1)
                f.setOnSelectListener {
                    binding.cbAgree.isChecked = true
                    if (this.payType == 0) {
                        mViewModel.payCreateOrder(vipGoodsEntity!!.goods_id, "weixin", origin)
                    } else {
                        mViewModel.payCreateOrder(vipGoodsEntity!!.goods_id, "alipay", origin)
                    }
                }
                f.show(childFragmentManager, PayTipDialog::class.java.simpleName)
            } else {
                if (this.payType == 0) {
                    mViewModel.payCreateOrder(vipGoodsEntity!!.goods_id, "weixin", origin)
                } else {
                    mViewModel.payCreateOrder(vipGoodsEntity!!.goods_id, "alipay", origin)
                }
            }
            EventReportManager.eventReport(EventConstants.PAY_PAY, if (payType == 0) "weixin" else "alipay", Gson().toJson(vipGoodsEntity))
        }

        binding.cbAgree.onCheckedChange { _, isChecked ->
            isAgree = isChecked
        }

        binding.tvAgree.onClick {
            binding.cbAgree.isChecked = !binding.cbAgree.isChecked
        }
    }

    @SuppressLint("SetTextI18n")
    override fun initObserve() {
        super.initObserve()
        mViewModel.userInfoLiveData.observe(this) {
            userInfo = it
        }
        mViewModel.mealListLiveData.observe(this) { list ->
            if (list.size <= 3) {
                binding.rvMeal.layoutManager = GridLayoutManager(requireContext(), 3)
                binding.rvMeal.setPadding(DensityUtils.dp2px(20f), 0, DensityUtils.dp2px(20f),0)
                binding.rvMeal.addItemDecoration(GridSpaceItemDecoration(3, 0, DensityUtils.dp2px(10f)))
            } else {
                binding.rvMeal.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false)
                binding.rvMeal.addItemDecoration(SpacesItemDecoration(DensityUtils.dp2px(10f), RecyclerView.HORIZONTAL))
                binding.rvMeal.addItemDecoration(FirstItemOffsetDecoration(DensityUtils.dp2px(20f), FirstItemOffsetDecoration.left))
            }

            mealAdapter.setList(list)

            vipGoodsEntity = list.find { it.checked }
            if (vipGoodsEntity == null && list.isNotEmpty()) {
                vipGoodsEntity = list[0]
            }
            if (vipGoodsEntity != null) {
                setPrice(vipGoodsEntity!!.price.toFloat())
                releasePayType()
            }
            initPrivacyTv()
        }
        mViewModel.createOrderLiveData.observe(this) {
            orderEntity = it
            if (this.payType == 0) {
                PayUtils.toWXPay(requireActivity(), it)
            } else {
                PayUtils.toAliPay(requireActivity(), it.payParam, "")
            }
        }

        val payStatusDisposable = RxBus.defaultInstance.toObservable(PayStatusEvent::class.java).subscribe {
            when (it.payStatus) {
                PayStatusEnum.PAY_SUCCESS -> {
                    toast("支付成功")
                    sendBDReport(true)
                    EventReportManager.eventReport(
                        EventConstants.PAY_SUCCESS,
                        if (payType == 0) "weixin" else "alipay",
                        "{isGuide:$isGuide, orderId:${orderEntity?.orderId}, meal:${Gson().toJson(vipGoodsEntity)}}"
                    )
                    if (isGuide) {
                        requireActivity().startActivity<MainActivity>()
                    } else {
                        RxBus.defaultInstance.post(VipPaySuccessEvent())
                        requireActivity().finish()
                    }
                }

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

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

    private fun setPrice(price: Float) {
        totalPrice = if (price < 0) 0f else price
        SpanUtils.with(binding.tvPrice)
            .append("￥")
            .setFontSize(13, true)
            .append(DecimalFormat("0.##").format(totalPrice))
            .append(formatPricePeriod(vipGoodsEntity!!.value))
            .setFontSize(13, true)
            .create()
        SpanUtils.with(binding.tvOriginPrice)
            .append("￥${DecimalFormat("0.##").format(vipGoodsEntity!!.origin_price.toFloat())}")
            .setStrikethrough()
            .create()
    }

    private fun formatPricePeriod(value: String): String {
        if (value == "#") {
            return "/终生"
        } else if (value.endsWith("m")) {
            val monthStr = value.replace("m", "")
            if (!TextUtils.isEmpty(monthStr)) {
                val month = monthStr.toInt()
                return if (month >= 12) {
                    "/${if (month / 12 > 1) "${month / 12}" else ""}年"
                } else if (month % 3 == 0) {
                    "/${if (month / 3 > 1) "${month / 3}" else ""}季"
                } else {
                    "/${if (month > 1) "$month" else ""}月"
                }
            }
        }
        return ""
    }

    private fun checkPayType() {
        if (payType == 0) {
            val start = ContextCompat.getDrawable(requireContext(), R.mipmap.ic_wx_pay)
            val end = ContextCompat.getDrawable(requireContext(), R.mipmap.ic_pay_true)
            binding.tvWxPay.setCompoundDrawablesRelativeWithIntrinsicBounds(start, null, end, null)

            val start2 = ContextCompat.getDrawable(requireContext(), R.mipmap.ic_ali_pay)
            val end2 = ContextCompat.getDrawable(requireContext(), R.mipmap.ic_pay_false)
            binding.tvAliPay.setCompoundDrawablesRelativeWithIntrinsicBounds(start2, null, end2, null)
        } else {
            val start = ContextCompat.getDrawable(requireContext(), R.mipmap.ic_ali_pay)
            val end = ContextCompat.getDrawable(requireContext(), R.mipmap.ic_pay_true)
            binding.tvAliPay.setCompoundDrawablesRelativeWithIntrinsicBounds(start, null, end, null)

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

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

        if (vipGoodsEntity?.pay_type!!.startsWith("alipay")) {
            payType = 1
        }
        if (vipGoodsEntity?.pay_type!!.startsWith("weixin")) {
            payType = 0
        }

        checkPayType()
    }

    private fun initPrivacyTv() {
        val spanUtils = SpanUtils.with(binding.tvAgree)
            .append("我已阅读并同意")
            .append("《会员服务协议规则》")
            .setClickSpan(getColor(R.color.color_466afd), false) {
                UrlHelper.startUserAgreement(requireContext(), "会员服务协议规则")
            }
        if (!TextUtils.isEmpty(vipGoodsEntity?.sign_value) && payType == 1) {
            spanUtils.append("和")
            spanUtils.append("《自动续费服务规则》")
            spanUtils.setClickSpan(getColor(R.color.color_466afd), false) {
                UrlHelper.startRenewAgreement(requireContext())
            }
        }
        spanUtils.create()
    }

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

    @SuppressLint("UnsafeOptInUsageError")
    private fun setBackPressed() {
        if (BuildCompat.isAtLeastT()) {
            requireActivity().onBackInvokedDispatcher.registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT) {
                if (isGuide) {
                    requireActivity().startActivity<MainActivity>()
                    EventReportManager.eventReport(EventConstants.GUIDE_SKIP, "back", pageDuration())
                } else {
                    requireActivity().finish()
                }
            }
        } else {
            requireActivity().onBackPressedDispatcher.addCallback(this) {
                if (isGuide) {
                    requireActivity().startActivity<MainActivity>()
                    EventReportManager.eventReport(EventConstants.GUIDE_SKIP, "back", pageDuration())
                } else {
                    requireActivity().finish()
                }
            }
        }
    }
}