package com.sdk;

import com.trtcreactnativesdk.listener.CustomTRTCCloudListener;

import androidx.annotation.NonNull;
import android.content.Context;
import android.text.TextUtils;
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.module.annotations.ReactModule;
import com.tencent.liteav.audio.TXAudioEffectManager;
import com.tencent.liteav.beauty.TXBeautyManager;
import com.tencent.liteav.device.TXDeviceManager;
import com.tencent.rtmp.ui.TXCloudVideoView;
import com.tencent.trtc.TRTCCloud;
import com.tencent.trtc.TRTCCloudDef;
import com.tencent.trtc.TRTCCloudListener;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.Toast;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.Arguments;
import com.google.gson.Gson;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

@ReactModule(name = TRTCReactNativeSdkModule.NAME)
public class TRTCReactNativeSdkModule extends ReactContextBaseJavaModule {
    public static final String NAME = "TRTCReactNativeSdk";
    private TRTCCloud trtcCloud;
    private TXDeviceManager txDeviceManager;
    private TXBeautyManager txBeautyManager;
    private TXAudioEffectManager txAudioEffectManager;
    private ReactApplicationContext trtReactContext;
    private static final String TAG = "TRTCCloudRN";
    private CustomTRTCCloudListener trtcListener;
    public TRTCReactNativeSdkModule(ReactApplicationContext reactContext) {
        super(reactContext);
        trtReactContext= reactContext;
    }

    @Override
    @NonNull
    public String getName() {
        return NAME;
    }

    // Example method
    // See https://reactnative.dev/docs/native-modules-android
    @ReactMethod
    public void sharedInstance(Promise promise) {
      trtcCloud = TRTCCloud.sharedInstance(getReactApplicationContext());
      trtcListener = new CustomTRTCCloudListener(trtReactContext);
      trtcCloud.setListener(trtcListener);
      promise.resolve(null);
    }
    @ReactMethod
    public void destroySharedInstance(Promise promise) {
      TRTCCloud.destroySharedInstance();
      trtcCloud = null;
      promise.resolve(null);
    }

    @ReactMethod
    public void getSDKVersion(Promise promise) {
      String version = trtcCloud.getSDKVersion();
      promise.resolve(version);
    }
    @ReactMethod
    public void enterRoom(ReadableMap params, int scene, Promise promise) {
      trtcCloud.callExperimentalAPI("{\"api\": \"setFramework\", \"params\": {\"framework\": 22}}");
      TRTCCloudDef.TRTCParams trtcP = new TRTCCloudDef.TRTCParams();
      trtcP.sdkAppId = params.getInt("sdkAppId");
      trtcP.userId = params.getString("userId");
      trtcP.userSig = params.getString("userSig");
      String roomId = params.getString("roomId");
      trtcP.roomId = (int) (Long.parseLong(roomId) & 0xFFFFFFFF);
      trtcP.strRoomId = params.getString("strRoomId");
      trtcP.role = params.getInt("role");
      trtcP.streamId = params.getString("streamId");
      trtcP.userDefineRecordId = params.getString("userDefineRecordId");
      trtcP.privateMapKey = params.getString("privateMapKey");
      trtcP.businessInfo = params.getString("businessInfo");

      trtcCloud.enterRoom(trtcP, scene);
      promise.resolve(null);
    }
    @ReactMethod
    public void exitRoom(Promise promise) {
      trtcCloud.exitRoom();
      promise.resolve(null);
    }
    @ReactMethod
    public void connectOtherRoom(ReadableMap params, Promise promise) {
      String param = params.getString("param");
      trtcCloud.ConnectOtherRoom(param);
      promise.resolve(null);
    }
    @ReactMethod
    public void disconnectOtherRoom(Promise promise) {
      trtcCloud.DisconnectOtherRoom();
      promise.resolve(null);
    }
    @ReactMethod
    private void setMixTranscodingConfig(ReadableMap params, Promise promise) {
      String config = params.getString("config");
      System.out.println(config);
      trtcCloud.setMixTranscodingConfig(new Gson().fromJson(config, TRTCCloudDef.TRTCTranscodingConfig.class));
      promise.resolve(null);
    }
    @ReactMethod
    public void switchRole(ReadableMap params, Promise promise) {
      int role = params.getInt("role");
      trtcCloud.switchRole(role);
      promise.resolve(null);
    }
    @ReactMethod
    public void setDefaultStreamRecvMode(ReadableMap params, Promise promise) {
      boolean autoRecvAudioc = params.getBoolean("autoRecvAudio");
      boolean autoRecvVideo = params.getBoolean("autoRecvVideo");
      trtcCloud.setDefaultStreamRecvMode(autoRecvAudioc, autoRecvVideo);
      promise.resolve(null);
    }
    @ReactMethod
    public void switchRoom(ReadableMap params, Promise promise) {
      String config = params.getString("config");
      trtcCloud.switchRoom(new Gson().fromJson(config, TRTCCloudDef.TRTCSwitchRoomConfig.class));
      promise.resolve(null);
    }
    @ReactMethod
    public void startPublishing(ReadableMap params, Promise promise) {
      String streamId = params.getString("streamId");
      int streamType =params.getInt("streamType");
      trtcCloud.startPublishing(streamId, streamType);
      promise.resolve(null);
    }
    @ReactMethod
    private void stopPublishing(Promise promise) {
      trtcCloud.stopPublishing();
      promise.resolve(null);
    }

