package com.daya.live_teaching.rtc;

import android.content.Context;
import android.os.Handler;
import android.text.TextUtils;

import com.cooleshow.base.utils.LogUtils;
import com.daya.live_teaching.common.ErrorCode;
import com.daya.live_teaching.common.ResultCallback;
import com.daya.live_teaching.utils.log.SLog;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.rongcloud.rtc.api.RCRTCConfig;
import cn.rongcloud.rtc.api.RCRTCEngine;
import cn.rongcloud.rtc.api.RCRTCLocalUser;
import cn.rongcloud.rtc.api.RCRTCRemoteUser;
import cn.rongcloud.rtc.api.RCRTCRoom;
import cn.rongcloud.rtc.api.callback.IRCRTCResultCallback;
import cn.rongcloud.rtc.api.callback.IRCRTCResultDataCallback;
import cn.rongcloud.rtc.api.callback.IRCRTCRoomEventsListener;
import cn.rongcloud.rtc.api.callback.IRCRTCStatusReportListener;
import cn.rongcloud.rtc.api.stream.RCRTCAudioStreamConfig;
import cn.rongcloud.rtc.api.stream.RCRTCInputStream;
import cn.rongcloud.rtc.api.stream.RCRTCOutputStream;
import cn.rongcloud.rtc.api.stream.RCRTCVideoInputStream;
import cn.rongcloud.rtc.api.stream.RCRTCVideoStreamConfig;
import cn.rongcloud.rtc.api.stream.RCRTCVideoView;
import cn.rongcloud.rtc.base.RCRTCMediaType;
import cn.rongcloud.rtc.base.RCRTCParamsType;
import cn.rongcloud.rtc.base.RCRTCStreamType;
import cn.rongcloud.rtc.base.RTCErrorCode;
import io.rong.imlib.model.Message;

/**
 * Rong RTC 语音业务封装
 */
public class RtcManager {
    private static RtcManager instance;
    private RCRTCRoom rongRTCRoom;
    private RtcCallback rtcCallback;

    //是否需要注册状态回调，目前仅调试打开
    private boolean needRegisteredStatusReportListener = true;

    private RtcManager() {
    }

    public static RtcManager getInstance() {
        if (instance == null) {
            synchronized (RtcManager.class) {
                if (instance == null) {
                    instance = new RtcManager();
                }
            }
        }

        return instance;
    }

    public void setRtcCallback(RtcCallback callBack) {
        this.rtcCallback = callBack;
        if (rtcCallback != null && getRTCRoom() != null) {
            SLog.d(SLog.TAG_RTC, "setRtcCallback");
            rtcCallback.onInitialRemoteUserList(getRemoteUsersInfo());
        }
    }


    /**
     * 加入聊天房间
     *
     * @param roomId
     */
    public void joinRtcRoom(final String roomId, final ResultCallback<String> callback) {
        RCRTCEngine.getInstance().joinRoom(roomId, new IRCRTCResultDataCallback<RCRTCRoom>() {
            @Override
            public void onSuccess(RCRTCRoom rcrtcRoom) {
                rongRTCRoom = rcrtcRoom;
                setRoomEventListener();
                if (callback != null) {
                    callback.onSuccess(roomId);
                }
            }

            @Override
            public void onFailed(RTCErrorCode rtcErrorCode) {
                SLog.e(SLog.TAG_RTC, "joinRtcRoom failed - " + rtcErrorCode.getValue());
                rongRTCRoom = RCRTCEngine.getInstance().getRoom();
                if (null != rongRTCRoom && (RTCErrorCode.RongRTCCodeJoinRepeatedRoom.getValue() == rtcErrorCode.getValue() ||
                        RTCErrorCode.ILLEGALSTATE.getValue() == rtcErrorCode.getValue())) {
                    String id = rongRTCRoom.getRoomId();
                    if (!TextUtils.isEmpty(id) && id.equals(roomId)) {
                        setRoomEventListener();
                        if (callback != null) {
                            callback.onSuccess(roomId);
                        }
                    } else {
                        quitRtcRoom(id, null);
                        if (callback != null) {
                            callback.onFail(rtcErrorCode.getValue(), null);
                        }

                        if (rtcCallback != null) {
                            rtcCallback.onFail(rtcErrorCode);
                        }
                    }

                } else {
                    if (RTCErrorCode.RongRTCCodeJoinRepeatedRoom.getValue() == rtcErrorCode.getValue() ||
                            RTCErrorCode.ILLEGALSTATE.getValue() == rtcErrorCode.getValue()) {
                        quitRtcRoom(roomId, null);
                    }//新增当出现50002的时候如果本地room对象为null，强制退出房间一次
                    if (callback != null) {
                        callback.onFail(rtcErrorCode.getValue(), null);
                    }

                    if (rtcCallback != null) {
                        rtcCallback.onFail(rtcErrorCode);
                    }
                }

            }
        });

    }

