import { getComponentViewBindingId } from "./helpers";

export function findComponentsWithInAppPurchaseAction(data, result = []) {
  if (!Array.isArray(data)) data = [data];
  for (const item of data) {
    if ("components" in item) {
      findComponentsWithInAppPurchaseAction(item.components, result);
    }
    if ("children" in item) {
      findComponentsWithInAppPurchaseAction(item.children, result);
    }
    if ("props" in item && item.name == "InAppPurchaseButton") {
      result.push(item);
    }
  }
  return result;
}

export const generateInAppPurchaseImport = (fragment, configuration) => {
  if (findComponentsWithInAppPurchaseAction(fragment).length == 0) return "";
  return `
import android.widget.Toast
import android.content.SharedPreferences
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.ConsumeParams
import com.android.billingclient.api.ConsumeResponseListener
import com.android.billingclient.api.Purchase
import com.android.billingclient.api.PurchasesUpdatedListener
import com.android.billingclient.api.SkuDetailsParams
import com.manaknight.app.extensions.viewBinding
import com.manaknight.app.utils.Security
import java.io.IOException
 `;
};

export const generateInAppPurchaseField = (fragment, configuration) => {
  if (findComponentsWithInAppPurchaseAction(fragment).length == 0) return "";
  return `
     private var billingClient: BillingClient? = null
 `;
};

export const generateInAppPurchaseBinding = (fragment, configuration) => {
  if (findComponentsWithInAppPurchaseAction(fragment).length == 0) return "";

  const content = [];

  content.push(`  billingClient = BillingClient.newBuilder(requireActivity())
            .enablePendingPurchases().setListener(this).build()
        billingClient!!.startConnection(object : BillingClientStateListener {
            override fun onBillingSetupFinished(billingResult: BillingResult) {
                if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {

                    billingClient!!.queryPurchasesAsync(
                        BillingClient.SkuType.INAPP
                    ) { billingResult, list ->
                        if (list != null && list.size > 0) {
                            handlePurchases(list)
                        }
                    }
                }
            }

            override fun onBillingServiceDisconnected() {}
        })`);
  return content.join("\n");
};

export const generateInAppPurchaseFunctions = (fragment, configuration) => {
  if (findComponentsWithInAppPurchaseAction(fragment).length == 0) return "";
  return `
 private val preferenceObject: SharedPreferences
        private get() = requireActivity().getSharedPreferences(PREF_FILE, 0)
    private val preferenceEditObject: SharedPreferences.Editor
        private get() {
            val pref = requireActivity().getSharedPreferences(PREF_FILE, 0)
            return pref.edit()
        }
    private val purchaseCountValueFromPref: Int
        private get() = preferenceObject.getInt("PURCHASE_KEY", 0)

    private fun savePurchaseCountValueToPref(value: Int) {
        preferenceEditObject.putInt("PURCHASE_KEY", value).commit()
    }

    fun consume(view: View?) {

        if (billingClient!!.isReady) {
            initiatePurchase()
        } else {
            billingClient = BillingClient.newBuilder(requireActivity()).enablePendingPurchases().setListener(this).build()
            billingClient!!.startConnection(object : BillingClientStateListener {
                override fun onBillingSetupFinished(billingResult: BillingResult) {
                    if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
                        initiatePurchase()
                    } else {
                        Toast.makeText(activity, "Error " + billingResult.debugMessage, Toast.LENGTH_SHORT).show()
                    }
                }

                override fun onBillingServiceDisconnected() {}
            })
        }
    }

    private fun initiatePurchase() {
        val skuList: MutableList<String> = ArrayList()
        skuList.add("PRODUCT_ID")
        val params = SkuDetailsParams.newBuilder()
        params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP)
        billingClient!!.querySkuDetailsAsync(params.build()
        )
        {
                billingResult, skuDetailsList ->
            if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
                if (skuDetailsList != null && skuDetailsList.size > 0) {
                    val flowParams = BillingFlowParams.newBuilder()
                        .setSkuDetails(skuDetailsList[0])
                        .build()
                    billingClient!!.launchBillingFlow(requireActivity(), flowParams)
                }
                else {

                    Toast.makeText(activity, "Purchase Item not Found", Toast.LENGTH_SHORT).show()
                }
            }
            else {
                Toast.makeText(activity,
                    " Error " + billingResult.debugMessage, Toast.LENGTH_SHORT).show()
            }
        }
    }

    override fun onPurchasesUpdated(billingResult: BillingResult, purchases: List<Purchase>?) {

        if (billingResult.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) {
            handlePurchases(purchases)
        } else if (billingResult.responseCode == BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED) {

            billingClient!!.queryPurchasesAsync(
                BillingClient.SkuType.INAPP
            ) { billingResult, list ->
                if (list != null && list.size > 0) {
                    handlePurchases(list)
                }
            }
        } else if (billingResult.responseCode == BillingClient.BillingResponseCode.USER_CANCELED) {
            Toast.makeText(activity, "Purchase Canceled", Toast.LENGTH_SHORT).show()
        } else {
            Toast.makeText(activity, "Error " + billingResult.debugMessage, Toast.LENGTH_SHORT).show()
        }
    }

    fun handlePurchases(purchases: List<Purchase>) {
        for (purchase in purchases) {
            //if item is purchased
            if (purchase.purchaseState == Purchase.PurchaseState.PURCHASED) {
                if (!verifyValidSignature(purchase.originalJson, purchase.signature)) {

                    Toast.makeText(activity, "Error : Invalid Purchase", Toast.LENGTH_SHORT).show()
                    return
                }

                if (!purchase.isAcknowledged) {
                    val consumeParams = ConsumeParams.newBuilder()
                        .setPurchaseToken(purchase.purchaseToken)
                        .build()
                    billingClient!!.consumeAsync(consumeParams, consumeListener)
                }
            } else if (purchase.purchaseState == Purchase.PurchaseState.PENDING) {
                Toast.makeText(activity,
                    "Purchase is Pending. Please complete Transaction", Toast.LENGTH_SHORT).show()
            } else if (purchase.purchaseState == Purchase.PurchaseState.UNSPECIFIED_STATE) {
                Toast.makeText(activity, "Purchase Status Unknown", Toast.LENGTH_SHORT).show()
            }
        }
    }

    var consumeListener = ConsumeResponseListener { billingResult, purchaseToken ->
        if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
            val consumeCountValue = purchaseCountValueFromPref + 1
            savePurchaseCountValueToPref(consumeCountValue)
            Toast.makeText(activity, "Item Consumed", Toast.LENGTH_SHORT).show()
        }
    }

    private fun verifyValidSignature(signedData: String, signature: String): Boolean {
        return try {
            //for old playconsole
            // To get key go to Developer Console > Select your app > Development Tools > Services & APIs.
            //for new play console
            //To get key go to Developer Console > Select your app > Monetize > Monetization setup
            val base64Key = "Add your key here";
            Security.verifyPurchase(base64Key, signedData, signature)
        } catch (e: IOException) {
            false
        }
    }

    companion object {
        const val PREF_FILE = "MyPref"
        const val PURCHASE_KEY = "consumable"
        const val PRODUCT_ID = "consumable"
    }
 `;
};