    @ReactMethod
    private void startPublishCDNStream(ReadableMap params, Promise promise) {
      String param = params.getString("param");
      trtcCloud.startPublishCDNStream(new Gson().fromJson(param, TRTCCloudDef.TRTCPublishCDNParam.class));
      promise.resolve(null);
    }

    @ReactMethod
    private void stopPublishCDNStream(Promise promise) {
      trtcCloud.stopPublishCDNStream();
      promise.resolve(null);
    }
    @ReactMethod
    private void stopLocalPreview(Promise promise) {
      trtcCloud.stopLocalPreview();
      promise.resolve(null);
    }

    @ReactMethod
    private void stopRemoteView(ReadableMap params, Promise promise) {
      String userId = params.getString("userId");
      int streamType = params.getInt("streamType");
      trtcCloud.stopRemoteView(userId, streamType);
      promise.resolve(null);
    }

    @ReactMethod
    private void stopAllRemoteView(Promise promise) {
      trtcCloud.stopAllRemoteView();
      promise.resolve(null);
    }

    @ReactMethod
    private void muteRemoteAudio(ReadableMap params, Promise promise) {
      String userId = params.getString("userId");
      boolean mute = params.getBoolean("mute");
      trtcCloud.muteRemoteAudio(userId, mute);
      promise.resolve(null);
    }

    @ReactMethod
    private void muteAllRemoteAudio(ReadableMap params, Promise promise) {
        boolean mute = params.getBoolean("mute");
        trtcCloud.muteAllRemoteAudio(mute);
        promise.resolve(null);
    }

    @ReactMethod
    private void setRemoteAudioVolume(ReadableMap params, Promise promise) {
        String userId = params.getString("userId");
        int volume = params.getInt("volume");
        trtcCloud.setRemoteAudioVolume(userId, volume);
        promise.resolve(null);
    }

    @ReactMethod
    private void setAudioCaptureVolume(ReadableMap params, Promise promise) {
        int volume = params.getInt("volume");
        trtcCloud.setAudioCaptureVolume(volume);
        promise.resolve(null);
    }

    @ReactMethod
    private void getAudioCaptureVolume(Promise promise) {
      promise.resolve(trtcCloud.getAudioCaptureVolume());
    }

