package com.zxhl.cms.googlepay

import android.app.Activity
import android.util.Log
import com.android.billingclient.api.*
import com.android.billingclient.api.BillingClient.BillingResponseCode
import com.android.billingclient.api.BillingClient.SkuType
import com.zxhl.cms.AppContext
import com.zxhl.cms.net.ApiClient
import com.zxhl.cms.net.RxSchedulers
import com.zxhl.cms.net.callback.BaseObserver
import com.zxhl.cms.net.model.other.AnyEntity
import com.zxhl.cms.net.model.uc.GooglePayEntity
import com.zxhl.cms.utils.EventUtils


/**
 * @author (wangXuewei)
 * @datetime 2022-03-09 15:12 GMT+8
 * @detail :
 */
class GooglePayHelper {
    private val TAG = "GooglePayHelper"
    private var mActivity: Activity;
    private var mPayCallBack: GooglePayCallBack? = null;
    private var mConsume: String = "2"
    private var productId = ""
    private var obfuscatedAccountid = ""

    constructor(mActivity: Activity) {
        this.mActivity = mActivity
    }

    /**
     * 购买监听
     */
    private val purchasesUpdatedListener =
        PurchasesUpdatedListener { billingResult, purchases ->
            // To be implemented in a later section.
            Log.d(TAG, "购买监听 code ${billingResult.responseCode}")
            Log.d(TAG, "购买监听 size ${purchases?.size}")
            if (billingResult.responseCode == BillingResponseCode.OK) {
                mConsume = "2"
                //支付成功 同步后台
                if (!purchases.isNullOrEmpty()) {
                    for (i in 0 until purchases.size) {
                        var purchase = purchases[i];
                        Log.d(TAG, "detail ${purchase.originalJson}")
                        Log.d(TAG, "obfuscatedAccountid $obfuscatedAccountid")
                        var googlePayResult = GooglePayResult()
                        googlePayResult.packageName = purchase.packageName
                        googlePayResult.orderId = purchase.orderId
                        googlePayResult.productId = productId
                        googlePayResult.obfuscatedAccountid = obfuscatedAccountid
                        googlePayResult.developerPayload = purchase.developerPayload
                        googlePayResult.purchaseTime = purchase.purchaseTime.toString()
                        googlePayResult.purchaseState = purchase.purchaseState.toString()
                        googlePayResult.purchaseToken = purchase.purchaseToken
                        //购买成功 消耗掉
                        consume(googlePayResult, purchase)
                    }
                }
            } else if (billingResult.responseCode == BillingResponseCode.ITEM_ALREADY_OWNED) {
                //未消耗掉
                mConsume = "1"
                queryPurchases()
                mPayCallBack?.onError("商品未消耗掉 查询补单")
            } else if (billingResult.responseCode == BillingResponseCode.USER_CANCELED) {
                mPayCallBack?.onCancel()
            } else {
                mPayCallBack?.onError("支付异常: code:" + billingResult.responseCode + " msg:" + billingResult.debugMessage)
//                when (billingResult.responseCode) {
//                    BillingResponseCode.SERVICE_TIMEOUT -> {
//                        //服务连接超时
//                    }
//                    BillingResponseCode.FEATURE_NOT_SUPPORTED -> {
//                    }
//                    BillingResponseCode.SERVICE_DISCONNECTED -> {
//                        //服务未连接
//                    }
//                    BillingResponseCode.USER_CANCELED -> {
//                        //取消
//                    }
//                    BillingResponseCode.SERVICE_UNAVAILABLE -> {
//                        //服务不可用
//                    }
//                    BillingResponseCode.BILLING_UNAVAILABLE -> {
//                        //购买不可用
//                    }
//                    BillingResponseCode.ITEM_UNAVAILABLE -> {
//                        //商品不存在
//
//                    }
//                    BillingResponseCode.DEVELOPER_ERROR -> {
//                        //提供给 API 的无效参数
//                    }
//                    BillingResponseCode.ERROR -> {
//                        //错误
//                    }
//                    BillingResponseCode.ITEM_NOT_OWNED -> {
//                        //不可购买
//                    }
//                }
            }
        }

