
package com.reactlibrary;

import android.app.Activity;
import android.content.Context;
import android.widget.Toast;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;

import net.crowdconnected.androidcolocator.CoLocator;
import net.crowdconnected.androidcolocator.LocationCallback;
import net.crowdconnected.androidcolocator.connector.LocationResponse;

import java.util.List;
import java.util.logging.Logger;

public class RNNativeCarthageColocatorLibraryModule extends ReactContextBaseJavaModule {

  private final ReactApplicationContext reactContext;

  public static Logger logger = Logger.getLogger("global");

  public RNNativeCarthageColocatorLibraryModule(ReactApplicationContext reactContext) {
    super(reactContext);
    this.reactContext = reactContext;
  }

  @Override
  public String getName() {
    return "RNNativeCarthageColocatorLibrary";
  }

  @ReactMethod
  public void show(String text) {
    Context context = getReactApplicationContext();
    Toast.makeText(context, text, Toast.LENGTH_LONG).show();
  }

  @ReactMethod
  public void start(String apiKey) {
    Activity activity = getCurrentActivity();
    if (activity != null) {
      CoLocator.start(activity.getApplication(), apiKey);
      logger.info("Colocator start has been called with key " + apiKey);
    } else {
      logger.info("Colocator cannot be stared because activity is null");
    }
  }

  @ReactMethod
  public void startWithKeyAndUrl(String apiKey, String urlString) {
    Activity activity = getCurrentActivity();
    if (activity != null) {
      CoLocator.start(activity.getApplication(), apiKey, urlString);
      logger.info("Colocator start has been called with key " + apiKey + " and url " + urlString);
    } else {
      logger.info("Colocator cannot be stared because activity is null");
    }
  }

  @ReactMethod
  public void stop() {
    Activity activity = getCurrentActivity();
    if (activity != null) {
      CoLocator.instance().stop();
      logger.info("Colocator stop has been called");
    } else {
      logger.info("Colocator cannot be stopped because activity is null");
    }
  }

  @ReactMethod
  public void askForMotionPermission() {
    logger.info("Colocator Android doesn't have askForMotionPermission method");
  }

  @ReactMethod
  public void triggerBluetoothPermissionPopUp() {
    logger.info("Colocator Android doesn't have triggerBluetoothPermissionPopUp method");
  }

  @ReactMethod
  public void getDeviceID() {
    String deviceID = CoLocator.instance().getDeviceId();
    logger.info("Colocator provided device ID " + deviceID);
  }

  @ReactMethod
  public void addAlias(String key, String value) {
    CoLocator.instance().addAlias(key, value);
    logger.info("Colocator added alias [" + key + ": " + value + "]");
  }

  @ReactMethod
  public void requestLocation() {
    CoLocator.instance().requestLocation(new LocationCallback() {
      @Override
      public void onLocationReceived(LocationResponse response) {
        logger.info("Colocator received location response (" + response.getLatitude() + ", " + response.getLongitude() + ", " + response.getError() + ")");

        WritableMap params = Arguments.createMap();
        params.putDouble("latitude", response.getLatitude());
        params.putDouble("longitude", response.getLongitude());
        params.putDouble("headingOffset", response.getHeadingOffset());
        params.putDouble("error", response.getError());
        params.putDouble("timestamp", (double)response.getTimestamp());

        reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("LocationResponse", params);
      }

      @Override
      public void onLocationsReceived(List<LocationResponse> list) { }
    });
    logger.info("Colocator requestLocation method called");
  }

  @ReactMethod
  public void registerLocationListener() {
    CoLocator.instance().registerLocationListener(new LocationCallback() {
      @Override
      public void onLocationReceived(LocationResponse locationResponse) { }

      @Override
      public void onLocationsReceived(List<LocationResponse> list) {
        for (LocationResponse response : list) {
          logger.info("Colocator received location response (" + response.getLatitude() + ", " + response.getLongitude() + ", " + response.getError() + ")");

          WritableMap params = Arguments.createMap();
          params.putDouble("latitude", response.getLatitude());
          params.putDouble("longitude", response.getLongitude());
          params.putDouble("headingOffset", response.getHeadingOffset());
          params.putDouble("error", response.getError());
          params.putDouble("timestamp", (double)response.getTimestamp());

          reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("LocationResponse", params);
        }
      }
    });

    logger.info("Colocator registerLocationListener method called");
  }

  @ReactMethod
  public void unregisterLocationListener() {
    CoLocator.instance().unregisterLocationListener();
    logger.info("Colocator unregisterLocationListener method called");
  }
}