/*
 * Copyright (c) 2012-2016 Arne Schwabe
 * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
 */

package de.blinkt.openvpn.fragments;

import android.app.Fragment;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentSender;
import android.content.ServiceConnection;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.Space;
import android.widget.TextView;

import com.android.vending.billing.IInAppBillingService;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Vector;

import de.blinkt.openvpn.R;
import de.blinkt.openvpn.core.VpnStatus;

public class AboutFragment extends Fragment implements View.OnClickListener {

    public static final String INAPPITEM_TYPE_INAPP = "inapp";
    public static final String RESPONSE_CODE = "RESPONSE_CODE";
    private static final int DONATION_CODE = 12;
    private static final int BILLING_RESPONSE_RESULT_OK = 0;
    private static final String RESPONSE_BUY_INTENT = "BUY_INTENT";
    private static final String[] donationSkus = { "donation1eur", "donation2eur", "donation5eur", "donation10eur",
            "donation1337eur","donation23eur","donation25eur",};
    IInAppBillingService mService;
    Hashtable<View, String> viewToProduct = new Hashtable<>();
    ServiceConnection mServiceConn = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            mService = null;
        }

        @Override
        public void onServiceConnected(ComponentName name,
                                       IBinder service) {
            mService = IInAppBillingService.Stub.asInterface(service);
            initGooglePlayDonation();

        }
    };

    private void initGooglePlayDonation() {
        new Thread("queryGMSInApp") {
            @Override
            public void run() {
                initGMSDonateOptions();
            }
        }.start();
    }

    private TextView gmsTextView;

    private Button full_licenses_button;
    private WebView wvFullLicenses;
    private Space webViewFullLicensesSpacePlaceholder;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        /*
        getActivity().bindService(new
                Intent("com.android.vending.billing.InAppBillingService.BIND"),
                mServiceConn, Context.BIND_AUTO_CREATE);
        */
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mService != null) {
            getActivity().unbindService(mServiceConn);
        }

    }

    private void initGMSDonateOptions() {
        try {
            int billingSupported = mService.isBillingSupported(3, getActivity().getPackageName(), INAPPITEM_TYPE_INAPP);
            if (billingSupported != BILLING_RESPONSE_RESULT_OK) {
                Log.i("OpenVPN", "Play store billing not supported");
                return;
            }

            ArrayList skuList = new ArrayList();
            Collections.addAll(skuList, donationSkus);
            Bundle querySkus = new Bundle();
            querySkus.putStringArrayList("ITEM_ID_LIST", skuList);

            Bundle ownedItems = mService.getPurchases(3, getActivity().getPackageName(), INAPPITEM_TYPE_INAPP, null);


            if (ownedItems.getInt(RESPONSE_CODE) != BILLING_RESPONSE_RESULT_OK)
                return;

            final ArrayList<String> ownedSkus = ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");

            Bundle skuDetails = mService.getSkuDetails(3, getActivity().getPackageName(), INAPPITEM_TYPE_INAPP, querySkus);


            if (skuDetails.getInt(RESPONSE_CODE) != BILLING_RESPONSE_RESULT_OK)
                return;

            final ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST");

            if (getActivity() != null) {
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        createPlayBuyOptions(ownedSkus, responseList);

                    }
                });
            }

        } catch (RemoteException e) {
            VpnStatus.logException(e);
        }
    }

    private static class SkuResponse {
        String title;
        String price;

        SkuResponse(String p, String t)
        {
            title=t;
            price=p;
        }
    }



    private void createPlayBuyOptions(ArrayList<String> ownedSkus, ArrayList<String> responseList) {
        try {
            Vector<Pair<String,String>> gdonation = new Vector<Pair<String, String>>();

            gdonation.add(new Pair<String, String>(getString(R.string.donatePlayStore),null));
            HashMap<String, SkuResponse> responseMap = new HashMap<String, SkuResponse>();
            for (String thisResponse : responseList) {
                JSONObject object = new JSONObject(thisResponse);
                responseMap.put(
                        object.getString("productId"),
                        new SkuResponse(
                                object.getString("price"),
                                object.getString("title")));

            }
            for (String sku: donationSkus)
                if (responseMap.containsKey(sku))
                    gdonation.add(getSkuTitle(sku,
                            responseMap.get(sku).title, responseMap.get(sku).price, ownedSkus));

            String gmsTextString="";
            for(int i=0;i<gdonation.size();i++) {
                if(i==1)
                    gmsTextString+= "  ";
                else if(i>1)
                    gmsTextString+= ", ";
                gmsTextString+=gdonation.elementAt(i).first;
            }
            SpannableString gmsText = new SpannableString(gmsTextString);


            int lStart = 0;
            int lEnd=0;
            for(Pair<String, String> item:gdonation){
                lEnd = lStart + item.first.length();
                if (item.second!=null) {
                    final String mSku = item.second;
                    ClickableSpan cspan = new ClickableSpan()
                    {
                        @Override
                        public void onClick(View widget) {
                            triggerBuy(mSku);
                        }
                    };
                    gmsText.setSpan(cspan,lStart,lEnd,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
                lStart = lEnd+2; // Account for ", " between items
            }

            if(gmsTextView !=null) {
                gmsTextView.setText(gmsText);
                gmsTextView.setMovementMethod(LinkMovementMethod.getInstance());
                gmsTextView.setVisibility(View.VISIBLE);
            }

        } catch (JSONException e) {
            VpnStatus.logException("Parsing Play Store IAP",e);
        }

    }

    private Pair<String,String> getSkuTitle(final String sku, String title, String price, ArrayList<String> ownedSkus) {
        String text;
        if (ownedSkus.contains(sku))
            return new Pair<String,String>(getString(R.string.thanks_for_donation, price),null);

        if (price.contains("€")|| price.contains("\u20ac")) {
            text= title;
        } else {
            text = String.format(Locale.getDefault(), "%s (%s)", title, price);
        }
        //return text;
        return new Pair<String,String>(price, sku);

    }

    private void triggerBuy(String sku) {
        try {
            Bundle buyBundle
                    = mService.getBuyIntent(3, getActivity().getPackageName(),
                    sku, INAPPITEM_TYPE_INAPP, "Thanks for the donation! :)");


            if (buyBundle.getInt(RESPONSE_CODE) == BILLING_RESPONSE_RESULT_OK) {
                PendingIntent buyIntent = buyBundle.getParcelable(RESPONSE_BUY_INTENT);
                getActivity().startIntentSenderForResult(buyIntent.getIntentSender(), DONATION_CODE, new Intent(),
                        0, 0, 0);
            }

        } catch (RemoteException e) {
            VpnStatus.logException(e);
        } catch (IntentSender.SendIntentException e) {
            VpnStatus.logException(e);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.about, container, false);


        // ROUTE1 - commenting out - start
        //TextView ver = (TextView) v.findViewById(R.id.version);
        //
        //String version;
        //String name = "Openvpn";
        //try {
        //    PackageInfo packageinfo = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0);
        //    version = packageinfo.versionName;
        //    name = getString(R.string.app);
        //} catch (NameNotFoundException e) {
        //    version = "error fetching version";
        //}
        //
        //ver.setText(getString(R.string.version_info, name, version));
        // ROUTE1 - commenting out - start


        // ROUTE1 - commenting out - start
        //gmsTextView = (TextView) v.findViewById(R.id.donategms);
        // ROUTE1 - commenting out - end


        /* recreating view without onCreate/onDestroy cycle */

        // Disable GMS for now
        if (mService!=null)
            initGooglePlayDonation();


        // ROUTE1 - commenting out - start
        //TextView translation = (TextView) v.findViewById(R.id.translation);
        //
        //// Don't print a text for myself
        //if (getString(R.string.translationby).contains("Arne Schwabe"))
        //    translation.setText("");
        //else
        //    translation.setText(R.string.translationby);
        // ROUTE1 - commenting out - end


        WebView wvDerivIDCP = (WebView)v.findViewById(R.id.webViewDerivIDCP);
        wvDerivIDCP.loadUrl("file:///android_asset/DerivID_CP_1st_half.htm");

        wvFullLicenses = (WebView)v.findViewById(R.id.webViewFullLicenses);
        wvFullLicenses.loadUrl("file:///android_asset/DerivID_CP_2nd_half_Full_Licenses.htm");

        webViewFullLicensesSpacePlaceholder = (Space)v.findViewById(R.id.webViewFullLicensesSpacePlaceholder);

        full_licenses_button = (Button)v.findViewById(R.id.full_licenses_button);
        full_licenses_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(wvFullLicenses.getVisibility() != View.VISIBLE) {
                    wvFullLicenses.setVisibility(View.VISIBLE);
                    webViewFullLicensesSpacePlaceholder.setVisibility(View.GONE);
                    full_licenses_button.setText(R.string.full_licenses_hide);
                } else {
                    wvFullLicenses.setVisibility(View.GONE);
                    webViewFullLicensesSpacePlaceholder.setVisibility(View.VISIBLE);
                    full_licenses_button.setText(R.string.full_licenses);
                }
            }
        });


        return v;
    }


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (mService!=null)
            initGooglePlayDonation();
    }


    @Override
    public void onClick(View v) {

    }
}