    /**
     * 离开聊天室
     *
     * @param roomId
     */
    public void quitRtcRoom(final String roomId, final ResultCallback<String> callback) {
        removeRoomEventListener();
        RCRTCEngine.getInstance().leaveRoom(new IRCRTCResultCallback() {
            @Override
            public void onSuccess() {
                SLog.d(SLog.TAG_RTC, "Quit room");
                if (callback != null) {
                    callback.onSuccess(roomId);
                }
            }

            @Override
            public void onFailed(final RTCErrorCode rtcErrorCode) {
                SLog.e(SLog.TAG_RTC, "quitRtcRoom error - " + rtcErrorCode.getReason());

                if (callback != null) {
                    callback.onFail(ErrorCode.RTC_ERROR.getCode(), null);
                }
                if (rtcCallback != null) {
                    rtcCallback.onFail(rtcErrorCode);
                }

            }
        });

    }


    public void startRtcChat(RCRTCVideoView view, final ResultCallback<Boolean> callback) {
        if (getRTCRoom() == null) {
            SLog.e(SLog.TAG_RTC, "getRTCRoom() ==  " + getRTCRoom());
            if (callback != null) {
                callback.onFail(ErrorCode.RTC_ERROR.getCode(), null);
            }
            return;
        }

        RCRTCLocalUser localUser = getRTCRoom().getLocalUser();
        if (localUser == null) {
            SLog.e(SLog.TAG_RTC, "startRtcChat failed localUser is null ");
            if (callback != null) {
                callback.onFail(ErrorCode.RTC_ERROR.getCode(), null);
            }
            return;
        }

        //设置本地预览视图
        RCRTCEngine.getInstance().getDefaultVideoStream().setVideoView(view);
        //开始采集数据
        RCRTCEngine.getInstance().getDefaultVideoStream().startCamera(null);
        List<RCRTCOutputStream> localAvStreams = new ArrayList<>();
        localAvStreams.add(RCRTCEngine.getInstance().getDefaultAudioStream());
        localAvStreams.add(RCRTCEngine.getInstance().getDefaultVideoStream());
        localUser.publishStreams(localAvStreams, new IRCRTCResultCallback() {
            @Override
            public void onSuccess() {
                LogUtils.e("Local publish avStream success");
                if (callback != null) {
                    callback.onSuccess(true);
                }
            }

            @Override
            public void onFailed(RTCErrorCode rtcErrorCode) {
                LogUtils.e("startVoiceChat error - " + rtcErrorCode.getValue() + rtcErrorCode.getReason());

                if (callback != null) {
                    callback.onFail(ErrorCode.RTC_ERROR.getCode(), null);
                }

                if (rtcCallback != null) {
                    rtcCallback.onFail(rtcErrorCode);
                }
            }
        });
    }

    /**
     * 停止聊天
     */
    public void stopRTCChat(final ResultCallback<Boolean> callback) {
        if (getRTCRoom() == null) {
            return;
        }
        //设置本地预览视图
        RCRTCEngine.getInstance().getDefaultVideoStream().setVideoView(null);
        //开始采集数据
        RCRTCEngine.getInstance().getDefaultVideoStream().stopCamera();
        RCRTCLocalUser localUser = getRTCRoom().getLocalUser();
        if (localUser == null) {
            SLog.e(SLog.TAG_RTC, "stopRTCChat failed localUser is null ");
            return;
        }

        localUser.unpublishStreams(localUser.getStreams(), new IRCRTCResultCallback() {
            @Override
            public void onSuccess() {
                if (callback != null) {
                    callback.onSuccess(true);
                }
            }

            @Override
            public void onFailed(RTCErrorCode rtcErrorCode) {
                SLog.e(SLog.TAG_RTC, "stopVoiceChat error - " + rtcErrorCode.getReason());
                if (callback != null) {
                    callback.onFail(ErrorCode.RTC_ERROR.getCode(), null);
                }

                if (rtcCallback != null) {
                    rtcCallback.onFail(rtcErrorCode);
                }
            }
        });

    }


    /**
     * 是否使用语音聊天
     */
    public void setLocalMicEnable(boolean enable) {
        if (RCRTCEngine.getInstance().getDefaultAudioStream() != null) {
            RCRTCEngine.getInstance().getDefaultAudioStream().setMicrophoneDisable(!enable);
        }
    }

