package com.atmob.voiceai.sdk.billing.operation;

import android.app.Activity;

import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.BillingFlowParams;
import com.android.billingclient.api.BillingResult;
import com.android.billingclient.api.ProductDetails;
import com.android.billingclient.api.SkuDetails;
import com.atmob.common.logging.AtmobLog;

import java.util.Collections;
import java.util.Objects;

import atmob.reactivex.rxjava3.core.Single;

public class Subscription {

    private static final String TAG = Subscription.class.getSimpleName();


    public static Single<BillingResult> subscriptionGoods(BillingClient billingClient, Activity activity, Object productDetails, String basePlanId, String orderNo) {
        if (billingClient.isFeatureSupported(BillingClient.FeatureType.PRODUCT_DETAILS).getResponseCode() == BillingClient.BillingResponseCode.OK) {
            return launchProductBillingFlow(billingClient, activity, productDetails, basePlanId, orderNo);
        } else {
            return launchSkuBillingFlow(billingClient, activity, productDetails, orderNo);
        }
    }


    private static Single<BillingResult> launchProductBillingFlow(BillingClient billingClient, Activity activity, Object productDetails, String basePlanId, String orderNo) {
        AtmobLog.i(TAG, "launchBillingFlow() called with: productDetails = [" + productDetails + "], orderNo = [" + orderNo + "]");
        ProductDetails details = productDetails instanceof ProductDetails ? ((ProductDetails) productDetails) : null;
        if (details == null) {
            return Single.error(new IllegalStateException("Failed to launch billing flow, product details is null"));
        }
        String offerToken = "";
        ProductDetails.SubscriptionOfferDetails subscriptionOfferDetails = getSubscriptionOfferDetails(details, basePlanId);
        if (subscriptionOfferDetails != null) {
            offerToken = subscriptionOfferDetails.getOfferToken();
        }
        BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
                .setObfuscatedAccountId(orderNo)
                .setIsOfferPersonalized(true)
                .setProductDetailsParamsList(Collections.singletonList(
                        BillingFlowParams.ProductDetailsParams.newBuilder()
                                .setProductDetails(details)
                                .setOfferToken(offerToken)
                                .build()))
                .build();
        return Single.fromCallable(() -> {
            BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
            AtmobLog.d(TAG, "launchBillingFlow() called with: billingResult = [" + billingResult + "]");
            return billingResult;
        });
    }


    private static Single<BillingResult> launchSkuBillingFlow(BillingClient billingClient, Activity activity, Object productDetails, String orderNo) {
        AtmobLog.i(TAG, "launchBillingFlow() called with: productDetails = [" + productDetails + "], orderNo = [" + orderNo + "]");
        SkuDetails skuDetails = productDetails instanceof SkuDetails ? ((SkuDetails) productDetails) : null;
        if (skuDetails == null) {
            return Single.error(new IllegalStateException("Failed to launch billing flow, sku details is null"));
        }
        BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
                .setIsOfferPersonalized(true)
                .setSkuDetails(skuDetails)
                .setObfuscatedAccountId(orderNo)
                .build();
        return Single.fromCallable(() -> {
            BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
            AtmobLog.d(TAG, "launchBillingFlow() called with: billingResult = [" + billingResult + "]");
            return billingResult;
        });
    }

    private static ProductDetails.SubscriptionOfferDetails getSubscriptionOfferDetails(ProductDetails details, String basePlanId) {
        if (details.getSubscriptionOfferDetails() == null || details.getSubscriptionOfferDetails().isEmpty())
            return null;
        for (ProductDetails.SubscriptionOfferDetails subscriptionOfferDetail : details.getSubscriptionOfferDetails()) {
            if (Objects.equals(subscriptionOfferDetail.getBasePlanId(), basePlanId)) {
                return subscriptionOfferDetail;
            }
        }
        return null;
    }
}
