package org.octopus.randomfacts.core.billing

import android.app.Activity
import com.android.billingclient.api.BillingClient
import com.android.billingclient.api.BillingClient.BillingResponseCode
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.PurchasesUpdatedListener
import com.android.billingclient.api.QueryProductDetailsParams
import org.octopus.randomfacts.core.shared.Const

class OctopusBillingClient(val activity: Activity, val logic: (PurchaseState) -> Unit) {
    private val queryProductDetailsParams =
        QueryProductDetailsParams.newBuilder()
            .setProductList(
                listOf(
                    QueryProductDetailsParams.Product.newBuilder()
                        .setProductId(Const.UNLIMITED_COIN_PRODUCT_ID)
                        .setProductType(BillingClient.ProductType.INAPP)
                        .build()))
            .build()

    private val purchasesUpdatedListener =
        PurchasesUpdatedListener { billingResult, purchases ->
            if (billingResult.responseCode == BillingResponseCode.OK && purchases != null) {
                for (purchase in purchases) {
                    if (purchase.products.any { it == Const.UNLIMITED_COIN_PRODUCT_ID }) {
                        logic.invoke(PurchaseState.OK)
                    }
                }
            } else if (billingResult.responseCode == BillingResponseCode.USER_CANCELED) {
                logic.invoke(PurchaseState.CANCELLED)
            } else {
                logic.invoke(PurchaseState.KO)
            }

        }

    private var billingClient = BillingClient.newBuilder(activity)
        .setListener(purchasesUpdatedListener)
        .enablePendingPurchases(PendingPurchasesParams.newBuilder()
            .enablePrepaidPlans()
            .enableOneTimeProducts()
            .build())
        .enableAutoServiceReconnection()
        .build()

    fun init(onlyCheck: Boolean = false) {
        billingClient.startConnection(object : BillingClientStateListener {
            override fun onBillingSetupFinished(billingResult: BillingResult) {
                if (billingResult.responseCode ==  BillingResponseCode.OK) {
                    billingClient.queryProductDetailsAsync(queryProductDetailsParams) {
                            billingResult,
                            queryProductDetailsResult ->
                        if (billingResult.responseCode == BillingResponseCode.ITEM_ALREADY_OWNED) {
                            logic.invoke(PurchaseState.OK)
                        } else if (!onlyCheck && billingResult.responseCode == BillingResponseCode.OK) {
                            for ( productDetails in queryProductDetailsResult.productDetailsList) {
                                val productDetailsParamsList = listOf(
                                    BillingFlowParams.ProductDetailsParams.newBuilder()
                                        .setProductDetails(productDetails)
                                        .setOfferToken(productDetails.oneTimePurchaseOfferDetailsList!![0].offerToken!!)
                                        .build()
                                )

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

                                val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)
                                when (billingResult.responseCode) {
                                    BillingResponseCode.OK -> logic.invoke(PurchaseState.OK)
                                    BillingResponseCode.USER_CANCELED -> logic.invoke(PurchaseState.CANCELLED)
                                    else -> logic.invoke(PurchaseState.KO)
                                }
                            }

                            for ( unfetchedProduct in queryProductDetailsResult.unfetchedProductList) {
                                // Handle any unfetched products as appropriate.
                            }
                        }
                    }
                }
            }
            override fun onBillingServiceDisconnected() {
                // Try to restart the connection on the next request to
                // Google Play by calling the startConnection() method.
            }
        })



    }

}