    @ReactMethod
    private void setAudioPlayoutVolume(ReadableMap params, Promise promise) {
      int volume = params.getInt("volume");
      trtcCloud.setAudioPlayoutVolume(volume);
      promise.resolve(null);
    }

    @ReactMethod
    private void getAudioPlayoutVolume(Promise promise) {
      promise.resolve(trtcCloud.getAudioPlayoutVolume());
    }

    @ReactMethod
    private void startLocalAudio(ReadableMap params, Promise promise) {
      int quality = params.getInt("quality");
      trtcCloud.startLocalAudio(quality);
      promise.resolve(null);
    }

    @ReactMethod
    private void stopLocalAudio(Promise promise) {
        trtcCloud.stopLocalAudio();
        promise.resolve(null);
    }

    @ReactMethod
    private void muteLocalAudio(ReadableMap params, Promise promise) {
      boolean mute = params.getBoolean("mute");
      trtcCloud.muteLocalAudio(mute);
      promise.resolve(null);
    }

    @ReactMethod
    private void muteLocalVideo(ReadableMap params, Promise promise) {
      boolean mute = params.getBoolean( "mute");
      trtcCloud.muteLocalVideo(mute);
      promise.resolve(null);
    }

  @ReactMethod
  private void setVideoMuteImage(ReadableMap params, Promise promise) {
    final String imageUrl = params.getString("imageUrl");
    final int fps = params.getInt( "fps");
    if (imageUrl.equals("")) {
      trtcCloud.setVideoMuteImage(null, fps);
    } else {
        new Thread() {
          @Override
          public void run() {
            try {
              URL url = new URL(imageUrl);
              HttpURLConnection connection = (HttpURLConnection) url.openConnection();
              connection.setDoInput(true);
              connection.connect();
              InputStream input = connection.getInputStream();
              Bitmap myBitmap = BitmapFactory.decodeStream(input);
              trtcCloud.setVideoMuteImage(myBitmap, fps);
            } catch (IOException e) {
            //   TXLog.e(TAG, "|method=setVideoMuteImage|error=" + e);
            }
          }
        }.start();
    }
    promise.resolve(null);
  }

  @ReactMethod
  private void setWatermark(ReadableMap params, Promise promise) {
    final String imageUrl = params.getString("imageUrl");
    final int streamType = params.getInt("streamType");
    String xStr = params.getString("x");
    final float x = Float.parseFloat(xStr);
    String yStr = params.getString("y");
    final float y = Float.parseFloat(yStr);
    String widthStr = params.getString("width");
    final float width = Float.parseFloat(widthStr);
    new Thread() {
      @Override
      public void run() {
        try {
          URL url = new URL(imageUrl);
          HttpURLConnection connection = (HttpURLConnection) url.openConnection();
          connection.setDoInput(true);
          connection.connect();
          InputStream input = connection.getInputStream();
          Bitmap myBitmap = BitmapFactory.decodeStream(input);
          trtcCloud.setWatermark(myBitmap, streamType, x, y, width);
        } catch (IOException e) {
        //   TXLog.e(TAG,"|method=setWatermark|error=" + e);
        }
      }
    }.start();
    promise.resolve(null);
  }

    @ReactMethod
    private void muteRemoteVideoStream(ReadableMap params, Promise promise) {
      String userId = params.getString("userId");
      boolean mute = params.getBoolean("mute");
      trtcCloud.muteRemoteVideoStream(userId, mute);
      promise.resolve(null);
    }

    @ReactMethod
    private void muteAllRemoteVideoStreams(ReadableMap params, Promise promise) {
      boolean mute = params.getBoolean("mute");
      trtcCloud.muteAllRemoteVideoStreams(mute);
      promise.resolve(null);
    }