    /**
     * 是否使用视频聊天
     */
    public void setLocalVideoEnable(boolean enable) {
        if (RCRTCEngine.getInstance().getDefaultVideoStream() != null) {
            if (enable) {
                RCRTCEngine.getInstance().getDefaultVideoStream().startCamera(null);
            } else {
                RCRTCEngine.getInstance().getDefaultVideoStream().stopCamera();
            }
        }
    }

    public void switchCamera() {
        if (RCRTCEngine.getInstance().getDefaultVideoStream() != null) {
            RCRTCEngine.getInstance().getDefaultVideoStream().switchCamera(null);
        }
    }

    /**
     * 是否打开扬声器
     *
     * @param enabled
     */
    public void setEnableSpeakerphone(boolean enabled) {
        RCRTCEngine.getInstance().enableSpeaker(enabled);
    }


    /**
     * 房间静音设置
     */
    public void muteRoomVoice(boolean mute, final ResultCallback<Boolean> callback) {
        if (getRTCRoom() == null) {
            return;
        }
        List<RCRTCRemoteUser> remoteUserList = getRTCRoom().getRemoteUsers();
        List<RCRTCInputStream> receiveVoiceSteamList = new ArrayList<>();
        for (RCRTCRemoteUser remoteUser : remoteUserList) {
            List<RCRTCInputStream> remoteAVStreams = remoteUser.getStreams();
            for (RCRTCInputStream stream : remoteAVStreams) {
                if (stream.getMediaType() == RCRTCMediaType.AUDIO) {
                    receiveVoiceSteamList.addAll(remoteUser.getStreams());
                }
            }
        }

        if (receiveVoiceSteamList.size() > 0) {
            if (mute) {
                getRTCRoom().getLocalUser().unsubscribeStreams(receiveVoiceSteamList, new IRCRTCResultCallback() {
                    @Override
                    public void onSuccess() {
                        if (callback != null) {
                            callback.onSuccess(true);
                        }
                    }

                    @Override
                    public void onFailed(RTCErrorCode rtcErrorCode) {
                        SLog.e(SLog.TAG_RTC, "muteRoomVoice error - " + rtcErrorCode.getReason());
                        if (rtcCallback != null) {
                            rtcCallback.onFail(rtcErrorCode);
                        }
                    }
                });
            } else {
                getRTCRoom().getLocalUser().subscribeStreams(receiveVoiceSteamList, new IRCRTCResultCallback() {
                    @Override
                    public void onSuccess() {
                        if (callback != null) {
                            callback.onSuccess(false);
                        }
                    }

                    @Override
                    public void onFailed(RTCErrorCode rtcErrorCode) {
                        SLog.e(SLog.TAG_RTC, "muteRoomVoice error - " + rtcErrorCode.getReason());
                        if (rtcCallback != null) {
                            rtcCallback.onFail(rtcErrorCode);
                        }
                    }
                });
            }

        }
    }


    /**
     * 订阅所有当前在房间发布资源的用户
     */
    public void subscribeAll(HashMap<String, RCRTCVideoView> videoViews, final ResultCallback<Boolean> callback) {
        if (getRTCRoom() != null) {
            List<RCRTCRemoteUser> remoteUserList = getRTCRoom().getRemoteUsers();
            List<RCRTCInputStream> receiveSteamList = new ArrayList<>();
            for (RCRTCRemoteUser remoteUser : remoteUserList) {
                for (RCRTCInputStream inputStream : remoteUser.getStreams()) {
                    if (inputStream.getMediaType() == RCRTCMediaType.VIDEO) {
                        ((RCRTCVideoInputStream) inputStream).setStreamType(RCRTCStreamType.TINY);
                        ((RCRTCVideoInputStream) inputStream).setVideoView(videoViews.get(remoteUser.getUserId()));
                    }
                }
                receiveSteamList.addAll(remoteUser.getStreams());
            }
            if (receiveSteamList.size() > 0) {
                getRTCRoom().getLocalUser().subscribeStreams(receiveSteamList, new IRCRTCResultCallback() {
                    @Override
                    public void onSuccess() {
                        if (callback != null) {
                            callback.onSuccess(true);
                        }
                    }

                    @Override
                    public void onFailed(RTCErrorCode rtcErrorCode) {
                        if (callback != null) {
                            callback.onFail(ErrorCode.RTC_ERROR.getCode(), null);
                        }
                    }
                });
            }
        }

    }

