// package com.apache.cordova.expresscheckout;
package in.juspay.godel.hybrid;

import java.util.Map;
import java.util.Iterator;
import java.util.HashMap;

import android.webkit.WebView;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;

import in.juspay.juspaysafe.BrowserCallback;
import in.juspay.juspaysafe.BrowserParams;
import in.juspay.godel.analytics.GodelTracker;

import in.juspay.juspaysafe.JuspaySafeBrowser;

public class GodelCordovaPluginImpl extends CordovaPlugin {

    private static final String PAYMENT = "JuspayStartPayment";
    private static final String TRACK_STATUS = "JuspayTrackStatus";

    @Override
    public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
        try {
            if(action.equals(PAYMENT)) {
                doPayment(args.optJSONObject(0), callbackContext);
                return true;
            } else if(action.equals(TRACK_STATUS)) {
                trackStatus(args.optJSONObject(0));
                return true;
            }
        } catch(JSONException e) {
            e.printStackTrace();
            throw e;
        }

        return false;
    }

    /**
     * Helper method to copy a JSONObeject that is isomorphic
     * to a Map<String, String>
     *
     * @param  object JSONObject to be copied into a Map<String, String>
     * @return        Map<String, String> of the same contents that are
     *                having the same {k,v} pairs.
     */
    private static Map<String, String> copyJSONObjectToMap(JSONObject object) {
        Map<String, String> targetMap = new HashMap<String, String>();

        for(Iterator<String> it = object.keys(); it.hasNext(); ) {
	    String key = it.next();
	    targetMap.put(key, object.optString(key));
        }

        return targetMap;
    }

    private void doPayment(JSONObject params, final CallbackContext callbackContext) throws JSONException {
        JSONArray endUrlRegexJSON = params.optJSONArray("endUrlRegexes");
        String[] endUrlRegexes = null;

        if(endUrlRegexJSON != null) {
            endUrlRegexes = new String[endUrlRegexJSON.length()];

            for(int i=0;i<endUrlRegexJSON.length();i+=1) {
                endUrlRegexes[i] = endUrlRegexJSON.getString(i);
            }
        }

        JuspaySafeBrowser.setEndUrls(endUrlRegexes);


        /*
          Set up the BrowserParams
         */
        BrowserParams browserParams = new BrowserParams();

        // Fill in the main browserParams
        JSONObject browserParamsJSON = params.optJSONObject("browserParams");
        browserParams.setUrl(browserParamsJSON.getString("url"));
        browserParams.setMerchantId(browserParamsJSON.getString("merchantId"));
        browserParams.setClientId(browserParamsJSON.getString("clientId"));
        browserParams.setTransactionId(browserParamsJSON.getString("transactionId"));
        browserParams.setOrderId(browserParamsJSON.getString("orderId"));
        browserParams.setAmount(browserParamsJSON.getString("amount"));
        browserParams.setCustomerEmail(browserParamsJSON.getString("customerEmail"));

        // Try to fill in the non required parameters
        if(browserParamsJSON.has("customerId")) {
            browserParams.setCustomerId(browserParamsJSON.getString("customerId"));
        }

        if(browserParamsJSON.has("postData")) {
            browserParams.setPostData(browserParamsJSON.getString("postData"));
        }

        if(browserParamsJSON.has("customHeaders")) {
            browserParams.setCustomHeaders(copyJSONObjectToMap(browserParamsJSON.getJSONObject("customHeaders")));
        }

        if(browserParamsJSON.has("customParams")) {
            browserParams.setCustomParameters(copyJSONObjectToMap(browserParamsJSON.getJSONObject("customParams")));
        }

        JSONObject stylingParams = params.optJSONObject("actionBar");
        if(stylingParams != null) {
            String actionBarIcon = stylingParams.optString("icon", null);
            String actionBarBackgroundColor = stylingParams.optString("backgroundColor", null);
            String actionBarBackgroundImage = stylingParams.optString("backgroundImage", null);
            String displayNote = stylingParams.optString("displayNote", null);
            String remarks = stylingParams.optString("remarks",null);

            Activity activity = this.cordova.getActivity();

            if(actionBarIcon != null) {
                browserParams.setActionBarIcon(getDrawableForName(actionBarIcon, activity));
            }

            if(actionBarBackgroundColor != null) {
                browserParams.setActionBarBackgroundColor(new ColorDrawable(Color.parseColor(actionBarBackgroundColor)));
            }

            if(actionBarBackgroundImage != null) {
                browserParams.setActionBarBackgroundImage(getDrawableForName(actionBarBackgroundImage, activity));
            }

            if(displayNote != null) {
                browserParams.setDisplayNote(displayNote);
            }

            if(remarks != null) {
                browserParams.setRemarks(remarks);
            }
        }

        /**
        * Here we ensure that we call the same function by specifiying the same callback
        * on JS side
        */
        JuspaySafeBrowser.start(this.cordova.getActivity(), browserParams, new BrowserCallback() {
                @Override
                public void endUrlReached(WebView wv, JSONObject data) {
                    try {
                        JSONObject obj = new JSONObject();
                        obj.put("_method", "endUrlReached");
                        obj.put("data", data);

                        callbackContext.success(obj);
                    } catch(Exception e) {
                        callbackContext.error(e.getMessage());
                    }
                }

                @Override
                public void onTransactionAborted(JSONObject data) {
                    try {
                        JSONObject obj = new JSONObject();
                        obj.put("_method", "onTransactionAborted");
                        obj.put("data", data);
                        callbackContext.success(obj);
                    } catch(Exception e) {
                        callbackContext.error(e.getMessage());
                    }
                }
        });
    }

    private static Drawable getDrawableForName(String name, Activity activity) {
        int id = activity.getResources().getIdentifier(name, "drawable", activity.getPackageName());
        return activity.getResources().getDrawable(id);
    }

    private void trackStatus(JSONObject params) throws JSONException {
        GodelTracker
            .getInstance()
            .trackPaymentStatus(
                params.getString("txnId"),
                params.getString("status")
            );
    }
}
