package io.clef.cordova;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.FragmentActivity;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.jdeferred.DoneCallback;
import org.jdeferred.FailCallback;
import org.json.JSONArray;
import org.json.JSONException;

import java.util.UUID;

import io.clef.sdk.Client;

import io.clef.cordova.LoginCompatActivity;
import static timber.log.Timber.*;

/**
 * This class echoes a string called from JavaScript.
 */
public class Plugin extends CordovaPlugin {
    static Client client;
    static CallbackContext cb;
    static final int INTENT_TO_SIGN_IN = 0x1000001;
    static final int INTENT_TO_REGISTER = 0x1000002;

    @Override
    public boolean execute(final String action, final JSONArray args, CallbackContext callbackContext) throws JSONException {
        d("Obtained action '%s'.", action);
        switch (action) {
          case "configure":
            final String appId = args.getString(0);
            this.configure(appId, callbackContext);
            break;
          case "register":
            this.register(callbackContext);
            break;
          case "signIn":
            this.signIn(callbackContext);
            break;
          case "isRegistered":
            this.checkIfRegistered(callbackContext);
            break;
          case "unregister":
            this.unregister(callbackContext);
            break;
          default:
            return false;
        }

        return true;
    }

    private void runInBackground(final Runnable runnable) {
        cordova.getThreadPool().execute(runnable);
    }

    private void runOnUiThread(final Runnable runnable) {
        cordova.getActivity().runOnUiThread(runnable);
    }

    public void unregister(final CallbackContext callbackContext) {
        runInBackground(new Runnable() {
          public void run() {
            client.unregisterDevice()
              .then(new DoneCallback<String>() {
                public void onDone(final String result) {
                  callbackContext.success(result);
                }
              }, new FailCallback<Throwable>() {
                public void onFail(final Throwable failure) {
                  callbackContext.error(failure.getMessage());
                }
              });
          }
        });
    }


    public void checkIfRegistered(final CallbackContext callbackContext) {
        runInBackground(new Runnable() {
          public void run() {
            if (client.isRegistered()) {
              callbackContext.success();
            } else {
              callbackContext.error("This device is not registered.");
            }
          }
        });
    }

    private void configure(final String appId, final CallbackContext callbackContext) {
        runInBackground(new Runnable() {
          public void run() {
            if (appId != null && appId.length() > 0) {
                client = Client.initialize(appId, cordova.getActivity());
                callbackContext.success();
            } else {
                callbackContext.error("Expected one non-empty string argument.");
            }
          }
        });
    }

    private void register(final CallbackContext callbackContext) {
        cb = callbackContext;
        runOnUiThread(new Runnable() {
          public void run() {
            final Intent intent = new Intent(cordova.getActivity(), LoginCompatActivity.class);
            intent.putExtra("action", LoginCompatActivity.ACTION_REGISTER);
            cordova.getActivity().startActivityForResult(intent, INTENT_TO_REGISTER);
          }
        });
    }

    /*
     * This is a special case. We need to get access to a `FragmentManager`
     * in order to present the dialog fragment that holds the logic for
     * rendering and presenting the Wave.
     *
     * The problem is that Cordova does not make use of the support libraries
     * and we do. This requires us to launch a compatible activity and launch
     * the Wave from there.
     */
    private void signIn(final CallbackContext callbackContext) {
        cb = callbackContext;
        runOnUiThread(new Runnable() {
          public void run() {
            final Intent intent = new Intent(cordova.getActivity(), LoginCompatActivity.class);
            intent.putExtra("action", LoginCompatActivity.ACTION_SIGN_IN);
            cordova.getActivity().startActivityForResult(intent, INTENT_TO_SIGN_IN);
          }
        });
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        d("Got intent with data: %s", intent.toUri(Intent.URI_INTENT_SCHEME));
        if (requestCode == INTENT_TO_SIGN_IN && resultCode == Activity.RESULT_OK) {
          cordova.getActivity().finish();
        } else {
          super.onActivityResult(requestCode, resultCode, intent);
        }
    }
}
