package com.ctpodp;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.widget.FrameLayout;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.inpixon.odp.Extend;
import com.inpixon.odp.TDNavOutput;
import com.inpixon.odp.aiding.FloorPlan;
import com.inpixon.odp.aiding.Location;
import com.inpixon.odp.aiding.Region;

import java.util.List;

public class OdpView extends FrameLayout {
  ReactContext _reactContext;
  Extend _extend = null;
  Long _lastTime = 0L;
  Double _odpUpdateDelayMs = 0.0;

  public OdpView(@NonNull Context context) {
    super(context);
  }

  public void sendEvent(String topic, WritableMap data) {
    _reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
        .emit(topic, data);
  }

  public void start(ReactContext reactContext, String key, String host, double odpUpdateDelayMs) {
    _reactContext = reactContext;
    _odpUpdateDelayMs = odpUpdateDelayMs;

    Toast.makeText(_reactContext, "Extend Initializing", Toast.LENGTH_SHORT).show();
    if (_extend != null) {
      onDestroy();
    }
    _extend = new Extend(_reactContext, key, host);
    _extend.setOnExtend(new ExtendListener());
    _extend.bind();
  }

  public void onDestroy() {
    try {
      _extend.unbind();
    } catch (Exception e) {

    }
  }

  public void uploadLogs() {
    _extend.uploadLogs();
  }

  @Override
  public void onDetachedFromWindow() {
    onDestroy();
    super.onDetachedFromWindow();
  }

  class ExtendListener implements Extend.OnExtend {

    @Override
    public void onReady(boolean b) {
      WritableMap params = Arguments.createMap();
      params.putBoolean("boolean", b);
      Log.d("Extend", "Extend Ready");

      sendEvent("ODP_READY", params);
    }

    @Override
    public void onKeyValidation(boolean validated) {
      if (validated) { // The key has been validated. Set whichever modules you want enabled
        // or disabled here and start the service after these calls.
        // Toast.makeText(_reactContext, "Key Valid", Toast.LENGTH_SHORT).show();
        Log.d("Extend", "Extend Started");
        _extend.setLogWriting(true); // enable sensor logging for debug
        _extend.setVicinityEnabled(true);
        _extend.start();
      } else { // The key is invalid or expired.
        // Toast.makeText(_reactContext, "Key Not Valid", Toast.LENGTH_SHORT).show();
        Log.d("Extend", "Extend Not Started");
      }
    }

    @Override
    public void onNavigationUpdate(TDNavOutput navOutput) {
      // Ignore updates that are too frequent
      Long currentTime = System.currentTimeMillis();
      if (currentTime - _lastTime < _odpUpdateDelayMs) {
        return;
      } else {
        _lastTime = currentTime;
      }

      // Send the update
      WritableMap params = Arguments.createMap();
      params.putDouble("lat", navOutput.latitude);
      params.putDouble("long", navOutput.longitude);
      params.putDouble("x", navOutput.x);
      params.putDouble("y", navOutput.y);
      params.putDouble("xfom", navOutput.xfom);
      params.putDouble("yfom", navOutput.yfom);
      params.putDouble("viewHeading", navOutput.viewHeading);
      params.putDouble("bearing", navOutput.bearing);
      params.putDouble("accuracyRadius", navOutput.accuracyRadius);
      params.putInt("floor", navOutput.floor);
      params.putDouble("utc", navOutput.utc);
      params.putInt("dynamicState", navOutput.dynamicState);
      params.putInt("elevationState", navOutput.elevationState);
      params.putInt("usedSystems", navOutput.usedSystems);
      sendEvent("ODP_NAVIGATION_UPDATE", params);
    }

    @Override
    public void onFacilityUpdate(String name, Location location, Region region, List<FloorPlan> floorPlans) {
      Log.d("Extend", "onFacilityUpdate: " + name);
      WritableMap params = Arguments.createMap();

      // Name
      params.putString("name", name);

      // // Location
      // WritableMap locationMap = Arguments.createMap();
      // locationMap.putDouble("latitude", location.getLatitude());
      // locationMap.putDouble("longitude", location.getLongitude());
      // locationMap.putDouble("altitude", location.getAltitude());
      // locationMap.putDouble("x", location.getX());
      // locationMap.putDouble("y", location.getY());
      // locationMap.putDouble("z", location.getZ());
      // locationMap.putBoolean("isGeo", location.getIsGeo());
      // params.putMap("location", locationMap);
      //
      // // Region
      // WritableMap regionMap = Arguments.createMap();
      // locationMap.putDouble("floor", region.getFloor());
      // locationMap.putDouble("id", region.getId());
      // locationMap.putString("name", region.getName());
      // locationMap.putString("icon", region.getIcon());
      // WritableArray pointsArray = Arguments.createArray();
      // for (Location pointLocation : region.getPoints()) {
      // WritableMap pLMap = Arguments.createMap();
      // pLMap.putDouble("latitude", pointLocation.getLatitude());
      // pLMap.putDouble("longitude", pointLocation.getLongitude());
      // pLMap.putDouble("altitude", pointLocation.getAltitude());
      // pLMap.putDouble("x", pointLocation.getX());
      // pLMap.putDouble("y", pointLocation.getY());
      // pLMap.putDouble("x", pointLocation.getZ());
      // pLMap.putBoolean("isGeo", pointLocation.getIsGeo());
      // pointsArray.pushMap(pLMap);
      // }
      // locationMap.putArray("points", pointsArray);
      // locationMap.putString("className", region.getClass().getSimpleName());
      // params.putMap("region", regionMap);
      //
      // // FloorPlans
      // WritableArray floorPlanArr = Arguments.createArray();
      // for (FloorPlan floorPlan : floorPlans) {
      // WritableMap flPlanMap = Arguments.createMap();
      // flPlanMap.putDouble("floor", floorPlan.getFloor());
      // flPlanMap.putInt("describeContents", floorPlan.describeContents());
      // flPlanMap.putDouble("latitude", floorPlan.getGeoHeight());
      // flPlanMap.putDouble("xMax", floorPlan.getXMax());
      // flPlanMap.putDouble("xMin", floorPlan.getXMin());
      // flPlanMap.putDouble("yMax", floorPlan.getYMax());
      // flPlanMap.putDouble("yMin", floorPlan.getYMin());
      // flPlanMap.putString("file", floorPlan.getFile());
      // flPlanMap.putString("name", floorPlan.getName());
      // flPlanMap.putString("className", floorPlan.getClass().getSimpleName());
      // floorPlanArr.pushMap(flPlanMap);
      // }
      // params.putArray("floorPlans", floorPlanArr);

      sendEvent("ODP_FACILITY_UPDATE", params);
    }

    @Override
    public void onDebugEvent(Bundle bundle) {

    }

    @Override
    public void onUploadProgressUpdate(int i, int i1, int i2, int i3) {

    }
  }

}