    public void subscribe(boolean isPlayUserAudio, boolean isSimulcast, String userId, RCRTCVideoView videoView, final ResultCallback<String> callback) {
        RCRTCRemoteUser remoteUser = getRTCRoom().getRemoteUser(userId);
        subscribe(isPlayUserAudio, isSimulcast, remoteUser, videoView, null, callback);
    }

    public void subscribe(boolean isPlayUserAudio, boolean isSimulcast, String userId, RCRTCVideoView videoView, RCRTCVideoView screenShareView, final ResultCallback<String> callback) {
        RCRTCRemoteUser remoteUser = getRTCRoom().getRemoteUser(userId);
        subscribe(isPlayUserAudio, isSimulcast, remoteUser, videoView, screenShareView, callback);
    }

    // 订阅单人,
    private void subscribe(boolean isPlayUserAudio, boolean isSimulcast, final RCRTCRemoteUser remoteUser, RCRTCVideoView videoView, RCRTCVideoView screenShareView, final ResultCallback<String> callback) {
        if (getRTCRoom() == null || remoteUser == null || remoteUser.getStreams() == null) {
            return;
        }
        LogUtils.i(SLog.TAG_RTC, "subscribe 订阅单人");
        //某些手机会出现声音从听筒出来,咨询融云技术之后建议订阅之前再设置一遍麦克风模式
        RCRTCEngine.getInstance().enableSpeaker(true);
        for (RCRTCInputStream inputStream : remoteUser.getStreams()) {
            if (inputStream.getMediaType() == RCRTCMediaType.VIDEO) {
                SLog.d(SLog.TAG_RTC, "Set remote video view , user = " + remoteUser.getUserId());
                ((RCRTCVideoInputStream) inputStream).setStreamType(RCRTCStreamType.NORMAL);
                if (inputStream.getTag().equals("screenshare") && screenShareView != null) {
                    ((RCRTCVideoInputStream) inputStream).setVideoView(screenShareView);
                } else {
                    ((RCRTCVideoInputStream) inputStream).setVideoView(videoView);
                }
            }
        }

        getRTCRoom().getLocalUser().subscribeStreams(remoteUser.getStreams(), new IRCRTCResultCallback() {
            @Override
            public void onSuccess() {
                SLog.d(SLog.TAG_RTC, "subscribeAvStream success,user = " + remoteUser.getUserId());
                if (callback != null) {
                    callback.onSuccess(remoteUser.getUserId());
                }
                if (isSimulcast) {
                    switchStream(remoteUser.getUserId(), isSimulcast);
                }
                enableRTCAVInputStream(remoteUser.getUserId(), isPlayUserAudio);

            }

            @Override
            public void onFailed(RTCErrorCode rtcErrorCode) {
                SLog.e(SLog.TAG_RTC, "subscribeAvStream error - " + rtcErrorCode.getReason());

                if (callback != null) {
                    callback.onFail(ErrorCode.RTC_ERROR.getCode(), null);
                }

                if (rtcCallback != null) {
                    rtcCallback.onFail(rtcErrorCode);
                }
            }
        });

    }

    public void unSubscribe(final String userId, final ResultCallback<String> callback) {
        RCRTCRemoteUser remoteUser = getRTCRoom().getRemoteUser(userId);
        if (getRTCRoom() == null || remoteUser == null || remoteUser.getStreams() == null) {
            return;
        }
        getRTCRoom().getLocalUser().unsubscribeStreams(remoteUser.getStreams(), new IRCRTCResultCallback() {
            @Override
            public void onSuccess() {
                SLog.d(SLog.TAG_RTC, "unSubscribeAvStream success,user = " + userId);
                if (callback != null) {
                    callback.onSuccess(userId);
                }
            }

            @Override
            public void onFailed(RTCErrorCode rtcErrorCode) {
                SLog.e(SLog.TAG_RTC, "unSubscribeAvStream error - " + rtcErrorCode.getReason());

                if (callback != null) {
                    callback.onFail(ErrorCode.RTC_ERROR.getCode(), null);
                }

                if (rtcCallback != null) {
                    rtcCallback.onFail(rtcErrorCode);
                }
            }
        });

    }


    public void subscribeVideo(final String userId, RCRTCVideoView videoView, final ResultCallback<String> callback) {
        subscribeStream(userId, RCRTCMediaType.VIDEO, false, videoView, callback);
    }


    public void unSubscribeVideo(String userId, final ResultCallback<String> callback) {
        unSubscribeStream(userId, RCRTCMediaType.VIDEO, false, callback);
    }