    private var billingClient = BillingClient.newBuilder(AppContext.get())
        .setListener(purchasesUpdatedListener)
        .enablePendingPurchases()
        .build()

    //检查之前的商品是否被消费
    fun init() {
        //已经连接查询订单
        if (billingClient.isReady) {
            Log.d(TAG, "init 已连接")
            queryPurchases()
        } else {
            //开始连接
            Log.d(TAG, "init 开始连接")
            billingClient.startConnection(object : BillingClientStateListener {
                override fun onBillingSetupFinished(billingResult: BillingResult) {
                    if (billingResult.responseCode == BillingResponseCode.OK) {
                        //BillingClient准备好了。你可以在这里查询购买情况。
                        Log.d(TAG, "init 连接成功")
                        queryPurchases()
                    } else {
                        Log.d(TAG, "init 连接失败 code:" + billingResult.responseCode)
                        mPayCallBack?.onError("初始化连接失败 code:" + billingResult.responseCode + " msg:" + billingResult.debugMessage)
                    }
                }

                override fun onBillingServiceDisconnected() {
                    // Try to restart the connection on the next request to
                    // Google Play by calling the startConnection() method.
                    Log.d(TAG, "init onBillingServiceDisconnected")
                    mPayCallBack?.onError("初始化连接失败 onBillingServiceDisconnected")
                }
            })
        }

    }

    /**
     * 购买商品
     */
    private fun purchase(mSku: String, orderId: String) {
        productId = mSku
        obfuscatedAccountid = orderId
        if (billingClient.isReady) {
            val skuList: MutableList<String> = ArrayList()
            skuList.add(mSku)
            val params = SkuDetailsParams.newBuilder()
            params.setSkusList(skuList).setType(SkuType.INAPP)
            billingClient.querySkuDetailsAsync(
                params.build()
            ) { billingResult, skuDetailsList ->
                // Process the result.
                if (billingResult.responseCode == BillingResponseCode.OK) {
                    if (!skuDetailsList.isNullOrEmpty()) {
                        for (i in 0 until skuDetailsList.size) {
                            val skuDetails = skuDetailsList[i]
                            Log.d(TAG, "purchase skuDetails $skuDetails")
                            if (mSku == skuDetails.sku) {
                                val flowParams = BillingFlowParams.newBuilder()
                                    .setSkuDetails(skuDetails)
//                                    .setObfuscatedProfileId()
                                    .setObfuscatedAccountId(orderId)
                                    .build()
                                //吊起支付
                                val responseCode =
                                    billingClient.launchBillingFlow(
                                        mActivity,
                                        flowParams
                                    ).responseCode
                                Log.d(TAG, "purchase 去支付 code $responseCode")
                            }
                        }

                    } else {
                        Log.d(TAG, "purchase 未查询到商品")
                        mPayCallBack?.onError("GooglePay 商品未查询到")
                    }
                } else {
                    Log.d(TAG, "purchase 查询连接失败 cede" + billingResult.responseCode)
                    mPayCallBack?.onError("GooglePay error code:" + billingResult.responseCode + " msg:" + billingResult.debugMessage)
                }
            }
        } else {
            Log.d(TAG, "purchase 购买 未连接")
            mPayCallBack?.onError("GooglePay purchase 购买 未连接")
        }
    }

