// Copyright © 2022 BytePlusRTC All rights reserved.
// SPDX-License-Identifier: MIT

package com.volcengine.reactnative.vertc;

import android.util.Log;

import androidx.annotation.Nullable;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.ss.bytertc.engine.RTCVideo;
import com.ss.bytertc.engine.engineimpl.RTCVideoImpl;
import com.volcengine.VolcApiEngine.IEventReceiver;
import com.volcengine.VolcApiEngine.VolcApiEngine;

@ReactModule(name = VertcModuleSpec.NAME)
public class VertcModule extends VertcModuleSpec implements IEventReceiver {
  public static ReactApplicationContext reactApplicationContext = null;
  
  private VertcImpl impl;

  VertcModule(ReactApplicationContext context) {
    super(context);
    reactApplicationContext = context;
    ScreenCaptureHelper.registerReactApplicationContext(context);
    this.impl = new VertcImpl(context, this);
    VertcApiEngineManager.instance.init(this.impl);
  }
  
  @Override
  public String getName() {
    return VertcImpl.NAME + "Module";
  }

  @ReactMethod(isBlockingSynchronousMethod = true)
  public boolean newApiEngine() {
    boolean res = this.impl.newApiEngine();
    NativeVariableManager.init(this.impl.apiEngine.msgClient, context);
    return res;
  }

  @ReactMethod(isBlockingSynchronousMethod = true)
  public String callApiSync(ReadableMap arg)  {
    try {
      String params = arg.getString("params");
      return this.impl.callApiSync(params);
    } catch (Exception e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }
  }

  @ReactMethod(isBlockingSynchronousMethod = false)
  public void callApi(ReadableMap arg, Callback callback)  {
    try {
      String params = arg.getString("params");
      this.impl.callApi(params, args -> {
        callback.invoke(args);
      });
    } catch (Exception e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }
  }

  @ReactMethod(isBlockingSynchronousMethod = true)
  public void testSome(ReadableMap arg)  {
    RTCVideo v = new RTCVideoImpl(null, "AppId", null, null, null);
//    v.feedback()
  }

  private int listenerCount = 0;

  @ReactMethod
  public void addListener(String eventName) {
    if (listenerCount == 0) {
      // Set up any upstream listeners or background tasks as necessary
    }

    listenerCount += 1;
  }

  @ReactMethod
  public void removeListeners(Integer count) {
    listenerCount -= count;
    if (listenerCount == 0) {
      // Remove upstream listeners, stop unnecessary background tasks
    }
  }

  private void sendEvent(ReactContext reactContext,
                          String eventName,
                          @Nullable WritableMap params) {
    reactContext
      .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
      .emit(eventName, params);
  }

  @Override
  public void OnEvent(String event, String data) {
    final WritableMap map = Arguments.createMap();
    map.putString("event", event);
    map.putString("data", data);

    super.context
      .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
      .emit(VertcModuleSpec.EVENT, map);
  }
}