    public void subscribeAudio(final String userId, final ResultCallback<String> callback) {
        subscribeStream(userId, RCRTCMediaType.AUDIO, false, null, callback);
    }


    public void unSubscribeAudio(String userId, final ResultCallback<String> callback) {
        unSubscribeStream(userId, RCRTCMediaType.AUDIO, false, callback);
    }

    public void subscribeScreen(String userId, RCRTCVideoView videoView, final ResultCallback<String> callback) {
        subscribeStream(userId, RCRTCMediaType.VIDEO, true, videoView, callback);

    }

    public void unSubscribeScreen(String userId, final ResultCallback<String> callback) {
        unSubscribeStream(userId, RCRTCMediaType.VIDEO, true, callback);
    }


    private void subscribeStream(final String userId, final RCRTCMediaType type, boolean isScreenShare, RCRTCVideoView videoView, final ResultCallback<String> callback) {
        if (getRTCRoom() == null) {
            SLog.e(SLog.TAG_RTC, type + " subscribeStream failed , room = " + getRTCRoom());
            if (callback != null) {
                callback.onFail(ErrorCode.RTC_ERROR.getCode(), null);
            }
            return;
        }
        final RCRTCRemoteUser remoteUser = getRTCRoom().getRemoteUser(userId);

        if (remoteUser == null || remoteUser.getStreams() == null) {
            SLog.e(SLog.TAG_RTC, type + "subscribeStream failed ,  room = " + getRTCRoom() + "userId = " + userId + "，remoteUser  = " + remoteUser);
            if (callback != null) {
                callback.onFail(ErrorCode.RTC_ERROR.getCode(), null);
            }
            return;
        }

        ArrayList<RCRTCInputStream> inputStreams = new ArrayList<>();
        for (RCRTCInputStream inputStream : remoteUser.getStreams()) {
            if (type == RCRTCMediaType.VIDEO && inputStream.getMediaType() == RCRTCMediaType.VIDEO) {
                if (isScreenShare && inputStream.getTag().equals("screenshare")) {
                    ((RCRTCVideoInputStream) inputStream).setVideoView(videoView);
                    SLog.d(SLog.TAG_RTC, "subscribeStream, Set remote video screen share view ,  user = " + remoteUser.getUserId() + ",videoView = " + videoView);
                    inputStreams.add(inputStream);

                } else if (!isScreenShare && !inputStream.getTag().equals("screenshare")) {
                    ((RCRTCVideoInputStream) inputStream).setVideoView(videoView);
                    ((RCRTCVideoInputStream) inputStream).setStreamType(RCRTCStreamType.TINY);
                    SLog.d(SLog.TAG_RTC, "subscribeStream, Set remote video view , user = " + remoteUser.getUserId() + ",videoView = " + videoView);
                    inputStreams.add(inputStream);
                }

            } else if (type == RCRTCMediaType.AUDIO && inputStream.getMediaType() == RCRTCMediaType.AUDIO) {
                inputStreams.add(inputStream);
            }

        }

        if (inputStreams.size() <= 0) {
            SLog.e(SLog.TAG_RTC, "subscribeStream, inputStreams size = " + inputStreams.size());
            if (callback != null) {
                callback.onFail(ErrorCode.RTC_ERROR.getCode(), null);
            }
            return;
        }

        SLog.d(SLog.TAG_RTC, "subscribeStream, inputStreams = " + inputStreams);
        getRTCRoom().getLocalUser().subscribeStreams(inputStreams, new IRCRTCResultCallback() {
            @Override
            public void onSuccess() {
                SLog.d(SLog.TAG_RTC, "subscribeStream " + type + " success,user = " + userId);
                if (callback != null) {
                    callback.onSuccess(userId);
                }
            }

            @Override
            public void onFailed(RTCErrorCode rtcErrorCode) {
                SLog.e(SLog.TAG_RTC, "subscribeStream " + type + " error - " + rtcErrorCode.getReason());

                if (callback != null) {
                    callback.onFail(ErrorCode.RTC_ERROR.getCode(), null);
                }

                if (rtcCallback != null) {
                    rtcCallback.onFail(rtcErrorCode);
                }
            }
        });

    }