    @ReactMethod
    private void setVideoEncoderParam(ReadableMap params, Promise promise) {
      String param = params.getString("param");
      trtcCloud.setVideoEncoderParam(new Gson().fromJson(param, TRTCCloudDef.TRTCVideoEncParam.class));
      promise.resolve(null);
    }

    
    @ReactMethod
    private void setNetworkQosParam(ReadableMap params, Promise promise) {
      String param = params.getString("param");
      trtcCloud.setNetworkQosParam(new Gson().fromJson(param, TRTCCloudDef.TRTCNetworkQosParam.class));
      promise.resolve(null);
    }

    
    @ReactMethod
    private void setVideoEncoderRotation(ReadableMap params, Promise promise) {
      int rotation = params.getInt("rotation");
      trtcCloud.setVideoEncoderRotation(rotation);
      promise.resolve(null);
    }

    
    @ReactMethod
    private void setVideoEncoderMirror(ReadableMap params, Promise promise) {
      boolean mirror = params.getBoolean("mirror");
      trtcCloud.setVideoEncoderMirror(mirror);
      promise.resolve(null);
    }

    @ReactMethod
    private void setGSensorMode(ReadableMap params, Promise promise) {
      int mode = params.getInt("mode");
      trtcCloud.setGSensorMode(mode);
      promise.resolve(null);
    }

    @ReactMethod
    private void setAudioRoute(ReadableMap params, Promise promise) {
      int route = params.getInt("route");
      trtcCloud.setAudioRoute(route);
      promise.resolve(null);
    }

    @ReactMethod
    private void enableAudioVolumeEvaluation(ReadableMap params, Promise promise) {
        int intervalMs = params.getInt("intervalMs");
        trtcCloud.enableAudioVolumeEvaluation(intervalMs);
        promise.resolve(null);
    }

    @ReactMethod
    private void startAudioRecording(ReadableMap params, Promise promise) {
        String filePath = params.getString("filePath");
        TRTCCloudDef.TRTCAudioRecordingParams recordParam = new TRTCCloudDef.TRTCAudioRecordingParams();
        recordParam.filePath = filePath;
        int value = trtcCloud.startAudioRecording(recordParam);
        promise.resolve(value);
    }

    @ReactMethod
    private void stopAudioRecording(Promise promise) {
        trtcCloud.stopAudioRecording();
        promise.resolve(null);
    }

    @ReactMethod
    private void startLocalRecording(ReadableMap params, Promise promise) {
        String param = params.getString("param");
        trtcCloud.startLocalRecording(new Gson().fromJson(param, TRTCCloudDef.TRTCLocalRecordingParams.class));
        promise.resolve(null);
    }

    @ReactMethod
    private void stopLocalRecording(Promise promise) {
        trtcCloud.stopLocalRecording();
        promise.resolve(null);
    }

    @ReactMethod
    private void setSystemVolumeType(ReadableMap params, Promise promise) {
        int type = params.getInt("type");
        trtcCloud.setSystemVolumeType(type);
        promise.resolve(null);
    }

    @ReactMethod
    private void getDeviceManager(Promise promise) {
      txDeviceManager = trtcCloud.getDeviceManager();
      promise.resolve(null);
    }

    @ReactMethod
    private void getBeautyManager(Promise promise) {
      txBeautyManager = trtcCloud.getBeautyManager();
      promise.resolve(null);
    }

    @ReactMethod
    public void getAudioEffectManager(Promise promise) {
      txAudioEffectManager = trtcCloud.getAudioEffectManager();
      promise.resolve(null);
    }

    @ReactMethod
    private void startSpeedTest(ReadableMap params, Promise promise) {
      int expectedUpBandwidth = params.getInt("expectedUpBandwidth");
      int expectedDownBandwidth = params.getInt("expectedDownBandwidth");
      int scene = params.getInt("scene");
      int sdkAppId = params.getInt("sdkAppId");
      String userId = params.getString("userId");
      String userSig = params.getString("userSig");
      TRTCCloudDef.TRTCSpeedTestParams testParams = new TRTCCloudDef.TRTCSpeedTestParams();
      testParams.expectedUpBandwidth = expectedUpBandwidth;
      testParams.expectedDownBandwidth = expectedDownBandwidth;
      testParams.scene = scene;
      testParams.userSig = userSig;
      testParams.userId = userId;
      testParams.sdkAppId = sdkAppId;
      trtcCloud.startSpeedTest(testParams);
      promise.resolve(null);
    }

