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

package com.volcengine.reactnative.vertc.events;

import android.util.Log;

import com.ss.bytertc.engine.RTCStream;
import com.ss.bytertc.engine.SubscribeConfig;
import com.ss.bytertc.engine.UserInfo;
import com.ss.bytertc.engine.data.AVSyncState;
import com.ss.bytertc.engine.data.ForwardStreamEventInfo;
import com.ss.bytertc.engine.data.ForwardStreamStateInfo;
import com.ss.bytertc.engine.data.PublishState;
import com.ss.bytertc.engine.data.PublishStateChangeReason;
import com.ss.bytertc.engine.data.SubscribeState;
import com.ss.bytertc.engine.data.SubscribeStateChangeReason;
import com.ss.bytertc.engine.handler.IRTCRoomEventHandler;
import com.ss.bytertc.engine.type.LocalStreamStats;
import com.ss.bytertc.engine.type.MediaStreamType;
import com.ss.bytertc.engine.type.NetworkQualityStats;
import com.ss.bytertc.engine.type.RTCRoomStats;
import com.ss.bytertc.engine.type.RemoteStreamStats;
import com.ss.bytertc.engine.type.SetRoomExtraInfoResult;
import com.ss.bytertc.engine.type.StreamRemoveReason;
import com.ss.bytertc.engine.type.SubtitleErrorCode;
import com.ss.bytertc.engine.type.SubtitleMessage;
import com.ss.bytertc.engine.type.SubtitleMode;
import com.ss.bytertc.engine.type.SubtitleState;
import com.ss.bytertc.engine.type.UserVisibilityChangeError;
import com.volcengine.VolcApiEngine.BeanFactory;