    private void unSubscribeStream(final String userId, final RCRTCMediaType type, boolean isScreenShare, final ResultCallback<String> callback) {
        if (getRTCRoom() == null) {
            SLog.e(SLog.TAG_RTC, "unSubscribeStream failed , room = " + getRTCRoom());
            if (callback != null) {
                callback.onFail(ErrorCode.RTC_ERROR.getCode(), null);
            }
            return;
        }
        RCRTCRemoteUser remoteUser = getRTCRoom().getRemoteUser(userId);

        if (remoteUser == null || remoteUser.getStreams() == null) {
            SLog.e(SLog.TAG_RTC, "unSubscribeStream failed , remoteUser  = " + remoteUser);
            if (callback != null) {
                callback.onFail(ErrorCode.RTC_ERROR.getCode(), null);
            }
            return;
        }

        ArrayList<RCRTCInputStream> inputStreams = new ArrayList<>();
        for (RCRTCInputStream inputStream : remoteUser.getStreams()) {
            if (type == RCRTCMediaType.VIDEO && inputStream.getMediaType() == RCRTCMediaType.VIDEO) {
                if (isScreenShare && inputStream.getTag().equals("screenshare")) {
                    inputStreams.add(inputStream);
                } else if (!isScreenShare && !inputStream.getTag().equals("screenshare")) {
                    inputStreams.add(inputStream);
                }
            } else if (type == RCRTCMediaType.AUDIO && inputStream.getMediaType() == RCRTCMediaType.AUDIO) {
                inputStreams.add(inputStream);
            }
        }

        SLog.e(SLog.TAG_RTC, "unSubscribeStream , inputStreams  = " + inputStreams);
        getRTCRoom().getLocalUser().unsubscribeStreams(inputStreams, new IRCRTCResultCallback() {
            @Override
            public void onSuccess() {
                SLog.d(SLog.TAG_RTC, "unSubscribeStream  " + type + " success,user = " + userId);
                if (callback != null) {
                    callback.onSuccess(userId);
                }
            }

            @Override
            public void onFailed(RTCErrorCode rtcErrorCode) {
                SLog.e(SLog.TAG_RTC, "unSubscribeStream  " + type + " error - " + rtcErrorCode.getReason());

                if (callback != null) {
                    callback.onFail(ErrorCode.RTC_ERROR.getCode(), null);
                }

                if (rtcCallback != null) {
                    rtcCallback.onFail(rtcErrorCode);
                }
            }
        });

    }


    public RCRTCRoom getRTCRoom() {
        return rongRTCRoom;
    }


    // 注册房间监听
    private void setRoomEventListener() {
        if (getRTCRoom() != null) {
            SLog.d(SLog.TAG_RTC, "Set room event listener");
            getRTCRoom().registerRoomListener(rtcEventsListener);
        }
    }

    // 注销房间监听
    private void removeRoomEventListener() {
        if (getRTCRoom() != null) {
            SLog.d(SLog.TAG_RTC, "Remove room event listener");
            getRTCRoom().unregisterRoomListener();
        }
    }

    //注册房间统计信息监听
    public void registerStatusReportListener(IRCRTCStatusReportListener ircrtcStatusReportListener) {
        if (needRegisteredStatusReportListener) {
            RCRTCEngine.getInstance().registerStatusReportListener(ircrtcStatusReportListener);
        }
    }

    //取消注册房间统计信息监听
    public void unregisterStatusReportListener() {
        RCRTCEngine.getInstance().unregisterStatusReportListener();
    }


    private Map<String, List<RCRTCInputStream>> getRemoteUsersInfo() {
        Map<String, List<RCRTCInputStream>> userIdInfo = new HashMap<>();
        if (getRTCRoom() != null) {
            if (getRTCRoom().getRemoteUsers().size() > 0) {
                for (RCRTCRemoteUser user : getRTCRoom().getRemoteUsers()) {
                    SLog.d(SLog.TAG_RTC, "remoteuser=" + user);
                    if (user != null) {
                        userIdInfo.put(user.getUserId(), user.getStreams());
                    }
                }
            }
        }
        return userIdInfo;
    }