    @ReactMethod
    private void stopSpeedTest(Promise promise) {
      trtcCloud.stopSpeedTest();
      promise.resolve(null);
    }

    @ReactMethod
    public void sendSEIMsg(ReadableMap params, Promise promise) {
      String message = params.getString("message");
      int repeatCount = params.getInt("repeatCount");
      message = TextUtils.isEmpty(message)? "" : message;
      trtcCloud.sendSEIMsg(message.getBytes(), repeatCount);
      promise.resolve(null);
    }

    @ReactMethod
    public void sendCustomCmdMsg(ReadableMap params, Promise promise) {
        int cmdID = params.getInt("cmdID");
        String data = params.getString("data");
        data = TextUtils.isEmpty(data)? "" : data;
        boolean reliable = params.getBoolean("reliable");
        boolean ordered = params.getBoolean("ordered");
        trtcCloud.sendCustomCmdMsg(cmdID, data.getBytes(), reliable, ordered);
        promise.resolve(null);
    }

    @ReactMethod
    private void setLogLevel(ReadableMap params, Promise promise) {
      int level = params.getInt("level");
      trtcCloud.setLogLevel(level);
      promise.resolve(null);
    }

    @ReactMethod
    private void setConsoleEnabled(ReadableMap params, Promise promise) {
      boolean enabled = params.getBoolean("enabled");
      TRTCCloud.setConsoleEnabled(enabled);
      promise.resolve(null);
    }

    @ReactMethod
    private void setLogDirPath(ReadableMap params, Promise promise) {
      String path = params.getString("path");
      TRTCCloud.setLogDirPath(path);
      promise.resolve(null);
    }

    @ReactMethod
    private void setLogCompressEnabled(ReadableMap params, Promise promise) {
      boolean enabled = params.getBoolean("enabled");
      TRTCCloud.setLogCompressEnabled(enabled);
      promise.resolve(null);
    }

    @ReactMethod
    private void callExperimentalAPI(ReadableMap params, Promise promise) {
      String jsonStr = params.getString("jsonStr");
      trtcCloud.callExperimentalAPI(jsonStr);
      promise.resolve(null);
    }

    @ReactMethod
    private void enableVoiceEarMonitor(ReadableMap params, Promise promise) {
      boolean enable = params.getBoolean("enable");
      txAudioEffectManager.enableVoiceEarMonitor(enable);
      promise.resolve(null);
    }

  @ReactMethod
  private void setVoiceEarMonitorVolume(ReadableMap params, Promise promise) {
    int volume = params.getInt("volume");
    txAudioEffectManager.setVoiceEarMonitorVolume(volume);
    promise.resolve(null);
  }

  @ReactMethod
  private void setVoiceReverbType(ReadableMap params, Promise promise) {
    int type = params.getInt("type");
    TXAudioEffectManager.TXVoiceReverbType reverbType =
      TXAudioEffectManager.TXVoiceReverbType.TXLiveVoiceReverbType_0;
    switch (type) {
      case 0:
        reverbType = TXAudioEffectManager.TXVoiceReverbType.TXLiveVoiceReverbType_0;
        break;
      case 1:
        reverbType = TXAudioEffectManager.TXVoiceReverbType.TXLiveVoiceReverbType_1;
        break;
      case 2:
        reverbType = TXAudioEffectManager.TXVoiceReverbType.TXLiveVoiceReverbType_2;
        break;
      case 3:
        reverbType = TXAudioEffectManager.TXVoiceReverbType.TXLiveVoiceReverbType_3;
        break;
      case 4:
        reverbType = TXAudioEffectManager.TXVoiceReverbType.TXLiveVoiceReverbType_4;
        break;
      case 5:
        reverbType = TXAudioEffectManager.TXVoiceReverbType.TXLiveVoiceReverbType_5;
        break;
      case 6:
        reverbType = TXAudioEffectManager.TXVoiceReverbType.TXLiveVoiceReverbType_6;
        break;
      case 7:
        reverbType = TXAudioEffectManager.TXVoiceReverbType.TXLiveVoiceReverbType_7;
        break;
      default:
        reverbType = TXAudioEffectManager.TXVoiceReverbType.TXLiveVoiceReverbType_0;
        break;
    }
    txAudioEffectManager.setVoiceReverbType(reverbType);
    promise.resolve(null);
  }

