package cn.yyxx.eyuangame.core.impl.iab

import android.app.Activity
import android.text.TextUtils
import cn.yyxx.eyuangame.base.entity.SdkChargeInfo
import cn.yyxx.eyuangame.base.utils.Logger
import cn.yyxx.eyuangame.core.entity.ResultInfo
import cn.yyxx.eyuangame.core.impl.SdkBridgeImpl
import cn.yyxx.eyuangame.core.internal.IImplCallback
import cn.yyxx.eyuangame.core.internal.IRequestCallback
import cn.yyxx.eyuangame.core.network.SdkRequest
import cn.yyxx.eyuangame.core.utils.MMKVUtils
import cn.yyxx.support.ResUtils
import cn.yyxx.support.hawkeye.ToastUtils
import com.android.billingclient.api.*
import org.json.JSONException
import org.json.JSONObject

/**
 * @author #Suyghur.
 * Created on 2021/06/28
 */
class ChargeImpl : InAppBilling() {

    //初始化IAB收银台客户端
    //连接谷歌商店
    private lateinit var implCallback: IImplCallback
    private lateinit var chargeInfo: SdkChargeInfo


    fun charge(activity: Activity, chargeInfo: SdkChargeInfo, callback: IImplCallback) {
        if (!checkGoogleApiAvailability(activity)) {
            ToastUtils.toastInfo(activity, "Your phone or Google account does not support In-app Billing")
            callback.onResult(-1, "谷歌iab支付服务不可用")
            return
        }
        this.implCallback = callback
        this.chargeInfo = chargeInfo
        showDialog(activity)

//        checkLocalNotifyFailedOrder(activity)
        getOrderId(activity)
    }

    override fun chargePurchasesUpdated(activity: Activity, purchase: Purchase) {
        Logger.d("chargePurchasesUpdated")
        notifyOrder2Backend(activity, chargeInfo.orderId, purchase, false)
    }

    override fun preRewardPurchasesUpdated(activity: Activity, purchase: Purchase) {
    }

    override fun queryRewardInfo(activity: Activity) {
    }

    /**
     * 查询未消耗订单
     */
    override fun queryChargeInfo(activity: Activity) {
        billingClient?.apply {
            val list = queryPurchases(BillingClient.SkuType.INAPP).purchasesList
            if (list.isNullOrEmpty()) {
                //正常发起支付流程
                querySkuDetails(activity)
            } else {
                Logger.e("存在未消耗订单,发起补单流程,size : ${list.size}")
                run breaking@{
                    if (list.size > 0) {
                        list.forEach { purchase ->
                            if (purchase.sku == SdkBridgeImpl.initBean.rewardId) {
                                Logger.e("存在阻塞的预注册奖励,停止支付流程")
                                if (list.size == 1) {
                                    dismissDialog()
                                    disConnection()
                                    ToastUtils.toastInfo(activity, "In-app Billing has some error , please restart app and try again")
                                    implCallback.onResult(-1, "存在阻塞的预注册奖励,停止支付流程")
                                }
                                //跳出支付流程
                                return@breaking
                            } else {
                                consumeCacheOrder(activity, purchase)
                            }
                        }
                    } else {
                        //发起正常支付流程
                        querySkuDetails(activity)
                    }
                }
            }


//            queryPurchasesAsync(BillingClient.SkuType.INAPP, object : PurchasesResponseListener {
//                override fun onQueryPurchasesResponse(billingResult: BillingResult, list: MutableList<Purchase>) {
//                    logBillingResult("onQueryPurchasesResponse", billingResult)
//                    if (list.isNullOrEmpty()) {
//                        //正常发起支付流程
//                        Logger.d("正常发起支付流程")
//                        querySkuDetails(activity)
//                    } else {
//                        Logger.e("存在未消耗订单,发起补单流程,size : ${list.size}")
//                        run breaking@{
//                            list.forEach { purchase ->
//                                purchase.skus.forEach {
//                                    if (it.equals(SdkBridgeImpl.initBean.rewardId)) {
//                                        Logger.e("存在阻塞的预注册奖励,停止支付流程")
//                                        if (list.size == 1) {
//                                            dismissDialog()
//                                            disConnection()
//                                            ToastUtils.toastInfo(activity, "In-app Billing has some error , please restart app and try again")
//                                            implCallback.onResult(-1, "存在阻塞的预注册奖励,停止支付流程")
//                                        }
//                                        //跳出支付流程
//                                        return@breaking
//                                    } else {
//                                        consumeCacheOrder(activity, purchase)
//                                    }
//                                }
//                            }
//                        }
//                    }
//                }
//            })
        }
    }

