package com.tgv.malware.business.billing

import android.app.Activity
import android.os.Bundle
import android.util.Log
import com.android.billingclient.api.AcknowledgePurchaseParams
import com.android.billingclient.api.BillingClient
import com.android.billingclient.api.BillingClientStateListener
import com.android.billingclient.api.BillingFlowParams
import com.android.billingclient.api.BillingResult
import com.android.billingclient.api.PendingPurchasesParams
import com.android.billingclient.api.ProductDetails
import com.android.billingclient.api.ProductDetails.SubscriptionOfferDetails
import com.android.billingclient.api.Purchase
import com.android.billingclient.api.PurchasesUpdatedListener
import com.android.billingclient.api.QueryProductDetailsParams
import com.android.billingclient.api.QueryPurchasesParams
import com.android.billingclient.api.acknowledgePurchase
import com.android.billingclient.api.queryProductDetails
import com.tgv.malware.MyApplication
import com.tgv.malware.bean.config.VipConfigBean
import com.tgv.malware.business.helper.EventUtils
import com.tgv.malware.utils.AppPreferences
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.ktx.Firebase
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONObject

object GoogleSubUtil {

    private val TAG = "GoogleSubUtil"

    const val KEY_SP_VIP = "spVip"


    /**
     * vip历史状态
     * 用来判断没拿到数据时是否是vip,是否展示广告判断用这个
     */
    fun getSpVip(): Boolean {
        return AppPreferences.getInstance().getBoolean(KEY_SP_VIP, false)
    }

    /**
     * 用来实时为UI提供状态
     * null表示未知状态
     */
    val vipResult: MutableStateFlow<Boolean?> = MutableStateFlow(null)

    /**
     * 定义连接状态
     */
    val connectionResult = MutableStateFlow(false)


    /**
     *年产品详情
     */
    var yearProductFlow: MutableStateFlow<ProductDetails?> = MutableStateFlow(null)

    /**
     *月产品详情
     */
    var monthProductFlow: MutableStateFlow<ProductDetails?> = MutableStateFlow(null)

    /**
     *周产品详情
     */
    var weekProductFlow: MutableStateFlow<ProductDetails?> = MutableStateFlow(null)

    /**
     * 订阅详情是否已经准备
     */
    var subOffDetailReady = MutableStateFlow(false)


    /**
     * 获取订阅详情
     */
    fun getSubOffDetail(productDetails: ProductDetails, basePlanId: String, offId: String): SubscriptionOfferDetails? {

        val subOffDetails = productDetails.subscriptionOfferDetails

        return if (subOffDetails.isNullOrEmpty()) {
            null
        } else {
            subOffDetails.find { it.basePlanId == basePlanId && it.offerId == offId } ?: subOffDetails[0]
        }
    }


    /**
     * 更新sp里面的vip状态
     */
    fun vipSpObserveForever() {
        MainScope().launch {
            vipResult.collectLatest {
                if (it != null) {
                    AppPreferences.getInstance().putBoolean(KEY_SP_VIP, it)
                }
            }
        }
    }

    private val client by lazy {

        vipSpObserveForever()

        BillingClient.newBuilder(MyApplication.appContext)
            .setListener(purchasesUpdatedListener)
            .enablePendingPurchases(
                PendingPurchasesParams.newBuilder().enableOneTimeProducts().build()
            )
            // Configure other settings.
            .build()
    }