  @ReactMethod
  private void setVoiceChangerType(ReadableMap params, Promise promise) {
    int type = params.getInt("type");
    TXAudioEffectManager.TXVoiceChangerType changerType =
      TXAudioEffectManager.TXVoiceChangerType.TXLiveVoiceChangerType_0;
    switch (type) {
      case 0:
        changerType = TXAudioEffectManager.TXVoiceChangerType.TXLiveVoiceChangerType_0;
        break;
      case 1:
        changerType = TXAudioEffectManager.TXVoiceChangerType.TXLiveVoiceChangerType_1;
        break;
      case 2:
        changerType = TXAudioEffectManager.TXVoiceChangerType.TXLiveVoiceChangerType_2;
        break;
      case 3:
        changerType = TXAudioEffectManager.TXVoiceChangerType.TXLiveVoiceChangerType_3;
        break;
      case 4:
        changerType = TXAudioEffectManager.TXVoiceChangerType.TXLiveVoiceChangerType_4;
        break;
      case 5:
        changerType = TXAudioEffectManager.TXVoiceChangerType.TXLiveVoiceChangerType_5;
        break;
      case 6:
        changerType = TXAudioEffectManager.TXVoiceChangerType.TXLiveVoiceChangerType_6;
        break;
      case 7:
        changerType = TXAudioEffectManager.TXVoiceChangerType.TXLiveVoiceChangerType_7;
        break;
      case 8:
        changerType = TXAudioEffectManager.TXVoiceChangerType.TXLiveVoiceChangerType_8;
        break;
      case 9:
        changerType = TXAudioEffectManager.TXVoiceChangerType.TXLiveVoiceChangerType_9;
        break;
      case 10:
        changerType = TXAudioEffectManager.TXVoiceChangerType.TXLiveVoiceChangerType_10;
        break;
      case 11:
        changerType = TXAudioEffectManager.TXVoiceChangerType.TXLiveVoiceChangerType_11;
        break;
      default:
        changerType = TXAudioEffectManager.TXVoiceChangerType.TXLiveVoiceChangerType_0;
        break;
    }
    txAudioEffectManager.setVoiceChangerType(changerType);
    promise.resolve(null);
  }

  @ReactMethod
  private void setVoiceCaptureVolume(ReadableMap params, Promise promise) {
    int volume = params.getInt("volume");
    txAudioEffectManager.setVoiceCaptureVolume(volume);
    promise.resolve(null);
  }

  @ReactMethod
  private void setMusicObserver(ReadableMap params, Promise promise) {
    int id = params.getInt("id");
    txAudioEffectManager.setMusicObserver(id, new TXAudioEffectManager.TXMusicPlayObserver() {
      @Override
      public void onStart(int i, int i1) {
        trtcListener.onMusicObserverStart(i, i1);
      }

      @Override
      public void onPlayProgress(int i, long l, long l1) {
        trtcListener.onMusicObserverPlayProgress(i, l,l1);
      }

      @Override
      public void onComplete(int i, int i1) {
        trtcListener.onMusicObserverComplete(i, i1);
      }
    });
    promise.resolve(null);
  }

