package app.fedilab.fedilabtube;
/* Copyright 2021 Thomas Schneider
 *
 * This file is a part of TubeLab
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * TubeLab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with TubeLab; if not,
 * see <http://www.gnu.org/licenses>. */

import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

import com.android.billingclient.api.AcknowledgePurchaseParams;
import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.BillingClientStateListener;
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.google.android.material.snackbar.Snackbar;
import com.google.android.material.tabs.TabLayout;

import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import app.fedilab.fedilabtube.databinding.ActivityDonationBinding;

import app.fedilab.fedilabtube.fragment.MySubscriptionDonationsFragment;
import app.fedilab.fedilabtube.fragment.DonationsFragment;


public class DonationActivity extends AppCompatActivity implements PurchasesUpdatedListener {


    DonationsFragment donationsFragment;
    DonationsFragment subscriptionDonationsFragment;
    MySubscriptionDonationsFragment mySubscriptionDonationsFragment;
    private ActivityDonationBinding binding;
    private BillingClient billingClient;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityDonationBinding.inflate(getLayoutInflater());
        View view = binding.getRoot();
        setContentView(view);
        billingClient = BillingClient.newBuilder(this)
                .setListener(this)
                .enablePendingPurchases()
                .build();
        billingClient.startConnection(new BillingClientStateListener() {
            @Override
            public void onBillingSetupFinished(@NotNull BillingResult billingResult) {
                if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                    // The BillingClient is ready. You can query purchases here.
                    donationsFragment.initialized(billingClient);
                    subscriptionDonationsFragment.initialized(billingClient);

                    List<Purchase> purchases = queryPurchases();
                    if (purchases != null) {
                        for (Purchase purchase : purchases) {
                            if (!purchase.isAutoRenewing()) {
                                ConsumeParams consumeParams =
                                        ConsumeParams.newBuilder()
                                                .setPurchaseToken(purchase.getPurchaseToken())
                                                .build();

                                ConsumeResponseListener listener = (billingResult1, purchaseToken) -> {
                                    //noinspection StatementWithEmptyBody
                                    if (billingResult1.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                                        // Handle the success of the consume operation.
                                    }
                                };
                                billingClient.consumeAsync(consumeParams, listener);
                            }
                        }
                    }
                }
            }

            @Override
            public void onBillingServiceDisconnected() {
                // Try to restart the connection on the next request to
                // Google Play by calling the startConnection() method.
            }
        });
        if (getSupportActionBar() != null)
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        donationsFragment = new DonationsFragment();
        Bundle bundle1 = new Bundle();
        bundle1.putSerializable("isSubscriptions", false);
        donationsFragment.setArguments(bundle1);


        subscriptionDonationsFragment = new DonationsFragment();
        Bundle bundle2 = new Bundle();
        bundle2.putSerializable("isSubscriptions", true);
        subscriptionDonationsFragment.setArguments(bundle2);

        mySubscriptionDonationsFragment = new MySubscriptionDonationsFragment();

        binding.tablayout.addTab(binding.tablayout.newTab().setText(getString(R.string.one_time)));
        binding.tablayout.addTab(binding.tablayout.newTab().setText(getString(R.string.subscriptions)));
        binding.tablayout.addTab(binding.tablayout.newTab().setText(getString(R.string.my_subscriptions)));
        binding.viewpager.setOffscreenPageLimit(3);

        PagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
        binding.viewpager.setAdapter(mPagerAdapter);
        binding.viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                TabLayout.Tab tab = binding.tablayout.getTabAt(position);
                if (tab != null)
                    tab.select();
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        binding.tablayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                binding.viewpager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
            }
        });

    }

    private List<Purchase> queryPurchases() {
        Purchase.PurchasesResult purchasesResult = billingClient.queryPurchases(BillingClient.SkuType.SUBS);
        List<Purchase> purchases = purchasesResult.getPurchasesList();
        List<String> isSubscriptions = new ArrayList<>();
        HashMap<String, Purchase> map = new HashMap<>();
        if (purchases != null) {
            for (Purchase purchase : purchases) {
                try {
                    if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
                        JSONObject purchaseJson = new JSONObject(purchase.getOriginalJson());
                        String productId = purchaseJson.getString("productId");
                        isSubscriptions.add(productId);
                        map.put(productId, purchase);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            SkuDetailsParams.Builder paramsSub = SkuDetailsParams.newBuilder();
            paramsSub.setSkusList(isSubscriptions).setType(BillingClient.SkuType.SUBS);
            billingClient.querySkuDetailsAsync(paramsSub.build(),
                    (billingResult2, skuDetailsList) -> mySubscriptionDonationsFragment.initialized(skuDetailsList, map, billingClient));
        } else {
            mySubscriptionDonationsFragment.initialized(new ArrayList<>(), map, billingClient);
        }
        return purchases;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            finish();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> purchases) {
        String message;
        if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK
                && purchases != null) {
            for (Purchase purchase : purchases) {
                if (!purchase.isAutoRenewing()) {
                    ConsumeParams consumeParams =
                            ConsumeParams.newBuilder()
                                    .setPurchaseToken(purchase.getPurchaseToken())
                                    .build();

                    ConsumeResponseListener listener = (billingResult1, purchaseToken) -> {
                    };
                    billingClient.consumeAsync(consumeParams, listener);
                } else {
                    if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
                        if (!purchase.isAcknowledged()) {
                            AcknowledgePurchaseParams acknowledgePurchaseParams =
                                    AcknowledgePurchaseParams.newBuilder()
                                            .setPurchaseToken(purchase.getPurchaseToken())
                                            .build();
                            billingClient.acknowledgePurchase(acknowledgePurchaseParams, b -> {
                            });
                        }
                    }

                    queryPurchases();
                }
            }
            message = getString(R.string.donation_succeeded_null);
        } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {
            message = getString(R.string.donation_cancelled);
        } else {
            message = getString(R.string.toast_error);
        }
        View parentLayout = findViewById(android.R.id.content);
        Snackbar snackbar = Snackbar.make(parentLayout, message, Snackbar.LENGTH_INDEFINITE);
        snackbar.setAction(R.string.close, view -> snackbar.dismiss());
        snackbar.show();
    }


    /**
     * Pager adapter for the 2 fragments
     */
    private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {

        ScreenSlidePagerAdapter(FragmentManager fm) {
            super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
        }

        @NotNull
        @Override
        public Fragment getItem(int position) {
            if (position == 0) {
                return donationsFragment;
            } else if (position == 1) {
                return subscriptionDonationsFragment;
            } else {
                return mySubscriptionDonationsFragment;
            }
        }


        @Override
        public int getCount() {
            return 3;
        }
    }
}