    /**
     * 消耗商品
     *
     * @param purchaseToken 商品token
     */
    private fun consume(googlePayResult: GooglePayResult, purchase: Purchase) {
        if (billingClient.isReady) {
            val consumeParams =
                ConsumeParams.newBuilder()
                    .setPurchaseToken(googlePayResult.purchaseToken)
                    .build()
            billingClient.consumeAsync(
                consumeParams
            ) { billingResult, s ->
                if (billingResult.responseCode == BillingResponseCode.OK) {
                    // Handle the success of the consume operation.
                    Log.d(TAG, "consume 消耗成功${googlePayResult.purchaseToken}")
                    //同步后台 消耗掉
                    updateToService(googlePayResult, purchase)
                    productId = ""
                    obfuscatedAccountid = ""
                } else {
                    Log.d(TAG, "consume 消耗失败 code:" + billingResult.responseCode)
                    mPayCallBack?.onError("consume 消耗失败 code:" + billingResult.responseCode + " msg:" + billingResult.debugMessage)//支付成功
                }
            }
        } else {
            billingClient.startConnection(object : BillingClientStateListener {
                override fun onBillingSetupFinished(billingResult: BillingResult) {
                    if (billingResult.responseCode == BillingResponseCode.OK) {
                        //重连后 消耗掉
                        val consumeParams =
                            ConsumeParams.newBuilder()
                                .setPurchaseToken(googlePayResult.purchaseToken)
                                .build()
                        billingClient.consumeAsync(
                            consumeParams
                        ) { billingResult, s ->
                            if (billingResult.responseCode == BillingResponseCode.OK) {
                                // Handle the success of the consume operation.
                                Log.d(TAG, "consume 消耗成功${googlePayResult.purchaseToken}")
                                //同步后台 消耗掉
                                updateToService(googlePayResult, purchase)
                                productId = ""
                                obfuscatedAccountid = ""
                            } else {
                                Log.d(TAG, "consume 消耗失败 code:" + billingResult.responseCode)
                                mPayCallBack?.onError("consume 消耗失败 code:" + billingResult.responseCode + " msg:" + billingResult.debugMessage)
                            }
                        }
                    } else {
//                        Log.d(TAG, "consume init 连接失败 code:" + billingResult.responseCode)
                        mPayCallBack?.onError("consume 消耗连接失败 code:" + billingResult.responseCode + " msg:" + billingResult.debugMessage)
                    }
                }

                override fun onBillingServiceDisconnected() {
                    // Try to restart the connection on the next request to
                    // Google Play by calling the startConnection() method.
                    mPayCallBack?.onError("consume onBillingServiceDisconnected")
                }
            })
        }
    }

    /**
     * 补单消耗商品
     *
     * @param purchaseToken 商品token
     */
    private fun consume2(purchaseToken: String) {
        if (billingClient.isReady) {
            val consumeParams =
                ConsumeParams.newBuilder()
                    .setPurchaseToken(purchaseToken)
                    .build()
            billingClient.consumeAsync(
                consumeParams
            ) { billingResult, s ->
                if (billingResult.responseCode == BillingResponseCode.OK) {
                    // Handle the success of the consume operation.
                    Log.d(TAG, "consume 消耗成功$purchaseToken")
                } else {
                    Log.d(TAG, "consume 消耗失败 code:" + billingResult.responseCode)
                }
            }
        } else {
            billingClient.startConnection(object : BillingClientStateListener {
                override fun onBillingSetupFinished(billingResult: BillingResult) {
                    if (billingResult.responseCode == BillingResponseCode.OK) {
                        //重连后 消耗掉
                        val consumeParams =
                            ConsumeParams.newBuilder()
                                .setPurchaseToken(purchaseToken)
                                .build()
                        billingClient.consumeAsync(
                            consumeParams
                        ) { billingResult, s ->
                            if (billingResult.responseCode == BillingResponseCode.OK) {
                                // Handle the success of the consume operation.
                                Log.d(TAG, "consume 消耗成功$purchaseToken")
                            } else {
                                Log.d(TAG, "consume 消耗失败 code:" + billingResult.responseCode)
                            }
                        }
                    } else {
                        Log.d(TAG, "consume init 连接失败 code:" + billingResult.responseCode)
                    }
                }

                override fun onBillingServiceDisconnected() {
                    // Try to restart the connection on the next request to
                    // Google Play by calling the startConnection() method.
                    Log.d(TAG, "consume init onBillingServiceDisconnected")
                }
            })
        }
    }