  @ReactMethod
  private void startPlayMusic(ReadableMap params, Promise promise) {
    String musicParam = params.getString(  "musicParam");
    TXAudioEffectManager.AudioMusicParam audioMusicParam =
      new Gson().fromJson(musicParam, TXAudioEffectManager.AudioMusicParam.class);
    boolean isSuccess = txAudioEffectManager.startPlayMusic(audioMusicParam);
    promise.resolve(isSuccess);
    txAudioEffectManager.setMusicObserver(audioMusicParam.id, new TXAudioEffectManager.TXMusicPlayObserver() {
      @Override
      public void onStart(int i, int i1) {
        trtcListener.onMusicObserverStart(i, i1);
      }

      @Override
      public void onPlayProgress(int i, long l, long l1) {
        trtcListener.onMusicObserverPlayProgress(i, l,l1);
      }

      @Override
      public void onComplete(int i, int i1) {
        trtcListener.onMusicObserverComplete(i, i1);
      }
    });
  }

  @ReactMethod
  private void stopPlayMusic(ReadableMap params, Promise promise) {
    int id = params.getInt("id");
    txAudioEffectManager.stopPlayMusic(id);
    promise.resolve(null);
  }

  @ReactMethod
  private void pausePlayMusic(ReadableMap params, Promise promise) {
    int id = params.getInt("id");
    txAudioEffectManager.pausePlayMusic(id);
    promise.resolve(null);
  }

  @ReactMethod
  private void resumePlayMusic(ReadableMap params, Promise promise) {
    int id = params.getInt("id");
    txAudioEffectManager.resumePlayMusic(id);
    promise.resolve(null);
  }

  @ReactMethod
  private void setMusicPublishVolume(ReadableMap params, Promise promise) {
    int id = params.getInt("id");
    int volume = params.getInt("volume");
    txAudioEffectManager.setMusicPublishVolume(id, volume);
    promise.resolve(null);
  }

  @ReactMethod
  private void setMusicPlayoutVolume(ReadableMap params, Promise promise) {
    int id = params.getInt("id");
    int volume = params.getInt("volume");
    txAudioEffectManager.setMusicPlayoutVolume(id, volume);
    promise.resolve(null);
  }

  @ReactMethod
  private void setAllMusicVolume(ReadableMap params, Promise promise) {
    int volume = params.getInt("volume");
    txAudioEffectManager.setAllMusicVolume(volume);
    promise.resolve(null);
  }

  @ReactMethod
  private void setMusicPitch(ReadableMap params, Promise promise) {
    int id = params.getInt("id");
    String pitchParam = params.getString("pitch");
    float pitch = Float.parseFloat(pitchParam);
    txAudioEffectManager.setMusicPitch(id, pitch);
    promise.resolve(null);
  }

  @ReactMethod
  private void setMusicSpeedRate(ReadableMap params, Promise promise) {
    int id = params.getInt("id");
    String speedRateParam = params.getString("speedRate");
    float speedRate = Float.parseFloat(speedRateParam);
    txAudioEffectManager.setMusicSpeedRate(id, speedRate);
    promise.resolve(null);
  }

  @ReactMethod
  private void getMusicCurrentPosInMS(ReadableMap params, Promise promise) {
    int id = params.getInt("id");
    long time = txAudioEffectManager.getMusicCurrentPosInMS(id);
    promise.resolve(String.valueOf(time));
  }

  @ReactMethod
  private void seekMusicToPosInMS(ReadableMap params, Promise promise) {
    int id = params.getInt("id");
    int pts = params.getInt("pts");
    txAudioEffectManager.seekMusicToPosInMS(id, pts);
    promise.resolve(null);
  }

  @ReactMethod
  private void getMusicDurationInMS(ReadableMap params, Promise promise) {
    String path = params.getString("path");
    long time = txAudioEffectManager.getMusicDurationInMS(path);
    promise.resolve(String.valueOf(time));
  }