    // 房间事件监听
    private IRCRTCRoomEventsListener rtcEventsListener = new IRCRTCRoomEventsListener() {

        @Override
        public void onRemoteUserPublishResource(RCRTCRemoteUser RCRTCRemoteUser, List<RCRTCInputStream> list) {
            SLog.d(SLog.TAG_RTC, "Remote user publish resource，user = " + RCRTCRemoteUser.getUserId() + "," + rtcCallback);
            if (rtcCallback != null) {
                rtcCallback.onRemoteUserPublishResource(RCRTCRemoteUser.getUserId(), list);
            }
        }

        @Override
        public void onRemoteUserMuteAudio(RCRTCRemoteUser RCRTCRemoteUser, RCRTCInputStream RCRTCInputStream, boolean b) {
            SLog.d(SLog.TAG_RTC, "Remote User AudioStream Mute，user=" + RCRTCRemoteUser.getUserId() + ", mute = " + b + "," + rtcCallback);
            if (rtcCallback != null) {
                rtcCallback.onRemoteUserAudioStreamMute(RCRTCRemoteUser.getUserId(), b);
            }
        }

        @Override
        public void onRemoteUserMuteVideo(RCRTCRemoteUser RCRTCRemoteUser, RCRTCInputStream RCRTCInputStream, boolean b) {
            SLog.d(SLog.TAG_RTC, "Remote user video stream enable，user=" + RCRTCRemoteUser.getUserId() + ", Enabled = " + b + "," + rtcCallback);
            if (rtcCallback != null) {
                rtcCallback.onRemoteUserVideoStreamEnabled(RCRTCRemoteUser.getUserId(), b);
            }
        }


        @Override
        public void onRemoteUserUnpublishResource(RCRTCRemoteUser RCRTCRemoteUser, List<RCRTCInputStream> list) {
            SLog.d(SLog.TAG_RTC, "Remote user unpublish resource，user=" + RCRTCRemoteUser.getUserId() + "," + rtcCallback);
            if (rtcCallback != null) {
                rtcCallback.onRemoteUserUnPublishResource(RCRTCRemoteUser.getUserId(), list);
            }
        }

        @Override
        public void onUserJoined(RCRTCRemoteUser RCRTCRemoteUser) {
            SLog.d(SLog.TAG_RTC, "User join room ，user=" + RCRTCRemoteUser.getUserId());
            if (rtcCallback != null) {
                rtcCallback.onUserJoined(RCRTCRemoteUser.getUserId());
            }
        }

        @Override
        public void onUserLeft(RCRTCRemoteUser RCRTCRemoteUser) {
            SLog.d(SLog.TAG_RTC, "User left room ，user=" + RCRTCRemoteUser.getUserId());
            if (rtcCallback != null) {
                rtcCallback.onUserLeft(RCRTCRemoteUser.getUserId());
            }
        }

        @Override
        public void onUserOffline(RCRTCRemoteUser RCRTCRemoteUser) {
            SLog.d(SLog.TAG_RTC, "User offline ，user=" + RCRTCRemoteUser.getUserId());
            if (rtcCallback != null) {
                rtcCallback.onUserOffline(RCRTCRemoteUser.getUserId());
            }
        }

        @Override
        public void onPublishLiveStreams(List<RCRTCInputStream> list) {

        }

        @Override
        public void onUnpublishLiveStreams(List<RCRTCInputStream> list) {

        }

        @Override
        public void onVideoTrackAdd(String s, String s1) {
            SLog.d(SLog.TAG_RTC, "Video Track Add  ，s = " + s + ", s1 = " + s1);
        }

        @Override
        public void onFirstRemoteVideoFrame(String userId, String tag) {
            SLog.d(SLog.TAG_RTC, "First frame draw  ，userId = " + userId + ", tag = " + tag);
            if (rtcCallback != null) {
                rtcCallback.onFirstFrameDraw(userId, tag);
            }
        }

        @Override
        public void onLeaveRoom(int i) {
            SLog.d(SLog.TAG_RTC, "Leave room");
        }

        @Override
        public void onReceiveMessage(Message message) {

        }

        @Override
        public void onKickedByServer() {

        }
    };

    public void setVideoResolution(VideoResolution resolution) {

        //        RongRTCConfig.Builder configBuilder = new RongRTCConfig.Builder();
        //        configBuilder.buildMusicMode();
        //        configBuilder.enableTinyStream(true);
        //        configBuilder.setNoiseSuppressionLevel(RongRTCConfig.NSLevel.NS_VERYHIGH);
        //        configBuilder.enableHardWareEncodeHighProfile(false);//修改鬼畜问题
        //        RCRTCCapture.getInstance().setRTCConfig(configBuilder.build());
    }

    public int nsLevel = 3;

    /**
     * 获取降噪等级
     *
     * @return
     */
    public int getNsLevel() {
        return nsLevel;
    }

    /**
     * 同声传译
     * @param nsLevel
     * @param context
     * @return
     */
    public boolean setVideoResolution(int nsLevel, Context context) {
        try {
            this.nsLevel = nsLevel;
            RCRTCConfig onfigBuilder = RCRTCConfig.Builder.create().enableHardwareEncoderHighProfile(false).build();
            RCRTCEngine.getInstance().init(context, onfigBuilder);
            RCRTCEngine.getInstance().getDefaultVideoStream().setVideoConfig(RCRTCVideoStreamConfig.Builder.create()
                    .setMinRate(500)
                    .setMaxRate(1000)
                    .build());

            RCRTCEngine.getInstance().getDefaultAudioStream().setAudioConfig(RCRTCAudioStreamConfig.Builder.create().setNoiseSuppressionLevel(RCRTCParamsType.NSLevel.NS_VERYHIGH).build());


            RCRTCEngine.getInstance().getDefaultVideoStream().enableTinyStream(true);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return true;
        }

    }