    override fun purchasesUpdatedFailed() {
    }

    override fun connectGooglePlayFailed() {
    }

    /**
     * 检查本地通知发货失败订单
     */
    private fun checkLocalNotifyFailedOrder(activity: Activity) {

    }

    /**
     * 获取订单号
     */
    private fun getOrderId(activity: Activity) {
        SdkRequest.instance.createOrder(activity, chargeInfo, object : IRequestCallback {
            override fun onResponse(resultInfo: ResultInfo) {
                if (resultInfo.code == 1 && !TextUtils.isEmpty(resultInfo.data)) {
                    try {
                        val jsonObject = JSONObject(resultInfo.data)
                        chargeInfo.orderId = jsonObject.getString("order_id")
                        Logger.d("order_id ---> ${chargeInfo.orderId}")
                        //获取订单号成功,初始化IAB收银台客户端
                        Logger.d("获取订单号成功,初始化IAB收银台客户端")
                        initializeBillingClient(activity)
                        connectGooglePlay(activity, false)
                    } catch (e: JSONException) {
                        e.printStackTrace()
                        dismissDialog()
                        val msg = if (TextUtils.isEmpty(resultInfo.msg)) {
                            ResUtils.getResString(activity, "yyxx_charge_tv_error")
                        } else {
                            resultInfo.msg
                        }
                        ToastUtils.toastInfo(activity, msg)
                        implCallback.onResult(-1, "获取订单异常")
                    }
                } else {
                    dismissDialog()
                    val msg = if (TextUtils.isEmpty(resultInfo.msg)) {
                        ResUtils.getResString(activity, "yyxx_charge_tv_error")
                    } else {
                        resultInfo.msg
                    }
                    ToastUtils.toastInfo(activity, msg)
                    implCallback.onResult(-1, "获取订单异常")
                }
            }

        })
    }

    /**
     * 查询商品信息
     */
    private fun querySkuDetails(activity: Activity) {
        val skus = mutableListOf<String>()
        skus.add(chargeInfo.productId)
        val params = SkuDetailsParams.newBuilder().setType(BillingClient.SkuType.INAPP).setSkusList(skus).build()
        billingClient?.querySkuDetailsAsync(params) { billingResult, list ->
            logBillingResult("onSkuDetailsResponse", billingResult)
            dismissDialog()
            if (list.isNullOrEmpty()) {
                //查询商品信息失败
                Logger.e("查询商品信息失败")
                ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
                implCallback.onResult(-1, "查询商品信息失败")
                disConnection()
            } else {
                if (list.size == 1) {
                    val skuDetails = list[0]
                    Logger.d("product id : ${skuDetails.sku}")
                    launchBillingFlow(activity, skuDetails)
                } else {
                    ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
                    implCallback.onResult(-1, "查询商品信息异常")
                    disConnection()
                }
            }
        }
    }

