
package com.veyetals.rppg;

import android.app.Activity;
import android.content.Intent;

import androidx.appcompat.app.AppCompatActivity;

import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.BaseActivityEventListener;
import com.facebook.react.bridge.Promise;
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.markitech.rppg_veyetals.VeyetalsManager;
import com.markitech.rppg_veyetals.models.Vitals;

import java.util.List;

public class RNVeyetalsNativeModule extends ReactContextBaseJavaModule {
  private static final String E_ACTIVITY_DOES_NOT_EXIST = "E_ACTIVITY_DOES_NOT_EXIST";
  private static final String E_VEYETALS_CANCELLED = "E_VEYETALS_CANCELLED";
  private static final String E_FAILED_INITIATE_VEYETALS = "E_FAILED_TO_INITIALIZE_VEYETALS";
  private static final String E_NO_FINAL_RESULTS_FOUND = "E_NO_FINAL_RESULTS_FOUND";
  private static final int REQUEST_VEYETALS = AppCompatActivity.RESULT_FIRST_USER + 1000;

  private final ReactApplicationContext reactContext;
  private Promise mVeyetalsPromise;

  private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() {
    @Override
    public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
      if (requestCode == REQUEST_VEYETALS) {
        if (mVeyetalsPromise != null) {
          if (resultCode == Activity.RESULT_CANCELED) {
            mVeyetalsPromise.reject(E_VEYETALS_CANCELLED, "Veyetals scanning was cancelled");
          } else if (resultCode == Activity.RESULT_OK) {
            List<Vitals> vitals = data.getParcelableArrayListExtra("com.markitech.rppg_veyetals.result_vitals_data");
            Vitals finalResults = null;
            for(Vitals vital : vitals){
              if(vital.isFinal()){
                finalResults = vital;
                break;
              }
            }
            if(finalResults != null) {
              WritableMap map = Arguments.createMap();
              map.putString("Heart-rate", "" + Math.round(finalResults.getHeartRate()));
              map.putString("HRV", "" + Math.round(finalResults.getHeartRateVariability()));
              map.putString("02-saturation", "" + Math.round(finalResults.getO2Saturation()));
              map.putString("Respiration-rate", "" + Math.round(finalResults.getRespiratoryRate()));
              map.putString("Systolic", "" + Math.round(finalResults.getSystolic()));
              map.putString("Diastolic", "" + Math.round(finalResults.getDiastolic()));
              map.putString("Stress-levels", "" + Math.round(finalResults.getStress()));
              mVeyetalsPromise.resolve(map);
            }else{
              mVeyetalsPromise.reject(E_NO_FINAL_RESULTS_FOUND, "Final vitals data is not available");
            }
          }
          mVeyetalsPromise = null;
        }
      }
    }
  };

  public RNVeyetalsNativeModule(ReactApplicationContext reactContext) {
    super(reactContext);
    reactContext.addActivityEventListener(mActivityEventListener);
    this.reactContext = reactContext;
  }

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


  @ReactMethod
  public void start(String userId, String channelId, String mode, boolean isLiteVersion, final Promise promise) {
    Activity currentActivity = getCurrentActivity();

    if (currentActivity == null) {
      promise.reject(E_ACTIVITY_DOES_NOT_EXIST, "Activity doesn't exist");
      return;
    }

    mVeyetalsPromise = promise;

    try {
      String veyetalsMode = "com.markitech.rppg_veyetals.face";
      if (mode != null && mode.equals("finger")){
        veyetalsMode = "com.markitech.rppg_veyetals.finger";
      }
      VeyetalsManager.INSTANCE.startVeyetalsCalculation(getCurrentActivity(), REQUEST_VEYETALS, userId, channelId, veyetalsMode, isLiteVersion);
    } catch (Exception e) {
      mVeyetalsPromise.reject(E_FAILED_INITIATE_VEYETALS, e);
      mVeyetalsPromise = null;
    }
  }

}