import java.lang.reflect.Array;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class IRTCRoomEventHandlerImpl extends IRTCRoomEventHandler implements BeanFactory.EventReceiver  {
   public BeanFactory.EventEmitter ee;

  public IRTCRoomEventHandlerImpl(BeanFactory.EventEmitter ee) {
    this.ee = ee;
  }

  @Override
  public void onLeaveRoom(RTCRoomStats stats) {
    this.ee.sendEvent("onLeaveRoom", stats);
  }

  @Override
  public void onRoomStateChanged(String roomId, String uid, int state, String extraInfo) {
    this.ee.sendEvent("onRoomStateChanged", roomId, uid, state, extraInfo);
  }

  @Override
  public void onStreamStateChanged(String roomId, String uid, int state, String extraInfo) {
    this.ee.sendEvent("onStreamStateChanged", roomId, uid, state, extraInfo);
  }

  @Override
  public void onRoomWarning(int warn) {
    this.ee.sendEvent("onRoomWarning", warn);
  }

  @Override
  public void onRoomError(int err) {
    this.ee.sendEvent("onRoomError", err);
  }

  @Override
  public void onAVSyncStateChange(AVSyncState state) {
    this.ee.sendEvent("onAVSyncStateChange", state);
  }

  @Override
  public void onRoomStats(RTCRoomStats stats) {
    this.ee.sendEvent("onRoomStats", stats);
  }

  @Override
  public void onUserJoined(UserInfo userInfo, int elapsed) {
    this.ee.sendEvent("onUserJoined", userInfo, elapsed);
  }

  @Override
  public void onUserLeave(String uid, int reason) {
    this.ee.sendEvent("onUserLeave", uid, reason);
  }

  @Override
  public void onTokenWillExpire() {
    this.ee.sendEvent("onTokenWillExpire");
  }

  @Override
  public void onPublishPrivilegeTokenWillExpire() {
    this.ee.sendEvent("onPublishPrivilegeTokenWillExpire");
  }

  @Override
  public void onSubscribePrivilegeTokenWillExpire() {
    this.ee.sendEvent("onSubscribePrivilegeTokenWillExpire");
  }

  @Override
  public void onUserPublishStreamVideo(String roomId, String uid, boolean isPublish) {
    this.ee.sendEvent("onUserPublishStreamVideo", roomId, uid, isPublish);
  }

  @Override
  public void onUserPublishStreamAudio(String roomId, String uid, boolean isPublish) {
    this.ee.sendEvent("onUserPublishStreamAudio", roomId, uid, isPublish);
  }

  @Override
  public void onUserPublishScreenVideo(String roomId, String uid, boolean isPublish) {
    this.ee.sendEvent("onUserPublishScreenVideo", roomId, uid, isPublish);
  }

  @Override
  public void onUserPublishScreenAudio(String roomId, String uid, boolean isPublish) {
    this.ee.sendEvent("onUserPublishScreenAudio", roomId, uid, isPublish);
  }

  @Override
  public void onVideoPublishStateChanged(String roomId, String uid, PublishState state, PublishStateChangeReason reason) {
    this.ee.sendEvent("onVideoPublishStateChanged", roomId, uid, state, reason);
  }

  @Override
  public void onAudioPublishStateChanged(String roomId, String uid, PublishState state, PublishStateChangeReason reason) {
    this.ee.sendEvent("onAudioPublishStateChanged", roomId, uid, state, reason);
  }

  @Override
  public void onScreenVideoPublishStateChanged(String roomId, String uid, PublishState state, PublishStateChangeReason reason) {
    this.ee.sendEvent("onScreenVideoPublishStateChanged", roomId, uid, state, reason);
  }

  @Override
  public void onScreenAudioPublishStateChanged(String roomId, String uid, PublishState state, PublishStateChangeReason reason) {
    this.ee.sendEvent("onScreenAudioPublishStateChanged", roomId, uid, state, reason);
  }


  @Override
  public void onVideoSubscribeStateChanged(String roomId, String uid, SubscribeState state, SubscribeStateChangeReason reason) {
    this.ee.sendEvent("onVideoSubscribeStateChanged", roomId, uid, state, reason);
  }

  @Override
  public void onAudioSubscribeStateChanged(String roomId, String uid, SubscribeState state, SubscribeStateChangeReason reason) {
    this.ee.sendEvent("onAudioSubscribeStateChanged", roomId, uid, state, reason);
  }

  @Override
  public void onScreenVideoSubscribeStateChanged(String roomId, String uid, SubscribeState state, SubscribeStateChangeReason reason) {
    this.ee.sendEvent("onScreenVideoSubscribeStateChanged", roomId, uid, state, reason);
  }

  @Override
  public void onScreenAudioSubscribeStateChanged(String roomId, String uid, SubscribeState state, SubscribeStateChangeReason reason) {
    this.ee.sendEvent("onScreenAudioSubscribeStateChanged", roomId, uid, state, reason);
  }

  @Override
  public void onLocalStreamStats(LocalStreamStats stats) {
    this.ee.sendEvent("onLocalStreamStats", stats);
  }

  @Override
  public void onRemoteStreamStats(RemoteStreamStats stats) {
    this.ee.sendEvent("onRemoteStreamStats", stats);
  }

  @Override
  public void onStreamRemove(RTCStream stream, StreamRemoveReason reason) {
    this.ee.sendEvent("onStreamRemove", stream, reason);
  }

  @Override
  public void onStreamAdd(RTCStream stream) {
    this.ee.sendEvent("onStreamAdd", stream);
  }

  @Override
  public void onStreamSubscribed(int stateCode, String userId, SubscribeConfig info) {
    this.ee.sendEvent("onStreamSubscribed", stateCode, userId, info);
  }

  @Override
  public void onStreamPublishSuccess(String uid, boolean isScreen) {
    this.ee.sendEvent("onStreamPublishSuccess", uid, isScreen);
  }

  @Override
  public void onRoomMessageReceived(String uid, String message) {
    this.ee.sendEvent("onRoomMessageReceived", uid, message);
  }

  @Override
  public void onRoomBinaryMessageReceived(String uid, ByteBuffer message) {
    this.ee.sendEvent("onRoomBinaryMessageReceived", uid, message);
  }

  @Override
  public void onUserMessageReceived(String uid, String message) {
    this.ee.sendEvent("onUserMessageReceived", uid, message);
  }

  @Override
  public void onUserBinaryMessageReceived(String uid, ByteBuffer message) {
    this.ee.sendEvent("onUserBinaryMessageReceived", uid, message);
  }

  @Override
  public void onUserMessageSendResult(long msgid, int error) {
    this.ee.sendEvent("onUserMessageSendResult", msgid, error);
  }

  @Override
  public void onRoomMessageSendResult(long msgid, int error) {
    this.ee.sendEvent("onRoomMessageSendResult", msgid, error);
  }

  @Override
  public void onVideoStreamBanned(String uid, boolean banned) {
    this.ee.sendEvent("onVideoStreamBanned", uid, banned);
  }

  @Override
  public void onAudioStreamBanned(String uid, boolean banned) {
    this.ee.sendEvent("onAudioStreamBanned", uid, banned);
  }

  @Override
  public void onForwardStreamStateChanged(ForwardStreamStateInfo[] stateInfos) {
    ArrayList<Object> res = new ArrayList<>();
    for (ForwardStreamStateInfo info : stateInfos) {
      Map<String, Object> data = new HashMap<>();
      data.put("roomId", info.roomId);
      data.put("state", info.state);
      data.put("error", info.error);
      res.add(data);
    }
    this.ee.sendEvent("onForwardStreamStateChanged", res);
  }

  @Override
  public void onForwardStreamEvent(ForwardStreamEventInfo[] eventInfos) {
    ArrayList<Object> res = new ArrayList<>();
    for (ForwardStreamEventInfo info : eventInfos) {
      Map<String, Object> data = new HashMap<>();
      data.put("roomId", info.roomId);
      data.put("event", info.event);
      res.add(data);
    }
    this.ee.sendEvent("onForwardStreamEvent", res);
  }

  @Override
  public void onNetworkQuality(NetworkQualityStats localQuality, NetworkQualityStats[] remoteQualities) {
    this.ee.sendEvent("onNetworkQuality", localQuality, remoteQualities);
  }

  @Override
  public void onSetRoomExtraInfoResult(long taskId, SetRoomExtraInfoResult error) {
    this.ee.sendEvent("onSetRoomExtraInfoResult", taskId, error);
  }

  @Override
  public void onRoomExtraInfoUpdate(String key, String value, String lastUpdateUserId, long lastUpdateTimeMs) {
    this.ee.sendEvent("onRoomExtraInfoUpdate", key, value, lastUpdateUserId, lastUpdateTimeMs);
  }

  @Override
  public void onUserVisibilityChanged(boolean currentUserVisibility, UserVisibilityChangeError errorCode) {
    this.ee.sendEvent("onUserVisibilityChanged", currentUserVisibility, errorCode);
  }

  @Override
  public void onSubtitleStateChanged(SubtitleState state, SubtitleErrorCode errorCode, String errorMessage) {
    this.ee.sendEvent("onSubtitleStateChanged", state, errorCode, errorMessage);
  }

  @Override
  public void onSubtitleMessageReceived(SubtitleMessage[] subtitles) {
    ArrayList<Object> res = new ArrayList<>();
    for (SubtitleMessage subtitle : subtitles) {
      Map<String, Object> data = new HashMap<>();
      data.put("userId", subtitle.userId);
      data.put("mode", subtitle.mode);
      data.put("text", subtitle.text);
      data.put("language", subtitle.language);
      data.put("sequence", subtitle.sequence);
      data.put("definite", subtitle.definite);
      res.add(data);
    }
    this.ee.sendEvent("onSubtitleMessageReceived", res);
  }
}