    /**
     * 购买状态更新监听
     */
    private val purchasesUpdatedListener = object : PurchasesUpdatedListener {
        override fun onPurchasesUpdated(
            billingResult: BillingResult,
            purchases: MutableList<Purchase>?,
        ) {
            var purchase = purchases?.firstOrNull()
            eventJSON.apply { put("purchaseToken", purchase?.purchaseToken) }

            when (billingResult.responseCode) {
                BillingClient.BillingResponseCode.OK -> {

                    purchase = purchases?.firstOrNull { it.purchaseState == Purchase.PurchaseState.PURCHASED } ?: return

                    MainScope().launch {
                        val flag = acknowledgePurchase(purchase)
                        vipResult.update { flag }
                    }
                    EventUtils.event("google_billing_success", value = "success", ext = eventJSON)


                    val bundle = Bundle()
                    bundle.putString(FirebaseAnalytics.Param.CURRENCY, eventJSON.get(FirebaseAnalytics.Param.CURRENCY) as String)
                    bundle.putDouble(FirebaseAnalytics.Param.VALUE, eventJSON.get(FirebaseAnalytics.Param.VALUE) as Double)
                    bundle.putString(FirebaseAnalytics.Param.ITEM_ID, eventJSON.get(FirebaseAnalytics.Param.ITEM_ID) as String)
                    Firebase.analytics.logEvent(FirebaseAnalytics.Event.PURCHASE, bundle)

                }

                BillingClient.BillingResponseCode.BILLING_UNAVAILABLE -> {
                    EventUtils.event("google_billing_error", ext = eventJSON.apply {
                        put("info", "处理过程中发生用户计费错误。")
                    })
                }

                BillingClient.BillingResponseCode.DEVELOPER_ERROR -> {
                    EventUtils.event("google_billing_error", ext = eventJSON.apply {
                        put("info", "API操作期间发生致命错误。")
                    })
                }

                BillingClient.BillingResponseCode.ERROR -> {
                    EventUtils.event("google_billing_error", ext = eventJSON.apply {
                        put("info", "错误使用API导致的错误。")
                    })
                }

                BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED -> {
                    EventUtils.event("google_billing_error", ext = eventJSON.apply {
                        put("info", "当前设备上的Play商店不支持请求的功能。")
                    })
                }

                BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED -> {
                    EventUtils.event("google_billing_error", ext = eventJSON.apply {
                        put("info", "购买失败，因为该物品已被拥有。")
                    })
                }

                BillingClient.BillingResponseCode.ITEM_NOT_OWNED -> {
                    EventUtils.event("google_billing_error", ext = eventJSON.apply {
                        put("info", "对该项目请求的操作失败，因为它不属于用户。")
                    })
                }

                BillingClient.BillingResponseCode.ITEM_UNAVAILABLE -> {
                    EventUtils.event("google_billing_error", ext = eventJSON.apply {
                        put("info", "所请求的产品不可购买。")
                    })
                }

                BillingClient.BillingResponseCode.NETWORK_ERROR -> {
                    EventUtils.event("google_billing_error", ext = eventJSON.apply {
                        put("info", "操作过程中发生网络错误。")
                    })
                }

                BillingClient.BillingResponseCode.SERVICE_DISCONNECTED -> {
                    EventUtils.event("google_billing_error", ext = eventJSON.apply {
                        put("info", "该应用程序未通过Google Play计费库连接到Play商店服务。")
                    })
                }

                BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE -> {
                    EventUtils.event("google_billing_error", ext = eventJSON.apply {
                        put("info", "该服务当前不可用。")
                    })
                }

                BillingClient.BillingResponseCode.USER_CANCELED -> {
                    EventUtils.event("google_billing_error", ext = eventJSON.apply {
                        put("info", "交易已被用户取消。")
                    })
                }

                else -> {
                    EventUtils.event("google_billing_error", ext = eventJSON.apply {
                        put("info", "未知错误。")
                    })
                }
            }

        }
    }

    fun endConnection() {
        client.endConnection()
        connectionResult.update { false }
    }

    fun startConnection() {
        Log.e(TAG, "startConnection")
        if (client.isReady) {
            return
        }
        if (connectionResult.value == true) {
            return
        }
        var time = 3
        MainScope().launch {
            while (!connectionResult.value && time > 0) {
                time--
                realStartConnection()
                delay(1500)
            }
        }
    }