    public void switchStream(String lecturerId, boolean b) {
        if (!TextUtils.isEmpty(lecturerId)) {
            try {
                RCRTCRoom room = getRTCRoom();
                if (null == room) {
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            switchStream(lecturerId, b);
                        }
                    }, 2000);
                    return;
                }
                RCRTCRemoteUser remoteUser = room.getRemoteUser(lecturerId);
                if (null == remoteUser) {
                    return;
                }
                if (b) {
                    remoteUser.switchToNormalStream(new IRCRTCResultCallback() {
                        @Override
                        public void onSuccess() {
                        }

                        @Override
                        public void onFailed(RTCErrorCode rtcErrorCode) {
                        }
                    });
                } else {
                    remoteUser.switchToTinyStream(new IRCRTCResultCallback() {
                        @Override
                        public void onSuccess() {
                        }

                        @Override
                        public void onFailed(RTCErrorCode rtcErrorCode) {
                        }
                    });
                }

            } catch (Exception e) {

            }

        }

    }

    /**
     * 是否播放音频流
     *
     * @param userId
     * @param isEnable
     */
    public void enableRTCAVInputStream(String userId, boolean isEnable) {
        try {
            RCRTCRemoteUser remoteUser = rongRTCRoom.getRemoteUser(userId);
            if (null == remoteUser) {
                return;
            }
            for (RCRTCInputStream inputStream : remoteUser.getStreams()) {
                if (inputStream.getMediaType() == RCRTCMediaType.AUDIO) {
                    inputStream.mute(!isEnable);
                    LogUtils.e(isEnable + "----------------------------------------------" + userId);
                    break;
                }
            }
        } catch (Exception e) {

        }

    }

    /**
     * 订阅大流
     */
    public void exchangeStreamToNormalStream(String userid) {
        RCRTCRemoteUser remoteUser = getRTCRoom().getRemoteUser(userid);
        if (remoteUser != null) {
            remoteUser.switchToNormalStream(new IRCRTCResultCallback() {
                @Override
                public void onSuccess() {
                    SLog.d(SLog.TAG_RTC, "exchangeStreamToNormalStream->onUiSuccess.");
                }

                @Override
                public void onFailed(RTCErrorCode rtcErrorCode) {
                    SLog.e(SLog.TAG_RTC, "exchangeStreamToNormalStream->onUiFailed rtcErrorCode :" + rtcErrorCode.getValue());
                }
            });
        } else {
            SLog.e(SLog.TAG_RTC, "exchangeStreamToNormalStream:remoteUser is empty.");
        }
    }

    /**
     * 订阅小流
     */
    public void exchangeStreamToTinyStream(String userid) {
        RCRTCRemoteUser remoteUser = getRTCRoom().getRemoteUser(userid);
        if (remoteUser != null) {
            remoteUser.switchToTinyStream(new IRCRTCResultCallback() {
                @Override
                public void onSuccess() {
                    SLog.d(SLog.TAG_RTC, "exchangeStreamToTinyStream->onUiSuccess.");
                }

                @Override
                public void onFailed(RTCErrorCode rtcErrorCode) {
                    SLog.e(SLog.TAG_RTC, "exchangeStreamToTinyStream->onUiFailed rtcErrorCode :" + rtcErrorCode.getValue());
                }
            });
        } else {
            SLog.e(SLog.TAG_RTC, "exchangeStreamToTinyStream:remoteUser is empty.");
        }
    }

    public interface RtcCallback {

        void onInitialRemoteUserList(Map<String, List<RCRTCInputStream>> userInfos);

        void onRemoteUserPublishResource(String userIds, List<RCRTCInputStream> list);

        void onRemoteUserUnPublishResource(String userId, List<RCRTCInputStream> list);

        void onRemoteUserAudioStreamMute(String userId, boolean mute);

        void onRemoteUserVideoStreamEnabled(String userId, boolean enable);

        void onFail(RTCErrorCode rtcErrorCode);

        void onUserJoined(String userId);

        void onUserLeft(String userId);

        void onUserOffline(String userId);

        void onFirstFrameDraw(String userId, String tag);
    }
}