  @ReactMethod
  private void setBeautyStyle(ReadableMap params, Promise promise) {
    int beautyStyle = params.getInt("beautyStyle");
    txBeautyManager.setBeautyStyle(beautyStyle);
    promise.resolve(null);
  }
  
  @ReactMethod
  private void setFilter(ReadableMap params, Promise promise) {
    final String imageUrl = params.getString("imageUrl");
      new Thread() {
        @Override
        public void run() {
          try {
            URL url = new URL(imageUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            Bitmap myBitmap = BitmapFactory.decodeStream(input);
            txBeautyManager.setFilter(myBitmap);
          } catch (IOException e) {
            // TXLog.e(TAG,"|method=setFilter|error=" + e);
          }
        }
      }.start();
    promise.resolve(null);
  }

  @ReactMethod
  private void setFilterStrength(ReadableMap params, Promise promise) {
    String strength = params.getString("strength");
    float strengthFloat = Float.parseFloat(strength);
    txBeautyManager.setFilterStrength(strengthFloat);
    promise.resolve(null);
  }

  @ReactMethod
  private void setBeautyLevel(ReadableMap params, Promise promise) {
    int beautyLevel = params.getInt("beautyLevel");
    txBeautyManager.setBeautyLevel(beautyLevel);
    promise.resolve(null);
  }

  @ReactMethod
  private void setWhitenessLevel(ReadableMap params, Promise promise) {
    int whitenessLevel = params.getInt("whitenessLevel");
    txBeautyManager.setWhitenessLevel(whitenessLevel);
    promise.resolve(null);
  }

  @ReactMethod
  private void enableSharpnessEnhancement(ReadableMap params, Promise promise) {
    boolean enable = params.getBoolean("enable");
    txBeautyManager.enableSharpnessEnhancement(enable);
    promise.resolve(null);
  }

  @ReactMethod
  private void setRuddyLevel(ReadableMap params, Promise promise) {
    int ruddyLevel = params.getInt("ruddyLevel");
    txBeautyManager.setRuddyLevel(ruddyLevel);
    promise.resolve(null);
  }

  @ReactMethod
  public void isFrontCamera(Promise promise) {
    promise.resolve(txDeviceManager.isFrontCamera());
  }

  @ReactMethod
  public void switchCamera(ReadableMap params, Promise promise) {
    boolean isFrontCamera = params.getBoolean("isFrontCamera");
    promise.resolve(txDeviceManager.switchCamera(isFrontCamera));
  }

  @ReactMethod
  public void getCameraZoomMaxRatio(Promise promise) {
    promise.resolve(txDeviceManager.getCameraZoomMaxRatio());
  }

  @ReactMethod
  private void setCameraZoomRatio(ReadableMap params, Promise promise) {
    String value = params.getString("value");
    float ratioValue = Float.parseFloat(value);
    promise.resolve(txDeviceManager.setCameraZoomRatio(ratioValue));
  }

  @ReactMethod
  private void enableCameraAutoFocus(ReadableMap params, Promise promise) {
    boolean enable = params.getBoolean("enable");
    promise.resolve(txDeviceManager.enableCameraAutoFocus(enable));
  }

  @ReactMethod
  private void isAutoFocusEnabled(Promise promise) {
    promise.resolve(txDeviceManager.isAutoFocusEnabled());
  }

  @ReactMethod
  private void enableCameraTorch(ReadableMap params, Promise promise) {
    boolean enable = params.getBoolean("enable");
    promise.resolve(txDeviceManager.enableCameraTorch(enable));
  }

  @ReactMethod
  private void setCameraFocusPosition(ReadableMap params, Promise promise) {
    int x = params.getInt("x");
    int y = params.getInt("y");
    txDeviceManager.setCameraFocusPosition(x, y);
    promise.resolve(null);
  }

  @ReactMethod
  public void addListener(String eventName) {

  }

  @ReactMethod
  public void removeListeners(Integer count) {

  }
}