    private fun realStartConnection() {
        client.startConnection(object : BillingClientStateListener {
            override fun onBillingServiceDisconnected() {
                Log.e(TAG, "onBillingServiceDisconnected")
                connectionResult.update { false }
            }

            override fun onBillingSetupFinished(billingResult: BillingResult) {
                Log.e(TAG, "onBillingSetupFinished")
                if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
                    Log.e(TAG, "onBillingSetupFinished ok")
                    connectionResult.update { true }
                    //查询订阅购买状态
                    queryPurchasesAsync()
                    //查询所有的订阅产品
                    queryAllProduct()
                } else {
                    connectionResult.update { false }
                }
            }

        })
    }

    private fun queryAllProduct() = MainScope().launch(Dispatchers.IO) {

        val productYear: ProductDetails? = queryProduct(VipConfigBean.vipConfigBean.productIdYear)
        val productMonth: ProductDetails? = queryProduct(VipConfigBean.vipConfigBean.productIdMonth)
        val productWeek: ProductDetails? = queryProduct(VipConfigBean.vipConfigBean.productIdWeek)

        Log.e(TAG, "productYear=${productYear}")
        Log.e(TAG, "productMonth=${productMonth}")
        Log.e(TAG, "productWeek=${productWeek}")

        yearProductFlow.update { productYear }
        monthProductFlow.update { productMonth }
        weekProductFlow.update { productWeek }

        val isReady = !(productYear?.subscriptionOfferDetails.isNullOrEmpty() ||
                productMonth?.subscriptionOfferDetails.isNullOrEmpty() ||
                productWeek?.subscriptionOfferDetails.isNullOrEmpty())

        Log.e(TAG, "isReady=$isReady")

        subOffDetailReady.update { isReady }

    }

    suspend fun queryProduct(productId: String): ProductDetails? {
        val params = getParams(productId)

        val productDetails = withContext(Dispatchers.IO) {
            val productDetailsResult = client.queryProductDetails(params.build())
            return@withContext productDetailsResult.productDetailsList?.firstOrNull {
                //筛选匹配商品
                productId == it.productId
            }
        }
        return productDetails
    }

    private fun getParams(productId: String): QueryProductDetailsParams.Builder {
        val params = QueryProductDetailsParams.newBuilder()

        val productList = listOf(
            QueryProductDetailsParams.Product.newBuilder()
                .setProductId(productId)
                .setProductType(BillingClient.ProductType.SUBS)
                .build()
        )
        params.setProductList(productList)
        return params
    }

    /**
     * 支付上报
     */
    var eventJSON = JSONObject()
    fun pay(activity: Activity, productDetails: ProductDetails, subOffDetail: SubscriptionOfferDetails) {
        val pricingPhase = subOffDetail.pricingPhases.pricingPhaseList[0]
        eventJSON = JSONObject().apply {
            put("productId", productDetails.productId)
            put("basePlanId", subOffDetail.basePlanId)
            put("offerId", subOffDetail.offerId)
            put("offerToken", subOffDetail.offerToken)
            put(FirebaseAnalytics.Param.CURRENCY, pricingPhase.priceCurrencyCode)//订阅价格类型
            put(FirebaseAnalytics.Param.VALUE, pricingPhase.formattedPrice.formattedPrice2Double())//订阅价格 4.66
            put(FirebaseAnalytics.Param.ITEM_ID, productDetails.productId)//订阅产品ID
        }
        EventUtils.event("google_billing", value = "click", ext = eventJSON)

        val currency = eventJSON.get(FirebaseAnalytics.Param.CURRENCY) as String
        val value = eventJSON.get(FirebaseAnalytics.Param.VALUE) as Double
        val item_id = eventJSON.get(FirebaseAnalytics.Param.ITEM_ID) as String
        Log.e(TAG, "FirebaseAnalytics currency=$currency value=$value item_id=$item_id")

        val productDetailsParamsList = listOf(
            BillingFlowParams.ProductDetailsParams.newBuilder()
                .setProductDetails(productDetails)
                .setOfferToken(subOffDetail.offerToken)
                .build()
        )

        val billingFlowParams = BillingFlowParams.newBuilder()
            .setProductDetailsParamsList(productDetailsParamsList)
            .build()

        val billingResult = client.launchBillingFlow(activity, billingFlowParams)

        if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
            queryPurchasesAsync()
        } else {

        }
    }


    /**
     * 查询所有[购买]状态
     */
    fun queryPurchasesAsync() = MainScope().launch(Dispatchers.IO) {
        client.queryPurchasesAsync(
            QueryPurchasesParams.newBuilder()
                .setProductType(BillingClient.ProductType.SUBS)
                .build()
        ) { billingResult, purchases ->

            if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
                val noVip = purchases.isEmpty()
                Log.e("vipResult", "noVip=$noVip")
                if (noVip) {
                    vipResult.update { false }
                } else {
                    MainScope().launch {
                        purchases.forEachIndexed { index, purchase: Purchase ->
//             val vip = it.isAcknowledged && it.isAutoRenewing
//                            val purchaseState = purchase.purchaseState //买状态，表示购买交易的状态，例如是否已完成、是否被取消等。
                            var vip: Boolean?
                            val isAcknowledged = purchase.isAcknowledged // 是否已确认，表示该购买是否已经被应用确认。
                            vip = isAcknowledged
                            Log.e(TAG, "vipResult 1 vip=$vip index=$index")
                            if (!isAcknowledged) {//未确认再查询下购买状态
                                vip = acknowledgePurchase(purchase)
                                Log.e(TAG, "vipResult 2 vip=$vip index=$index")
                            }
                            vipResult.update { vip }
                        }
                    }
                }
            }
        }
    }

    //确认商品购买状态,null表示未知状态
    // BillingClient.BillingResponseCode.OK 已确认
    // BillingClient.BillingResponseCode.USER_CANCELED 用户取消等
    private suspend fun acknowledgePurchase(purchase: Purchase): Boolean? {

        val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
            .setPurchaseToken(purchase.purchaseToken)
            .build()
        val ackPurchaseResult = withContext(Dispatchers.IO) {
            client.acknowledgePurchase(acknowledgePurchaseParams)
        }

        if (ackPurchaseResult.responseCode == BillingClient.BillingResponseCode.OK) {
            EventUtils.event("google_billing", value = "consume", ext = eventJSON)
            return true
        }
        return null
    }

    /**
     * 价格提前数字转Double
     */
    fun String.formattedPrice2Double(): Double {
        val regex = """\$([\d.]+)""".toRegex()
        val matchResult = regex.find(this)

        if (matchResult != null) {
            val price = matchResult.groupValues[1].toDouble()
            return price
        } else {
            return 0.0
        }
    }
}