    /**
     * 启动收银台
     *
     */
    private fun launchBillingFlow(activity: Activity, skuDetails: SkuDetails) {
        billingClient?.apply {
            if (isReady) {
                val flowParams = BillingFlowParams.newBuilder().setObfuscatedAccountId(chargeInfo.orderId).setSkuDetails(skuDetails).build()

                val billingResult = launchBillingFlow(activity, flowParams)
                logBillingResult("launchBillingFlow", billingResult)
                if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
                    dismissDialog()
                    disConnection()
                    ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
                    implCallback.onResult(-1, "启动谷歌收银台失败")
                }
            } else {
                dismissDialog()
                disConnection()
                ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
                implCallback.onResult(-1, "启动谷歌收银台失败")
            }
        }
    }

    /**
     * 通知服务端发货
     */
    private fun notifyOrder2Backend(activity: Activity, orderId: String, purchase: Purchase, isCache: Boolean = false) {
        SdkRequest.instance.notifyOrder(activity, orderId, purchase.originalJson, object : IRequestCallback {
            override fun onResponse(resultInfo: ResultInfo) {
                if (resultInfo.code == 1) {
                    //消耗订单
                    consumeAsync(activity, purchase, isCache)
                } else {
                    //失败则缓存订单
                    saveOrderInfo(purchase.orderId, orderId)
                    dismissDialog()
                    disConnection()
                    val msg = if (TextUtils.isEmpty(resultInfo.msg)) {
                        ResUtils.getResString(activity, "yyxx_charge_tv_error")
                    } else {
                        resultInfo.msg
                    }
                    ToastUtils.toastInfo(activity, msg)
                    implCallback.onResult(-1, "发货失败")
                }
            }
        })
    }

    /**
     * 消耗缓存订单
     */
    private fun consumeCacheOrder(activity: Activity, purchase: Purchase) {
        //消耗完了再发起支付
        Logger.d("消耗缓存订单 : $purchase")
        var orderId = ""
        purchase.accountIdentifiers?.apply {
            orderId = if (!TextUtils.isEmpty(obfuscatedAccountId)) {
                obfuscatedAccountId!!
            } else {
                //TODO getLocalOrderId
                getOrderInfo(purchase.orderId)
            }
        }
        notifyOrder2Backend(activity, orderId, purchase, true)
//        consumeAsync(activity, purchase.purchaseToken, true)

    }

    /**
     * 消耗订单
     */
    private fun consumeAsync(activity: Activity, purchase: Purchase, isCache: Boolean = false) {
        val consumeParams = ConsumeParams.newBuilder().setPurchaseToken(purchase.purchaseToken).build()
        billingClient?.apply {
            if (isReady) {
                consumeAsync(consumeParams) { billingResult, token ->
                    logBillingResult("onConsumeResponse", billingResult)
                    dismissDialog()
                    if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
                        // saveOrder2Local()
                        if (isCache) {
                            querySkuDetails(activity)
                        } else {
                            implCallback.onResult(0, "支付成功")
                            disConnection()
                        }
                        removeOrderInfo(purchase.orderId)
                    } else {
                        implCallback.onResult(-1, "消耗订单异常")
                        disConnection()
                        ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
                    }
                }
            } else {
                dismissDialog()
                disConnection()
                implCallback.onResult(-1, "消耗订单异常")
                ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
            }
        }
    }

    private fun saveOrderInfo(googleOrderId: String, orderId: String) {
        try {
            MMKVUtils.instance.orderKV.encode(googleOrderId, orderId)
        } catch (e: JSONException) {
            e.printStackTrace()
        }
    }

    private fun getOrderInfo(googleOrderId: String): String {
        val info = MMKVUtils.instance.orderKV.decodeString(googleOrderId)
        Logger.d("getOrderInfo : $info")
        return if (TextUtils.isEmpty(info)) {
            ""
        } else {
            info!!
        }
    }

    private fun removeOrderInfo(googleOrderId: String) {
        MMKVUtils.instance.orderKV.removeValueForKey(googleOrderId)
    }


    companion object {
        val instance: ChargeImpl by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            ChargeImpl()
        }
    }
}