package com.reactnativezoom.videosdk;

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.ReadableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeArray;
import com.facebook.react.bridge.WritableNativeMap;

import us.zoom.sdk.ZoomVideoSDK;
import us.zoom.sdk.ZoomVideoSDKCameraDevice;
import us.zoom.sdk.ZoomVideoSDKVideoHelper;
import us.zoom.sdk.ZoomVideoSDKVideoPreferenceSetting;
import us.zoom.sdk.ZoomVideoSDKVideoPreferenceMode;
import us.zoom.sdk.ZoomVideoSDKVideoView;

import com.reactnativezoom.videosdk.convert.RNZoomVideoSDKErrors;
import com.reactnativezoom.videosdk.convert.RNZoomVideoSdkVideoPreferenceMode;

public class RNZoomVideoSdkVideoHelperModule extends ReactContextBaseJavaModule {

  private final ReactApplicationContext reactContext;
  private ZoomVideoSDKVideoView videoView;

  RNZoomVideoSdkVideoHelperModule(ReactApplicationContext reactContext) {
    super(reactContext);
    this.reactContext = reactContext;
  }

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

  private ZoomVideoSDKVideoHelper getVideoHelper() {
    ZoomVideoSDKVideoHelper videoHelper = null;
    try {
      videoHelper = ZoomVideoSDK.getInstance().getVideoHelper();
      if (videoHelper == null) {
        throw new Exception("No Video Helper Found");
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return videoHelper;
  }

  @ReactMethod
  public void getCameraList(Promise promise) {
    WritableArray cameraList = new WritableNativeArray();
    for (ZoomVideoSDKCameraDevice device : getVideoHelper().getCameraList()) {
      WritableMap camera = new WritableNativeMap();
      camera.putString("deviceId", device.getDeviceId());
      camera.putString("deviceName", device.getDeviceName());
      camera.putBoolean("isSelectedDevice", device.isSelectedDevice());
      cameraList.pushMap(camera);
    }

    promise.resolve(cameraList);
  }

  @ReactMethod
  public void getNumberOfCameras(Promise promise) {
    promise.resolve(getVideoHelper().getNumberOfCameras());
  }

  @ReactMethod
  public void rotateMyVideo(double rotation, Promise promise) {
    if (Utils.checkRNActivity(reactContext, promise)) {
      return;
    }
    reactContext.getCurrentActivity().runOnUiThread(new Runnable() {
      @Override
      public void run() {
        promise.resolve(getVideoHelper().rotateMyVideo((int) rotation));
      }
    });
  }

  @ReactMethod
  public void startVideo(Promise promise) {
    if (Utils.checkRNActivity(reactContext, promise)) {
      return;
    }
    reactContext.getCurrentActivity().runOnUiThread(new Runnable() {
      @Override
      public void run() {
        promise.resolve(RNZoomVideoSDKErrors.valueOf(getVideoHelper().startVideo()));
      }
    });
  }

  @ReactMethod
  public void stopVideo(Promise promise) {
    if (Utils.checkRNActivity(reactContext, promise)) {
      return;
    }
    reactContext.getCurrentActivity().runOnUiThread(new Runnable() {
      @Override
      public void run() {
        promise.resolve(RNZoomVideoSDKErrors.valueOf(getVideoHelper().stopVideo()));
      }
    });
  }

  @ReactMethod
  public void switchCamera(String deviceId, Promise promise) {
    if (Utils.checkRNActivity(reactContext, promise)) {
      return;
    }
    reactContext.getCurrentActivity().runOnUiThread(new Runnable() {
      @Override
      public void run() {
        if (deviceId != null) {
          ZoomVideoSDKCameraDevice device = getVideoHelper().getCameraList()
                  .stream()
                  .filter(c -> c.getDeviceId().equals(deviceId))
                  .findAny()
                  .orElse(null);
          if (device != null) {
            promise.resolve(getVideoHelper().switchCamera(device));
          }
        }
        promise.resolve(getVideoHelper().switchCamera());
      }
    });
  }

  @ReactMethod
  public void isOriginalAspectRatioEnabled(Promise promise) {
    if (Utils.checkRNActivity(reactContext, promise)) {
      return;
    }
    reactContext.getCurrentActivity().runOnUiThread(new Runnable() {
      @Override
      public void run() {
        promise.resolve(getVideoHelper().isOriginalAspectRatioEnabled());
      }
    });
  }

  @ReactMethod
  public void enableOriginalAspectRatio(boolean enableOriginalAspectRatio, Promise promise) {
    if (Utils.checkRNActivity(reactContext, promise)) {
      return;
    }
    reactContext.getCurrentActivity().runOnUiThread(new Runnable() {
      @Override
      public void run() {
        promise.resolve(getVideoHelper().enableOriginalAspectRatio(enableOriginalAspectRatio));
      }
    });
  }

  @ReactMethod
  public void isMyVideoMirrored(Promise promise) {
    if (Utils.checkRNActivity(reactContext, promise)) {
      return;
    }
    reactContext.getCurrentActivity().runOnUiThread(new Runnable() {
      @Override
      public void run() {
        promise.resolve(getVideoHelper().isMyVideoMirrored());
      }
    });
  }

  @ReactMethod
  public void mirrorMyVideo(boolean enable, Promise promise) {
    if (Utils.checkRNActivity(reactContext, promise)) {
      return;
    }
    reactContext.getCurrentActivity().runOnUiThread(new Runnable() {
      @Override
      public void run() {
        promise.resolve(RNZoomVideoSDKErrors.valueOf(getVideoHelper().mirrorMyVideo(enable)));
      }
    });
  }

  @ReactMethod
    public void turnOnOrOffFlashlight(boolean enable, Promise promise) {
      if (Utils.checkRNActivity(reactContext, promise)) {
      return;
    }
      reactContext.getCurrentActivity().runOnUiThread(new Runnable() {
        @Override
        public void run() {
          promise.resolve(getVideoHelper().turnOnOrOffFlashlight(enable));
        }
      });
    }

    @ReactMethod
    public void isSupportFlashlight(Promise promise) {
      if (Utils.checkRNActivity(reactContext, promise)) {
      return;
    }
      reactContext.getCurrentActivity().runOnUiThread(new Runnable() {
        @Override
        public void run() {
          promise.resolve(getVideoHelper().isSupportFlashlight());
        }
      });
    }

    @ReactMethod
    public void isFlashlightOn(Promise promise) {
      if (Utils.checkRNActivity(reactContext, promise)) {
      return;
    }
      reactContext.getCurrentActivity().runOnUiThread(new Runnable() {
        @Override
        public void run() {
          promise.resolve(getVideoHelper().isFlashlightOn());
        }
      });
    }
}