    /**
     * 补单操作 查询购买交易，以确保所有购买交易都得到成功处理，如购买未发货，或者未消耗
     */
    private fun queryPurchases() {
        if (billingClient.isReady) {
            billingClient.queryPurchasesAsync(
                SkuType.INAPP
            ) { billingResult, mutableList ->
                if (billingResult.responseCode == BillingResponseCode.OK) {
                    if (mutableList.isNullOrEmpty()) {
                        Log.d(TAG, "queryPurchases null")
                    } else {
                        for (i in 0 until mutableList.size) {
                            Log.d(TAG, "queryPurchases init " + mutableList[i].purchaseState)
                            if (mutableList[i].purchaseState == Purchase.PurchaseState.PURCHASED) {
                                //已购买,消耗即可
                                consume2(mutableList[i].purchaseToken)
                            }
                        }
                    }
                } else {
                    Log.d(TAG, "queryPurchases error code" + billingResult.responseCode)
                }
            }
        } else {
            billingClient.startConnection(object : BillingClientStateListener {
                override fun onBillingSetupFinished(billingResult: BillingResult) {
                    if (billingResult.responseCode == BillingResponseCode.OK) {
                        //BillingClient准备好了。你可以在这里查询购买情况。
                        Log.d(TAG, "queryPurchases init 连接成功")
                    } else {
                        Log.d(TAG, "queryPurchases init 连接失败 code:" + billingResult.responseCode)
                    }
                }

                override fun onBillingServiceDisconnected() {
                    // Try to restart the connection on the next request to
                    // Google Play by calling the startConnection() method.
                    Log.d(TAG, "queryPurchases init onBillingServiceDisconnected")
                }
            })
        }
    }


    /**
     * google支付
     */
    fun googlePay(goodsId: String,payMode: String, payCallBack: GooglePayCallBack) {
        mPayCallBack = payCallBack
        //向服务端获取订单ID
        ApiClient.userInfoAPi.googlePay(goodsId, "4", "", "", payMode)
            .compose(RxSchedulers.observableIO2Main())
            .subscribe(object : BaseObserver<GooglePayEntity>() {
                override fun onSuccess(result: GooglePayEntity?) {
                    if (result != null) {
                        var sku = goodsId.replace("-", "_")
                        Log.d(TAG, "请求支付${sku}")
                        purchase("xymh_$sku", result.outTradeNo ?: "")
                    } else {
                        Log.d(TAG, "未获取到订单")
                        mPayCallBack?.onError("GooglePay 未获取到订单数据")
                    }
                }

                override fun onFailure(e: Throwable?, code: String?, errorMsg: String?) {
//                    EventUtils.onEvent("GooglePay Fail:$errorMsg")
                    mPayCallBack?.onError("订单接口 Error:$errorMsg")
                }
            })
    }

    /**
     * google支付 成功后 同步给服务器
     */
    private fun updateToService(googlePayResult: GooglePayResult, purchase: Purchase) {
        //支付成功 向后端同步 网络问题再次重试
        ApiClient.shopApi.googlePaySuccess(googlePayResult)
            .compose(RxSchedulers.observableIO2Main())
            .subscribe(object : BaseObserver<Any>() {
                override fun onSuccess(result: Any?) {
                    EventUtils.onEvent("googlepaysuccess_onsuccess")
                    mPayCallBack?.onPaySuccess(googlePayResult, purchase.originalJson)//支付成功
                    if (result != null) {
                    }
                }

                override fun onFailure(e: Throwable?, code: String?, errorMsg: String?) {
                    EventUtils.onEvent("googlepaysuccess_onfailure", "${errorMsg}")
                    mPayCallBack?.onError("服务器同步失败 code:$code msg:$errorMsg")
                }
            })
    }


    fun release() {
        if (billingClient.isReady) {
            billingClient.endConnection();
        }
        mPayCallBack = null
        Log.d(TAG, "billingClient release")
    }

}