package com.daya.live_teaching.viewmodel;

import android.app.Application;
import android.os.CountDownTimer;
import android.text.TextUtils;

import com.cooleshow.base.data.net.BaseResponse;
import com.cooleshow.base.utils.LogUtils;
import com.daya.live_teaching.api.WhiteBoardApi;
import com.daya.live_teaching.common.ResultCallback;
import com.daya.live_teaching.common.StateLiveData;
import com.daya.live_teaching.im.IMManager;
import com.daya.live_teaching.model.ApplyForSpeechRequest;
import com.daya.live_teaching.model.ChangedUser;
import com.daya.live_teaching.model.ClassMember;
import com.daya.live_teaching.model.ClassMemberChangedAction;
import com.daya.live_teaching.model.DeviceChange;
import com.daya.live_teaching.model.DeviceChangeToast;
import com.daya.live_teaching.model.DeviceControlInvite;
import com.daya.live_teaching.model.DeviceSoudValum;
import com.daya.live_teaching.model.DeviceType;
import com.daya.live_teaching.model.DownLoadSong;
import com.daya.live_teaching.model.DownLoadSongStatus;
import com.daya.live_teaching.model.FileUploadBean;
import com.daya.live_teaching.model.FirstFrameUserInfo;
import com.daya.live_teaching.model.InsertImageBean;
import com.daya.live_teaching.model.LoginResult;
import com.daya.live_teaching.model.MetronomeInfo;
import com.daya.live_teaching.model.PassedTime;
import com.daya.live_teaching.model.PlayMidi;
import com.daya.live_teaching.model.RequestState;
import com.daya.live_teaching.model.Role;
import com.daya.live_teaching.model.RoleChangedUser;
import com.daya.live_teaching.model.ScreenDisplay;
import com.daya.live_teaching.model.SpeechResult;
import com.daya.live_teaching.model.StreamResource;
import com.daya.live_teaching.model.TicketExpired;
import com.daya.live_teaching.model.UpgradeRoleInvite;
import com.daya.live_teaching.model.UserInfo;
import com.daya.live_teaching.model.VideoClassMemberData;
import com.daya.live_teaching.model.WhiteBoard;
import com.daya.live_teaching.model.WhiteBoardAction;
import com.daya.live_teaching.model.WhiteCreateBean;
import com.daya.live_teaching.repository.ClassRepository;
import com.daya.live_teaching.repository.OnClassEventListener;
import com.daya.live_teaching.repository.OnClassVideoEventListener;
import com.daya.live_teaching.rtc.RtcManager;
import com.daya.live_teaching.ui.LiveActivity;
import com.daya.live_teaching.utils.log.SLog;
import com.google.gson.Gson;
import com.herewhite.sdk.Room;
import com.herewhite.sdk.domain.Promise;
import com.herewhite.sdk.domain.SDKError;
import com.herewhite.sdk.domain.Scene;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import androidx.annotation.NonNull;
import androidx.arch.core.util.Function;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Transformations;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;

import cn.rongcloud.rtc.api.RCRTCAudioMixer;
import cn.rongcloud.rtc.api.callback.IRCRTCStatusReportListener;
import cn.rongcloud.rtc.api.stream.RCRTCVideoView;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;


/**
 * 课堂视图模型
 */
public class ClassViewModel extends ViewModel {
    private static final String TAG = "ClassViewModel";

    private ClassRepository classRepository;
    private LiveActivity liveActivity;

    private SimpleDateFormat passTimeDateFormat = new SimpleDateFormat("HH:mm:ss");

    private MutableLiveData<UserInfo> userInfo = new MutableLiveData<>();   // 当前用户自己的信息
    private MutableLiveData<DeviceType> onDisableDevice = new MutableLiveData<>();  // 当被关闭设备
    private MutableLiveData<String> roomId = new MutableLiveData<>();       // 课堂 id
    private MutableLiveData<Integer> soundVolume = new MutableLiveData<>();       // 音量
    private MutableLiveData<List<ClassMember>> memberList = new MutableLiveData<>();    // 课堂成员 列表
    private MutableLiveData<List<WhiteBoard>> whiteBoardList = new MutableLiveData<>(); // 白板 列表
    private MutableLiveData<ScreenDisplay> display = new MutableLiveData<>();      // 屏幕显示
    private MutableLiveData<ApplyForSpeechRequest> applyForSpeechRequest = new MutableLiveData<>();   // 旁听者申请成为成员
    private MutableLiveData<DeviceControlInvite> deviceControlInvite = new MutableLiveData<>();     // 申请开启摄像头和麦克风
    private MutableLiveData<SpeechResult> speechResult = new MutableLiveData<>();       // 旁听者申请成员结果
    private MutableLiveData<UpgradeRoleInvite> upgradeRoleInvite = new MutableLiveData<>();         // 升级角色邀请
    private MutableLiveData<TicketExpired> ticketExpired = new MutableLiveData();           // 请求过期
    private MutableLiveData<List<String>> userListUserIds = new MutableLiveData<>();         // 学员视频列表
    private MutableLiveData<ClassMember> assistantRole = new MutableLiveData<>();         // 助教角色
    private MutableLiveData<ClassMember> lecturerRole = new MutableLiveData<>();         // 讲师角色
    private MutableLiveData<List<StreamResource>> initUserVideoList = new MutableLiveData<>();         // 加入房间时的视频列表
    private MutableLiveData<StreamResource> addVideoUser = new MutableLiveData<>();         // 有新人发布视频
    private MutableLiveData<StreamResource> removeVideoUser = new MutableLiveData<>();      // 退出视频发布
    private MutableLiveData<ClassMember> kickedoff = new MutableLiveData<>();    // 退出视频发布
    private MutableLiveData<Integer> unReadMessage = new MutableLiveData<>();   // 未读消息
    private MutableLiveData<ClassMember> roleChangeUser = new MutableLiveData<>();   // 默认身份改变
    private MutableLiveData<Boolean> localUserStartVideoChat = new MutableLiveData<>();   //开始音视频
    private MutableLiveData<DeviceChange> deviceChange = new MutableLiveData<>();   //开始音视频
    private MutableLiveData<DeviceChangeToast> deviceChangeToast = new MutableLiveData<>();   //开始音视频
    private MutableLiveData<Boolean> respondApplySpeechTimeout = new MutableLiveData<>();   // 相应申请发言超时
    private MutableLiveData<FirstFrameUserInfo> fisrtFrameDraw = new MutableLiveData<>();   // 相应申请发言超时
    private MutableLiveData<PlayMidi> playMidiMode = new MutableLiveData<>();   // 相应申请发言超时
    private MutableLiveData<ClassMember> addClassMember = new MutableLiveData<>();   // 相应申请发言超时
    private MutableLiveData<ClassMember> removeClassMember = new MutableLiveData<>();   // 相应申请发言超时
    private MutableLiveData<String> leaveRoom = new MutableLiveData<>();   // 相应申请发言超时
    private MutableLiveData<WhiteCreateBean> createWhiteBoard = new MutableLiveData<>();   // 相应申请发言超时
    private MutableLiveData<ClassMember.ScheduleStudentMusicScoresBean> playExamSong = new MutableLiveData<>();   // 相应申请发言超时

    private MutableLiveData<InsertImageBean> uploadFile = new MutableLiveData<>();   // 当前用户自己的信息


    private MutableLiveData<List<ClassMember>> queryNoJoinStu = new MutableLiveData<>();   // 当前用户自己的信息
    private MutableLiveData<DownLoadSong> downLoadSong = new MutableLiveData<>();   // 可以下载伴奏学员
    private MutableLiveData<DeviceSoudValum> deviceSoundValume = new MutableLiveData<>();   // 设备音量控制


    private MutableLiveData<MetronomeInfo> metronomeInfo = new MutableLiveData<>();   // 当前用户自己的信息

    private MutableLiveData<Calendar> passedTime = new MutableLiveData<>();     // 经过的时间
    private MutableLiveData<Calendar> quitRoomPaseedTime = new MutableLiveData<>();     // 经过的时间
    private MutableLiveData<Boolean> accompanyVolume = new MutableLiveData<>();     // 伴奏音量


    private Timer countPassTimeTimer = new Timer();
    private CountDownTimer applySpeechRequestTimer = new CountDownTimer(30 * 1000, 1000) {

        @Override
        public void onTick(long millisUntilFinished) {

        }

        @Override
        public void onFinish() {
            respondApplySpeechTimeout.postValue(true);
        }
    };

    /**
     * 列表人员有没有变化(主要是 id 以及顺序)
     */
    private volatile boolean isUserListNoUpdate = false;
    private volatile boolean isUserListRefreshData = false;
    private volatile boolean isRefreshExamSongList = false;
    private boolean onMetronomeIsPlay = false;
    private boolean onMusicIsPlay = false;
    private double zoomScale = 0;
    private String StuDisplayUserId;
    private String classId;
    private boolean isGongGe = false;


    private String musicScoreAccompanimentId;
    private boolean isAccompaniment;


    /**
     * 此构造方法不应该被使用
     * 声明此构造方法只为在已经通过{@link ClassViewModel.Factory}生成ViewModel后，
     * 让在生成此 ClassViewModel 的同一生命周期内的其他Fragment 可以不需要参数获取对象时使用
     */
    public ClassViewModel() {
        SLog.e(TAG, "ClassViewModel should be created by Factory with login info.");
    }


    public ClassViewModel(LoginResult result, Application application) {
        roomId.setValue(result.getRoomId());
        soundVolume.setValue(result.getSoundVolume());
        userInfo.setValue(result.getUserInfo());
        memberList.setValue(sortClassMember(result.getMembers()));
        ScreenDisplay screenDisplay = ScreenDisplay.createScreenDisplay(result.display);
        StuDisplayUserId = screenDisplay.getUserId();
        display.setValue(getDisplayWithClassMember(screenDisplay));
        ClassMember.PlayMidiJsonBean playMidiJsonBean = result.getUserInfo().getPlayMidiJson();

        classRepository = new ClassRepository(application.getApplicationContext());
        // 注册课堂事件监听
        classRepository.addOnClassEventListener(result.getRoomId(), onClassEventListener);


        //        remoteUserPublicResourceIds.postValue(new ArrayList<String>());
        classRepository.setOnClassVideoEventListener(onClassVideoEventListener);
        setMetronomeInfo(new MetronomeInfo(90, 3, 100));
        // 从成员中筛选出特定的角色用于单独对特殊角色的刷新
        findAndUpdateSpecialRole();
        int surplusTime = result.surplusTime;

        // 记时进入课堂的时间
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        if (surplusTime > 0) {
            calendar.add(Calendar.SECOND, surplusTime);
        }
        passedTime.setValue(calendar);
        TimerTask countTimeTask = new TimerTask() {
            @Override
            public void run() {
                Calendar time = passedTime.getValue();
                if (time.get(Calendar.HOUR_OF_DAY) != 0 || time.get(Calendar.MINUTE) != 0 || time.get(Calendar.SECOND) != 0) {
                    time.add(Calendar.SECOND, -1);
                    passedTime.postValue(time);
                } else {
                    countPassTimeTimer.cancel();
                    countPassTimeTimer.purge();
                    countPassTimeTimer = null;
                }
            }
        };
        countPassTimeTimer.schedule(countTimeTask, 1000, 1000);
    }

    public void refreshClassViewModel(LoginResult result, Application
            application) {
        roomId.setValue(result.getRoomId());
        userInfo.setValue(result.getUserInfo());
        soundVolume.setValue(result.getSoundVolume());
        memberList.setValue(sortClassMember(result.getMembers()));
        setMetronomeInfo(new MetronomeInfo(90, 3, 100));
        if (result.getUserInfo().getRole() == Role.STUDENT) {
            ScreenDisplay screenDisplay = ScreenDisplay.createScreenDisplay(result.getDisplay());
            display.setValue(getDisplayWithClassMember(screenDisplay));
        }
        StuDisplayUserId = result.getUserInfo().getUserId();
        ClassMember.PlayMidiJsonBean playMidiJsonBean = result.getUserInfo().getPlayMidiJson();

        classRepository = new ClassRepository(application.getApplicationContext());
        // 注册课堂事件监听
        classRepository.addOnClassEventListener(result.getRoomId(), onClassEventListener);
        //        remoteUserPublicResourceIds.postValue(new ArrayList<String>());
        classRepository.setOnClassVideoEventListener(onClassVideoEventListener);

        findAndUpdateSpecialRole();
        int surplusTime = result.getSurplusTime();

        // 记时进入课堂的时间
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        if (surplusTime > 0) {
            calendar.add(Calendar.SECOND, surplusTime);
        }
        passedTime.setValue(calendar);
        TimerTask countTimeTask = new TimerTask() {
            @Override
            public void run() {
                Calendar time = passedTime.getValue();
                if (time.get(Calendar.HOUR_OF_DAY) != 0 || time.get(Calendar.MINUTE) != 0 || time.get(Calendar.SECOND) != 0) {
                    time.add(Calendar.SECOND, -1);
                    passedTime.postValue(time);
                } else {
                    if (countPassTimeTimer != null) {
                        countPassTimeTimer.cancel();
                        countPassTimeTimer.purge();
                        countPassTimeTimer = null;
                    }

                }
            }
        };
        if (countPassTimeTimer != null) {
            countPassTimeTimer.cancel();
            countPassTimeTimer.purge();
            countPassTimeTimer = null;
        }
        countPassTimeTimer = new Timer();
        countPassTimeTimer.schedule(countTimeTask, 1000, 1000);
    }

    public void startQuitRoomPaseedTime(int autoCloseNetworkRoomTime) {
        // 记时进入课堂的时间
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.add(Calendar.SECOND, autoCloseNetworkRoomTime);
        quitRoomPaseedTime.setValue(calendar);
        Timer quitRoomTimeTimer = new Timer();
        TimerTask countTimeTask = new TimerTask() {
            @Override
            public void run() {
                Calendar time = quitRoomPaseedTime.getValue();
                if (time.get(Calendar.HOUR_OF_DAY) != 0 || time.get(Calendar.MINUTE) != 0 || time.get(Calendar.SECOND) != 0) {
                    time.add(Calendar.SECOND, -1);
                    quitRoomPaseedTime.postValue(time);
                } else {
                    quitRoomTimeTimer.cancel();
                    quitRoomTimeTimer.purge();
                }
            }
        };
        quitRoomTimeTimer.schedule(countTimeTask, 1000, 1000);
    }

    /**
     * 获取已经过的时间
     *
     * @return
     */
    public LiveData<PassedTime> getQuitRoomPaseedTime() {
        return Transformations.map(quitRoomPaseedTime, new Function<Calendar, PassedTime>() {
            @Override
            public PassedTime apply(Calendar calendar) {
                PassedTime passedTime = new PassedTime();
                passedTime.setTwinkle(true);
                passedTime.setPassedTime(passTimeDateFormat.format(calendar.getTime()));
                return passedTime;
            }
        });
    }

    public String getMusicScoreAccompanimentId() {
        return musicScoreAccompanimentId;
    }

    public void setMusicScoreAccompanimentId(String musicScoreAccompanimentId) {
        this.musicScoreAccompanimentId = musicScoreAccompanimentId;
    }

    public boolean isAccompaniment() {
        return isAccompaniment;
    }

    public void setAccompaniment(boolean isAccompaniment) {
        this.isAccompaniment = isAccompaniment;
    }

    public boolean isOnMetronomeIsPlay() {
        return onMetronomeIsPlay;
    }

    public void setOnMetronomeIsPlay(boolean onMetronomeIsPlay) {
        this.onMetronomeIsPlay = onMetronomeIsPlay;
    }

    public boolean isOnMusicIsPlay() {
        return onMusicIsPlay;
    }

    public void setOnMusicIsPlay(boolean onMusicIsPlay) {
        this.onMusicIsPlay = onMusicIsPlay;
    }

    public void setMetronomeInfo(MetronomeInfo info) {
        metronomeInfo.setValue(info);
    }


    public MutableLiveData<MetronomeInfo> getMetronomeInfo() {
        return metronomeInfo;
    }

    public MutableLiveData<String> getLeaveRoom() {
        return leaveRoom;
    }

    /**
     * 白板房间对象
     */
    Room room;

    public void setWhiteSdkRoom(Room room) {
        this.room = room;
    }

    public void setUserInfo(UserInfo userInfo) {
        this.userInfo.setValue(userInfo);
    }

    public void setDisplay(ScreenDisplay screenDisplay) {
        this.display.setValue(screenDisplay);
    }

    public MutableLiveData<List<ClassMember>> getQueryNoJoinStu() {
        return queryNoJoinStu;
    }

    /**
     * 插入图片文件上传
     */
    public MutableLiveData<InsertImageBean> getUploadFileUrl() {
        return uploadFile;
    }

    public MutableLiveData<Boolean> getAccompanyVolume() {
        return accompanyVolume;
    }
    public void setAccompanyVolume(boolean volume) {
        accompanyVolume.postValue(false);

        stopAccompany();
    }

    public MutableLiveData<WhiteCreateBean> getCreateWhiteBoard() {
        return createWhiteBoard;
    }

    public LiveData<VideoClassMemberData> getExamSongDownloadClassMember() {
        return Transformations.map(memberList, new Function<List<ClassMember>, VideoClassMemberData>() {
            @Override
            public VideoClassMemberData apply(List<ClassMember> input) {

                if (input == null || input.size() <= 0) {
                    return null;
                }
                List<ClassMember> songMembers = new ArrayList<>();
                for (ClassMember member : input) {
                    if (member.getRole() == Role.STUDENT) {
                        songMembers.add(member);
                    }
                }
                VideoClassMemberData data = new VideoClassMemberData();
                data.setMember(songMembers);
                data.setRefreshExamSongList(isRefreshExamSongList);
                isRefreshExamSongList = false;
                return data;
            }
        });
    }

    /**
     * 播放伴奏
     *
     * @return
     */
    public MutableLiveData<ClassMember.ScheduleStudentMusicScoresBean> getPlayExamSong() {
        return playExamSong;
    }

    /**
     * 下载伴奏通知
     *
     * @return
     */
    public MutableLiveData<DownLoadSong> getDownLoadSong() {
        return downLoadSong;
    }


    /**
     * 获取当前用户信息
     *
     * @return
     */
    public LiveData<UserInfo> getUserInfo() {
        return userInfo;
    }

    /**
     * 设备音量控制
     * @return
     */
    public LiveData<DeviceSoudValum> getSoundValum() {
        return deviceSoundValume;
    };
    /**
     * 获取当自己设备被停用状态
     *
     * @return
     */
    public LiveData<DeviceType> geOnDisableDevice() {
        return onDisableDevice;
    }

    public LiveData<String> getRoomId() {
        return roomId;
    }

    public LiveData<Integer> getSoundVolume() {
        return soundVolume;
    }
    /**
     * 获取成员列表
     *
     * @return
     */
    public LiveData<List<ClassMember>> getMemberList() {
        return memberList;
    }

    /**
     * @param classMembers
     */
    public void setMemberList(List<ClassMember> classMembers) {
        memberList.setValue(classMembers);
    }

    /**
     * 获取画布列表
     *
     * @return
     */
    public LiveData<List<WhiteBoard>> getWhiteBoardList() {
        return whiteBoardList;
    }

    /**
     * 获取共享画布显示内容
     *
     * @return
     */
    public LiveData<ScreenDisplay> getDisplay() {
        return display;
    }

    /**
     * 获取申请发言邀请
     *
     * @return
     */
    public LiveData<ApplyForSpeechRequest> getApplyForSpeechRequest() {
        return applyForSpeechRequest;
    }

    /**
     * 获取被邀请开启设备（摄像头、麦克风）状态和邀请后对方的响应状态
     *
     * @return
     */
    public LiveData<DeviceControlInvite> getDeviceControlInvite() {
        return deviceControlInvite;
    }

    /**
     * 获取申请发言结果
     *
     * @return
     */
    public LiveData<SpeechResult> getSpeechResult() {
        return speechResult;
    }

    /**
     * 获取非旁听用户的视频资源
     *
     * @return
     */
    public LiveData<List<String>> getVideoListUserIds() {
        return userListUserIds;
    }

    /**
     * 获取助教角色
     *
     * @return
     */
    public LiveData<ClassMember> getAssistant() {
        return assistantRole;
    }

    /**
     * 获取讲师角色
     *
     * @return
     */
    public LiveData<ClassMember> getLecturer() {
        return lecturerRole;
    }

    /**
     * 获取申请提升角色邀请
     *
     * @return
     */
    public LiveData<UpgradeRoleInvite> getUpgradeRoleInvite() {
        return upgradeRoleInvite;
    }

    /**
     * 获取申请过期反馈
     *
     * @return
     */
    public LiveData<TicketExpired> getTicketExpired() {
        return ticketExpired;
    }


    /**
     * 获取非旁听用户的视频资源
     *
     * @return
     */
    public LiveData<List<StreamResource>> getInitVideoList() {
        return initUserVideoList;
    }

    /**
     * 获取视频增加的用户
     *
     * @return
     */
    public LiveData<StreamResource> getVideoAddedUser() {
        return addVideoUser;
    }



    /**
     * 获取视频退出的用户
     *
     * @return
     */
    public LiveData<StreamResource> getVideoRemovedUser() {
        return removeVideoUser;
    }


    /**
     * 用户被踢
     *
     * @return
     */
    public LiveData<ClassMember> getKickedOff() {
        return kickedoff;
    }


    /**
     * 角色变化
     *
     * @return
     */
    public LiveData<ClassMember> getRoleChangeUser() {
        return roleChangeUser;
    }

    /**
     * 本地用户开始进行音视频
     *
     * @return
     */
    public LiveData<Boolean> getLocalUserStartVideoChat() {
        return localUserStartVideoChat;
    }

    public MutableLiveData<PlayMidi> getPlayMidiMode() {
        return playMidiMode;
    }

    /**
     * 获取音视频成员列表
     *
     * @return
     */
    public LiveData<VideoClassMemberData> getVideoMembersList() {

        return Transformations.map(memberList, new Function<List<ClassMember>, VideoClassMemberData>() {
            @Override
            public VideoClassMemberData apply(List<ClassMember> input) {
                if (input == null || input.size() <= 0) {
                    return null;
                }

                //                // 重写创建新的集合， 防止对原油顺序造成影响
                //                ArrayList<ClassMember> tmp = new ArrayList<>();
                //                tmp.addAll(input);
                //
                //                Collections.sort(tmp, new Comparator<ClassMember>() {
                //                    @Override
                //                    public int compare(ClassMember o1, ClassMember o2) {
                //                        long l = o1.getJoinTime() - o2.getJoinTime();
                //                        int i = l > 0 ? 1 : l < 0 ? -1 : 0;
                //                        return i;
                //                    }
                //                });

                ClassMember userInfoValue = userInfo.getValue();
                ArrayList<ClassMember> members = new ArrayList<>();
                boolean hasLecture = false;
                for (ClassMember member : input) {
                    if (member.getRole() != Role.LISTENER || (userInfoValue != null && userInfoValue.getUserId().equals(member.getUserId()))) {
                        if (member.getRole() == Role.LECTURER) {
                            hasLecture = true;
                            members.add(0, member);
                        } else {
                            members.add(member);
                        }
                    }
                }

                //                tmp.clear();

                if (!hasLecture) {
                    ClassMember member = new ClassMember();
                    member.setUserName("");
                    member.setRole(Role.LECTURER.getValue());
                    member.setUserId("-1");
                    members.add(0, member);
                }


                VideoClassMemberData data = new VideoClassMemberData();
                data.setMember(members);
                data.setNoUpdate(isUserListNoUpdate);
                data.setRefreshData(isUserListRefreshData);
                isUserListNoUpdate = false;
                isUserListRefreshData = false;
                return data;
            }
        });

    }


    /**
     * 获取讲师和助教列表
     *
     * @return
     */
    public LiveData<List<ClassMember>> getAssistantAndLecturerList() {
        return Transformations.map(memberList, new Function<List<ClassMember>, List<ClassMember>>() {
            @Override
            public List<ClassMember> apply(List<ClassMember> input) {
                if (input == null || input.size() <= 0) {
                    return null;
                }

                ArrayList<ClassMember> members = new ArrayList<>();
                for (ClassMember member : input) {
                    if (member.getRole() == Role.LECTURER) {
                        members.add(member);
                    }
                }
                return members;
            }
        });
    }

    public MutableLiveData<ClassMember> getAddClassMember() {
        return addClassMember;
    }

    public void setAddClassMember(MutableLiveData<ClassMember> addClassMember) {
        this.addClassMember = addClassMember;
    }

    public MutableLiveData<ClassMember> getRemoveClassMember() {
        return removeClassMember;
    }

    public void setRemoveClassMember(MutableLiveData<ClassMember> removeClassMember) {
        this.removeClassMember = removeClassMember;
    }

    // 设备状态变化
    public LiveData<DeviceChange> getDeviceChange() {
        return deviceChange;
    }

    // 设备状态变化
    public LiveData<DeviceChangeToast> getDeviceChangeToast() {
        return deviceChangeToast;
    }



    public LiveData<Boolean> getRespondApplySpeechTimeout() {
        return respondApplySpeechTimeout;
    }

    //第一绘画通知
    public LiveData<FirstFrameUserInfo> getFisrtFrameDraw() {
        return fisrtFrameDraw;
    }

    public void setWhiteBoardScale(double zoomScale) {
        this.zoomScale = zoomScale;
    }

    public double getZoomScale() {
        return zoomScale;
    }

    public void setGongGe(boolean b) {
        this.isGongGe = b;
    }

    public boolean getGongGe() {
        return isGongGe;
    }

    public void setClassId(String classId) {
        this.classId = classId;
    }

    public String getClassId() {
        return classId;
    }


    public static class Factory extends ViewModelProvider.NewInstanceFactory {
        private LoginResult loginResult;
        private Application application;

        public Factory(LoginResult result, Application application) {
            this.loginResult = result;
            this.application = application;
        }


        @NonNull
        @Override
        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
            try {
                return modelClass.getConstructor(LoginResult.class, Application.class).newInstance(loginResult, application);
            } catch (Exception e) {
                throw new RuntimeException("Cannot create an instance of " + modelClass, e);
            }
        }
    }

    /**
     * 退出房间
     *
     * @param roomId
     * @return
     */
    public LiveData<RequestState> leaveRoom(String roomId, String userId) {
        leaveRoom.postValue(roomId);
        RCRTCAudioMixer.getInstance().stop();
        final StateLiveData stateLiveData = new StateLiveData();
        classRepository.leave(roomId, userId, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }


    /**
     * 踢人操作
     *
     * @param roomId
     * @param userId
     * @return
     */
    public LiveData<RequestState> kickOff(String roomId, String userId) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.kickOff(roomId, userId, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 未加入房间人员
     *
     * @param roomId
     * @return
     */
    public LiveData<RequestState> queryNoJoinStu(String roomId) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.queryNoJoinStu(roomId, new ResultCallback<List<ClassMember>>() {
            @Override
            public void onSuccess(List<ClassMember> result) {
                queryNoJoinStu.postValue(result);
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }


    /**
     * 控制摄像头
     *
     * @param roomId
     * @param userId
     * @param cameraOn
     * @return
     */
    public LiveData<RequestState> controlCamera(String roomId, String userId, boolean cameraOn) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.controlCamera(roomId, userId, cameraOn, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 控制学员音量
     *
     * @param roomId
     * @param userId
     * @param cameraOn
     * @param deviceType
     * @param soundVolume
     * @return
     */
    public LiveData<RequestState> controlVolume(String roomId, String userId, boolean cameraOn, String deviceType, String soundVolume) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.controlVolume(roomId, userId, cameraOn, deviceType, soundVolume, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 控制音乐模式
     *
     * @param roomId
     * @param userId
     * @param musicModeOn
     * @return
     */
    public LiveData<RequestState> controlMusicMode(String roomId, String userId,
                                                   boolean musicModeOn) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.controlMusicMode(roomId, userId, musicModeOn, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 控制语音设备
     *
     * @param roomId
     * @param userId
     * @param microphone
     * @return
     */
    public LiveData<RequestState> controlMicrophone(String roomId, String userId,
                                                    boolean microphone) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.controlMicrophone(roomId, userId, microphone, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 控制伴奏播放
     *
     * @param roomId
     * @param userId
     * @return
     */
    public LiveData<RequestState> controlExamSong(String roomId, String userId, String musicScoreOn, String accompanimentOn, String musicScoreAccompanimentId, ResultCallback<Boolean> callBack) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.controlExamSong(roomId, userId, musicScoreOn, accompanimentOn, musicScoreAccompanimentId, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                callBack.onSuccess(result);
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
                callBack.onFail(errorCode, errorStr);
            }
        });

        return stateLiveData;
    }

    /**
     * 举手
     *
     * @param roomId
     * @param userId
     * @param handUpOn
     * @return
     */
    public LiveData<RequestState> controlHandUpOn(String roomId, String userId, boolean handUpOn) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.controlHandUpOn(roomId, userId, handUpOn, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });
        return stateLiveData;
    }

    /**
     * 举手
     *
     * @param roomId
     * @param handUpOn
     * @return
     */
    public LiveData<RequestState> deviceSyncHandUpOn(String roomId, String userId,
                                                     boolean handUpOn) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.deviceSyncHandUpOn(roomId, userId, handUpOn, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 控制全员摄像头
     *
     * @param roomId
     * @param cameraOn
     * @return
     */
    public LiveData<RequestState> batchControlCamera(String roomId, boolean cameraOn) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.batchControlCamera(roomId, cameraOn, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 控制全员音乐模式
     *
     * @param roomId
     * @param musicModeOn
     * @return
     */
    public LiveData<RequestState> batchControlMusicMode(String roomId, boolean musicModeOn) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.batchControlMusicMode(roomId, musicModeOn, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 控制全员语音设备
     *
     * @param roomId
     * @param microphone
     * @return
     */
    public LiveData<RequestState> batchControlMicrophone(String roomId, boolean microphone) {
        return batchControlMicrophone(roomId, null, microphone);
    }

    /**
     * 控制全员语音设备
     *
     * @param roomId
     * @param microphone
     * @return
     */
    public LiveData<RequestState> batchControlMicrophone(String roomId, String userId,
                                                         boolean microphone) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.batchControlMicrophone(roomId, userId, microphone, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 控制全员语音设备
     *
     * @param roomId
     * @return
     */
    public LiveData<RequestState> batchControlExamSong(String roomId, String userId, String musicScoreOn, String accompanimentOn, String musicScoreAccompanimentId,String soudnValue) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.batchControlExamSong(roomId, userId, musicScoreOn, accompanimentOn, musicScoreAccompanimentId,soudnValue, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    public LiveData<RequestState> batchControlExamSong(String roomId, String userId, String musicScoreOn, String accompanimentOn, String musicScoreAccompanimentId) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.batchControlExamSong(roomId, userId, musicScoreOn, accompanimentOn, musicScoreAccompanimentId,"", new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 控制全员节拍器
     *
     * @param roomId
     * @param
     * @return
     */
    public LiveData<RequestState> sendImPlayMidiMessage(String userId, String roomId,
                                                        boolean enable, ResultCallback<Boolean> callBack) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        MetronomeInfo info = metronomeInfo.getValue();
        classRepository.sendImPlayMidiMessage(userId, roomId, enable, info.getRate(), info.getCustomType(), info.getVolume(), new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                callBack.onSuccess(result);
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                callBack.onFail(errorCode, errorStr);
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 通知学生下载伴奏
     */
    public void pushDownloadexamSongMsg(String roomId, String musicScoreAccompanimentId, String url, String mp3Url, String fileName, String
            speed, ResultCallback<Boolean> callBack) {
        UserInfo user = userInfo.getValue();
        List<ClassMember.ScheduleStudentMusicScoresBean> scheduleStudentMusicScores = user.getScheduleStudentMusicScores();
        if (scheduleStudentMusicScores == null) {
            scheduleStudentMusicScores = new ArrayList<>();
        }
        boolean isAddMusicScore = true;
        for (ClassMember.ScheduleStudentMusicScoresBean musicScores : scheduleStudentMusicScores) {
            if (musicScoreAccompanimentId.equals(musicScores.getMusicScoreAccompanimentId())) {
                isAddMusicScore = false;
                break;
            }
        }
        List<ClassMember> memberListValue = memberList.getValue();
        if (isAddMusicScore) {
            ClassMember.ScheduleStudentMusicScoresBean musicScoresBean = new ClassMember.ScheduleStudentMusicScoresBean();
            musicScoresBean.setId(musicScoreAccompanimentId);
            musicScoresBean.setMusicScoreAccompanimentId(musicScoreAccompanimentId);
            musicScoresBean.setMsicScoreName(fileName);
            musicScoresBean.setMp3Url(mp3Url);
            musicScoresBean.setDownStatus(0);
            musicScoresBean.setUrl(url);
            musicScoresBean.setSpeed(Integer.valueOf(speed));
            musicScoresBean.setAccompanimentPlayStatus(0);
            musicScoresBean.setIsAccompaniment(TextUtils.isEmpty(url) ? 1 : 0);
            musicScoresBean.setPlayStatus(0);
            scheduleStudentMusicScores.add(musicScoresBean);
            user.setScheduleStudentMusicScores(scheduleStudentMusicScores);
            userInfo.postValue(user);

            if (memberListValue != null) {
                for (ClassMember member : memberListValue) {
                    List<ClassMember.ScheduleStudentMusicScoresBean> studentMusicScores = member.getScheduleStudentMusicScores();
                    if (studentMusicScores == null) {
                        studentMusicScores = new ArrayList<>();
                    }
                    studentMusicScores.add(musicScoresBean);
                    member.setScheduleStudentMusicScores(studentMusicScores);
                }
            }

        }
        userInfo.postValue(user);
        memberList.postValue(memberListValue);
        classRepository.pushDownloadexamSongMsg(roomId, musicScoreAccompanimentId, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean aBoolean) {
                if (callBack != null) {
                    callBack.onSuccess(aBoolean);
                }

            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                if (callBack != null) {
                    callBack.onFail(errorCode, errorStr);
                }
            }
        });
    }

    /**
     * 同意开启设备
     *
     * @param roomId
     * @param ticket
     * @return
     */
    public LiveData<RequestState> deviceApprove(String roomId, String deviceType) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.deviceApprove(roomId, deviceType, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 拒绝开启设备
     *
     * @param roomId
     * @param ticket
     * @return
     */
    public LiveData<RequestState> deviceReject(String roomId, String deviceType) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.deviceReject(roomId, deviceType, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 同步摄像头状态
     *
     * @param roomId
     * @param cameraOn
     * @return
     */
    public LiveData<RequestState> deviceSyncCamera(String roomId, boolean cameraOn) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.deviceSyncCamera(roomId, cameraOn, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 同步音乐模式状态
     *
     * @param roomId
     * @param musicModeOn
     * @return
     */
    public LiveData<RequestState> deviceSyncMusicMode(String roomId, boolean musicModeOn) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.deviceSyncMusicMode(roomId, musicModeOn, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }


    /**
     * 同步语音状态
     *
     * @param roomId
     * @param microphoneOn
     * @return
     */
    public LiveData<RequestState> deviceSyncMic(String roomId, boolean microphoneOn) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.deviceSyncMic(roomId, microphoneOn, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 同步伴奏播放状态
     *
     * @param roomId
     * @return
     */
    public LiveData<RequestState> deviceSyncExamSong(String roomId, boolean examSong) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.deviceSyncExamSong(roomId, examSong, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }


    /**
     * 批量降级
     *
     * @param roomId
     * @param members
     * @return
     */
    public LiveData<RequestState> downgrade(String roomId, List<ClassMember> members) {
        List<ChangedUser> users = new ArrayList<>();
        for (ClassMember member : members) {
            ChangedUser user = new ChangedUser();
            user.role = Role.LISTENER.getValue(); // 降级到旁听
            user.userId = member.getUserId();
            users.add(user);
        }

        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.downgrade(roomId, users, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 请求发言
     *
     * @param roomId
     * @return
     */
    public LiveData<RequestState> applySpeech(String roomId) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();

        // 申请中
        UserInfo userInfoValue = userInfo.getValue();
        userInfoValue.setApplySpeeching(true);
        userInfo.postValue(userInfoValue);

        classRepository.applySpeech(roomId, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();

            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
                // 申请失败
                UserInfo userInfoValue = userInfo.getValue();
                userInfoValue.setApplySpeeching(false);
                userInfo.postValue(userInfoValue);
            }
        });

        return stateLiveData;
    }


    /**
     * 同意发言
     *
     * @param roomId
     * @return
     */
    public LiveData<RequestState> approveSpeech(String roomId, String ticket) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        applySpeechRequestTimer.cancel();
        classRepository.approveSpeech(roomId, ticket, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 拒绝发言
     *
     * @param roomId
     * @return
     */
    public LiveData<RequestState> rejectSpeech(String roomId, String ticket) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        applySpeechRequestTimer.cancel();
        classRepository.rejectSpeech(roomId, ticket, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }


    /**
     * 转移角色
     *
     * @param roomId
     * @return
     */
    public LiveData<RequestState> transferRole(String roomId, String userId) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.transferRole(roomId, userId, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }


    /**
     * 邀请升级
     *
     * @param roomId
     * @return
     */
    public LiveData<RequestState> upgradeIntive(String roomId, String userId, int role) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.upgradeIntive(roomId, userId, role, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 接受升级
     *
     * @param roomId
     * @return
     */
    public LiveData<RequestState> upgradeApprove(String roomId, String ticket) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.upgradeApprove(roomId, ticket, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 拒绝升级
     *
     * @param roomId
     * @return
     */
    public LiveData<RequestState> upgradeReject(String roomId, String ticket) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.upgradeReject(roomId, ticket, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }

    /**
     * 拒绝升级
     *
     * @param roomId
     * @return
     */
    public LiveData<WhiteCreateBean> createWhiteBoard(String roomId) {
        classRepository.createWhiteBoard(roomId, new ResultCallback<WhiteCreateBean>() {
            @Override
            public void onSuccess(WhiteCreateBean result) {
                LogUtils.i("pq","WhiteCreateBean:"+result);
                createWhiteBoard.postValue(result);
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                LogUtils.i("pq","WhiteCreateBean onFail:"+errorCode+"-errorStr:"+errorStr);
            }
        });
        return createWhiteBoard;
    }

    /**
     * 升级为讲师
     *
     * @param roomId
     * @return
     */
    public LiveData<RequestState> changeRole(String roomId, String userId, int role) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.changeRole(roomId, userId, role, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });

        return stateLiveData;
    }


    /**
     * 创建白板
     */

    public LiveData<RequestState> createOneWhiteBoard() {

        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();

        String PAGE = String.valueOf(System.currentTimeMillis());
        room.putScenes(WhiteBoardApi.WHITE_BOARD_SCENE_PATH, new Scene[]{
                new Scene(PAGE)}, 0);
        updateWhiteBoardList();
        return stateLiveData;
    }

    /**
     * 插入图片
     *
     * @return
     */
    public LiveData<RequestState> WhiteBoardInsertImage(String fileUrl,
                                                        double imageWidth,
                                                        double imageHidtht) {
        LogUtils.i("白板问题==WhiteBoardInsertImage  = fileUrl==" + fileUrl);
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.uploadFile(fileUrl, new Callback<BaseResponse<FileUploadBean>>() {
            @Override
            public void onResponse(Call<BaseResponse<FileUploadBean>> call, Response<BaseResponse<FileUploadBean>> data) {
                stateLiveData.success();
                if (data != null && data.body() != null && data.body().getData() != null) {
                    InsertImageBean insertImageBean = new InsertImageBean();
                    insertImageBean.setFileUrl(data.body().getData().getUrl());
                    insertImageBean.setImageWidt(imageWidth);
                    insertImageBean.setImageHidtht(imageHidtht);
                    uploadFile.postValue(insertImageBean);
                }


            }

            @Override
            public void onFailure(Call<BaseResponse<FileUploadBean>> call, Throwable t) {
                stateLiveData.failed(1);
            }
        });
        return stateLiveData;
    }

    /**
     * uploadFile
     *
     * @return
     */
    public void uploadFile(String fileUrl, ResultCallback<String> callBack) {
        classRepository.uploadFile(fileUrl, new Callback<BaseResponse<FileUploadBean>>() {
            @Override
            public void onResponse(Call<BaseResponse<FileUploadBean>> call, Response<BaseResponse<FileUploadBean>> data) {
                if (data != null && data.body() != null && data.body().getData() != null) {
                    callBack.onSuccess(data.body().getData().getUrl());
                } else {
                    callBack.onFail(-1, "提交失败，请重试");
                }


            }

            @Override
            public void onFailure(Call<BaseResponse<FileUploadBean>> call, Throwable t) {
                callBack.onFail(-1, "提交失败，请重试");
            }
        });
    }

    /**
     * 课程申诉
     *
     * @return
     */
    public void addComplaints(String courseScheduleId, String url, String
            content, ResultCallback<Boolean> callBack) {
        classRepository.addComplaints(courseScheduleId, url, content, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean aBoolean) {
                callBack.onSuccess(aBoolean);
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                callBack.onFail(errorCode, errorStr);
            }
        });
    }

    /**
     * 获取白板列表
     *
     * @param
     * @return
     */
    public LiveData<RequestState> updateWhiteBoardList() {

        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        if (null != room) {
            room.getScenes(new Promise<Scene[]>() {
                @Override
                public void then(Scene[] scenes) {
                    List<WhiteBoard> reverseList = new ArrayList<>();
                    for (int i = 0; i < scenes.length; i++) {
                        WhiteBoard whiteBoard = new WhiteBoard();
                        whiteBoard.setName(scenes[i].getName());
                        whiteBoard.setWhiteboardId(scenes[i].getName());
                        reverseList.add(whiteBoard);
                        stateLiveData.success();
                    }
                    whiteBoardList.postValue(reverseList);
                }

                @Override
                public void catchEx(SDKError sdkError) {
                    //                stateLiveData.failed(1);
                }
            });
        }

        return stateLiveData;
    }

    /**
     * 切换共享画布区显示内容
     *
     * @param roomId
     * @param type   显示类型，参考{@link ScreenDisplay.Display}
     * @param id     当显示用户时传入用户id，当为白板时传入白板id
     * @return
     */
    public LiveData<RequestState> switchDisplay(String roomId,
                                                final ScreenDisplay.Display type, String id, boolean isPostDisplay) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        final String userId;
        final String whiteBoardId;
        switch (type) {
            case LECTURER:
            case STUDENT:
            case SCREEN:
                userId = id;
                whiteBoardId = null;
                break;
            case WHITEBOARD:
                userId = id;
                whiteBoardId = null;
                break;
            default:
                userId = null;
                whiteBoardId = null;
        }
        if (isPostDisplay) {
            StuDisplayUserId = userId;
            classRepository.switchDisplay(roomId, type.getType(), userId, whiteBoardId, new ResultCallback<Boolean>() {
                @Override
                public void onSuccess(Boolean aBoolean) {
                    stateLiveData.success();
                    ScreenDisplay toDisplay = new ScreenDisplay();
                    toDisplay.setType(type);
                    toDisplay.setUserId(userId);
                    toDisplay.setWhiteBoardUri(whiteBoardId);
                    ScreenDisplay displayWithClassMember = getDisplayWithClassMember(toDisplay);
                    display.postValue(displayWithClassMember);
                }

                @Override
                public void onFail(int errorCode, String errorStr) {
                    stateLiveData.failed(errorCode);
                }
            });

        } else {
            ScreenDisplay toDisplay = new ScreenDisplay();
            toDisplay.setType(type);
            toDisplay.setUserId(userId);
            toDisplay.setWhiteBoardUri(whiteBoardId);
            ScreenDisplay displayWithClassMember = getDisplayWithClassMember(toDisplay);
            display.postValue(displayWithClassMember);
        }

        return stateLiveData;
    }

    /**
     * 获取未读消息
     *
     * @return
     */
    public LiveData<Integer> getUnReadMessage() {
        return unReadMessage;
    }

    /**
     * 获取已经过的时间
     *
     * @return
     */
    public LiveData<PassedTime> getPassedTime() {
        return Transformations.map(passedTime, new Function<Calendar, PassedTime>() {
            @Override
            public PassedTime apply(Calendar calendar) {
                PassedTime passedTime = new PassedTime();
                if ((calendar.get(Calendar.MINUTE) < 5 || (calendar.get(Calendar.MINUTE) == 5 && calendar.get(Calendar.SECOND) == 0)) && calendar.get(Calendar.HOUR_OF_DAY) == 0) {
                    passedTime.setTwinkle(true);
                } else {
                    passedTime.setTwinkle(false);
                }
                passedTime.setPassedTime(passTimeDateFormat.format(calendar.getTime()));
                return passedTime;
            }
        });
    }


    private void stopAccompany() {
        playExamSong.postValue(new ClassMember.ScheduleStudentMusicScoresBean(0, 0));
    }
    /**
     * 课堂事件监听
     * 通过注册监听，更新当前房间内的信息
     */
    private OnClassEventListener onClassEventListener = new OnClassEventListener() {
        @Override
        public void onMemberChanged(ClassMemberChangedAction action, ClassMember classMember) {
            switch (action) {
                case JOIN:
                    addClassMember(classMember);
                    tryToUpdateSpecialRole(classMember);
                    break;
                case LEAVE:
                    removeClassMember(classMember);
                    break;
                case KICK:
                    kickedoff.postValue(classMember);
                    removeClassMember(classMember);
                    break;
            }
        }

        @Override
        public void onWhiteBoardChanged(WhiteBoardAction action, WhiteBoard whiteBoard) {
            updateWhiteBoardList();
        }

        @Override
        public void onOpenDeviceInvite(DeviceControlInvite deviceInvite) {
            deviceControlInvite.postValue(deviceInvite);
        }

        @Override
        public void onDeviceStateChanged(String userId, DeviceType deviceType, boolean isEnable, String musicScoreAccompanimentId) {
            updateDeviceState(userId, deviceType, isEnable, musicScoreAccompanimentId);
        }

        @Override
        public void onDeviceStateChanged(String senderUserId, String userId, DeviceType deviceType, boolean isEnable, String musicScoreAccompanimentId) {
            deviceChangeToast.postValue(new DeviceChangeToast(senderUserId, userId, deviceType, isEnable));
        }

        @Override
        public void onDeviceStateChanged(Integer soundVolume, DeviceType deviceType,String musicScoreAccompanimentId) {
            deviceSoundValume.postValue(new DeviceSoudValum(soundVolume,deviceType,musicScoreAccompanimentId));
        }

        @Override
        public void onDisplayChanged(ScreenDisplay screenDisplay) {
            ScreenDisplay displayWithClassMember = getDisplayWithClassMember(screenDisplay);
            display.postValue(displayWithClassMember);
        }

        @Override
        public void onWhiteBoardPageChanged(String whiteBoardId, int curPage, String userId) {
            // 目前白板翻页由 web 页实现
        }

        @Override
        public void onRoleChanged(List<RoleChangedUser> roleChangedUserList, String optUserId) {
            if (roleChangedUserList == null || roleChangedUserList.size() == 0)
                return;

            List<ClassMember> memberListValue = memberList.getValue();
            UserInfo userInfoValue = userInfo.getValue();
            if (memberListValue == null || memberListValue.size() == 0)
                return;

            for (RoleChangedUser role : roleChangedUserList) {
                // 判断自己是不是变化了
                if (userInfoValue.getUserId().equals(role.getUserId())) {
                    userInfoValue.setRole(role.getRole().getValue());
                    userInfo.postValue(userInfoValue);

                    // 保存用户名，用于显示角色变化消息
                    role.setUserName(userInfoValue.getUserName());
                }

                for (ClassMember member : memberListValue) {
                    if (member.getUserId().equals(role.getUserId())) {
                        Role r = role.getRole();
                        member.setRole(r.getValue());
                        //个人改变后的信息刷新， 主要用户共享区域的 讲师和助手
                        roleChangeUser.postValue(member);
                        //判断是否包含在需要单独的刷新角色
                        tryToUpdateSpecialRole(member);

                        // 保存用户名，用于显示角色变化消息
                        role.setUserName(member.getUserName());
                        break;
                    }
                }

            }

            // 由于此消息中包含多个角色变化信息，需要转为单条并逐个显示在聊天列表中
            IMManager.getInstance().saveRoleChangedMessageToSingle(roleChangedUserList, optUserId, roomId.getValue());

            memberList.postValue(sortClassMember(memberListValue));
        }

        @Override
        public void onApplyForSpeechRequest(ApplyForSpeechRequest request) {
            applySpeechRequestTimer.start();
            if (request != null && TextUtils.isEmpty(request.getReqUserName())) {
                List<ClassMember> value = memberList.getValue();
                if (value != null) {
                    for (ClassMember member : value) {
                        if (member.getUserId().equals(request.getReqUserId())) {
                            request.setReqUserName(member.getUserName());
                        }
                    }
                }
            }
            applyForSpeechRequest.postValue(request);
        }

        @Override
        public void onTicketExpired(TicketExpired expired) {
            // 目前有两个地方使用到了超时， 升级和请求发言
            UserInfo userInfoValue = userInfo.getValue();
            userInfoValue.setApplySpeeching(false);
            userInfo.postValue(userInfoValue);
            ticketExpired.postValue(expired);
        }

        @Override
        public void onRequestSpeechResult(SpeechResult result) {
            //
            if (result.isAccept()) {
                List<ClassMember> memberListValue = memberList.getValue();
                if (memberListValue != null) {
                    for (ClassMember member : memberListValue) {
                        if (member.getUserId().equals(result.getReqUserId())) {
                            member.setRole(Role.STUDENT.getValue());
                            member.setCamera(true);
                            member.setMicrophone(true);
                            member.setUserName(result.getReqUserName());
                            memberList.postValue(memberListValue);
                            break;
                        }
                    }
                }

                UserInfo userInfoValue = userInfo.getValue();
                if (userInfoValue.getUserId().equals(result.getReqUserId())) {
                    userInfoValue.setRole(Role.STUDENT.getValue());
                    userInfoValue.setCamera(true);
                    userInfoValue.setMicrophone(true);
                    userInfoValue.setUserName(result.getReqUserName());
                    userInfoValue.setApplySpeeching(false);
                    userInfo.postValue(userInfoValue);
                }
            } else {
                // 拒绝申请
                UserInfo userInfoValue = userInfo.getValue();
                userInfoValue.setApplySpeeching(false);
                userInfo.postValue(userInfoValue);
            }

            speechResult.postValue(result);
        }

        @Override
        public void onInviteUpgradeRole(UpgradeRoleInvite invite) {
            upgradeRoleInvite.postValue(invite);
        }

        @Override
        public void onExistUnReadMessage(int count) {
            unReadMessage.postValue(count);
        }

        @Override
        public void onPlayMidiMessage(PlayMidi playMidi) {
            updataPlayMidi(playMidi);

        }

        @Override
        public void onExamSongDownloadMessage(DownLoadSong song) {

            ClassMember.ScheduleStudentMusicScoresBean bean = new ClassMember.ScheduleStudentMusicScoresBean();
            bean.setMsicScoreName(song.getExamSongName());
            bean.setMusicScoreAccompanimentId(song.getMusicScoreAccompanimentId());
            bean.setUrl(song.getUrl());
            bean.setMp3Url(song.getMp3Url());
            List<ClassMember.ScheduleStudentMusicScoresBean> scheduleStudentMusicScoresBeans = userInfo.getValue().getScheduleStudentMusicScores();
            if (scheduleStudentMusicScoresBeans == null) {
                scheduleStudentMusicScoresBeans = new ArrayList<>();

            }
            scheduleStudentMusicScoresBeans.add(bean);
            UserInfo info = userInfo.getValue();
            if (info != null) {
                info.setScheduleStudentMusicScores(scheduleStudentMusicScoresBeans);
            }
            userInfo.postValue(info);

            downLoadSong.postValue(song);
        }

        @Override
        public void onExamSongDownloadStatus(String studentId, List<DownLoadSongStatus> downLoadSongStatus) {
            updateExamSongDownloadStatus(studentId, downLoadSongStatus);
        }
    };

    private synchronized void updateExamSongDownloadStatus(String studentId, List<DownLoadSongStatus> downLoadSongStatus) {
        UserInfo user = userInfo.getValue();
        if (user.getRole() != Role.LECTURER || null == downLoadSongStatus || downLoadSongStatus.size() == 0) {
            return;
        }
        List<ClassMember> memberListValue = memberList.getValue();
        if (memberListValue != null) {
            for (ClassMember member : memberListValue) {
                if (member.getUserId().equals(studentId)) {
                    List<ClassMember.ScheduleStudentMusicScoresBean> musicScoresBeans = member.getScheduleStudentMusicScores();
                    if (musicScoresBeans == null || musicScoresBeans.size() == 0) {
                        for (DownLoadSongStatus status : downLoadSongStatus) {
                            ClassMember.ScheduleStudentMusicScoresBean bean = new ClassMember.ScheduleStudentMusicScoresBean(status.getAccompanimentPlayStatus(), status.getDownStatus(), status.getMusicScoreAccompanimentId(), status.getPlayStatus(), status.getSpeed(), status.getUrl(), status.getMp3Url(), status.getMusicScoreName());
                            musicScoresBeans.add(bean);
                        }
                        member.setScheduleStudentMusicScores(musicScoresBeans);
                        continue;
                    } else {
                        for (DownLoadSongStatus status : downLoadSongStatus) {
                            for (ClassMember.ScheduleStudentMusicScoresBean musicScoresBean : musicScoresBeans) {
                                if (status.getMusicScoreAccompanimentId().equals(musicScoresBean.getMusicScoreAccompanimentId())) {
                                    musicScoresBean.setDownStatus(status.getDownStatus());
                                    break;
                                }
                            }
                        }

                    }
                    break;
                }
            }


            isRefreshExamSongList = true;
            isUserListRefreshData = false;
            memberList.postValue(memberListValue);
        }

        if (user != null) {

            List<ClassMember.ScheduleStudentMusicScoresBean> userMusicSores = new ArrayList<>();
            userMusicSores.clear();
            userMusicSores.addAll(new Gson().fromJson(new Gson().toJson(user), UserInfo.class).getScheduleStudentMusicScores());

            for (DownLoadSongStatus status : downLoadSongStatus) {
                int downStatus = 1;
                for (int i = 0; i < memberListValue.size(); i++) {
                    ClassMember member = memberListValue.get(i);
                    if (member.getRole() == Role.STUDENT) {
                        for (ClassMember.ScheduleStudentMusicScoresBean musicScoresBean : member.getScheduleStudentMusicScores()) {
                            if (status.getMusicScoreAccompanimentId().equals(musicScoresBean.getMusicScoreAccompanimentId()) && musicScoresBean.getDownStatus() != 1) {
                                downStatus = musicScoresBean.getDownStatus();
                                break;
                            }
                        }

                    }
                }

                for (ClassMember.ScheduleStudentMusicScoresBean music : userMusicSores) {
                    if (status.getMusicScoreAccompanimentId().equals(music.getMusicScoreAccompanimentId())) {
                        music.setDownStatus(downStatus);
                        break;
                    }
                }
            }

            user.setScheduleStudentMusicScores(userMusicSores);
            userInfo.postValue(user);
        }

    }



    public void downLoadFile(String url, String filePath, String
            fileName, ResultCallback<Boolean> callback) {
        classRepository.downloadFile(url, filePath, fileName, callback);
    }

    public void adjustExamSong(String roomId, String musicScoreAccompanimentId,
                               int status) {
        classRepository.adjustExamSong(roomId, musicScoreAccompanimentId, status, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean aBoolean) {

            }

            @Override
            public void onFail(int errorCode, String errorStr) {

            }
        });
    }


    private void updataPlayMidi(PlayMidi playMidi) {
        UserInfo userInfoValue = userInfo.getValue();
        if (userInfoValue.getRole() == Role.STUDENT) {
            String userId = playMidi.getUserId();
            if (!TextUtils.isEmpty(userId)) {
                String[] userIds = userId.split(",");
                for (String id : userIds) {
                    if (id.equals(userInfoValue.getUserId())) {
                        UserInfo.PlayMidiJsonBean playMidiJsonBean = userInfoValue.getPlayMidiJson();
                        if (null == playMidiJsonBean) {
                            playMidiJsonBean = new UserInfo.PlayMidiJsonBean();
                        }
                        playMidiJsonBean.setEnable(playMidi.isEnable());
                        playMidiJsonBean.setCustomType(playMidi.getCustomType());
                        playMidiJsonBean.setRate(playMidi.getRate());
                        userInfoValue.setPlayMidiJson(playMidiJsonBean);
                        playMidiMode.postValue(playMidi);
                        break;
                    }
                }
            } else {
                UserInfo.PlayMidiJsonBean playMidiJsonBean = userInfoValue.getPlayMidiJson();
                if (null == playMidiJsonBean) {
                    playMidiJsonBean = new UserInfo.PlayMidiJsonBean();
                }
                playMidiJsonBean.setEnable(playMidi.isEnable());
                playMidiJsonBean.setCustomType(playMidi.getCustomType());
                playMidiJsonBean.setRate(playMidi.getRate());
                userInfoValue.setPlayMidiJson(playMidiJsonBean);
                playMidiMode.postValue(playMidi);
            }
        }
        if (userInfoValue.getRole() == Role.LECTURER) {
            List<ClassMember> memberListValue = memberList.getValue();
            String userId = playMidi.getUserId();
            if (memberListValue != null) {
                for (ClassMember member : memberListValue) {
                    if (TextUtils.isEmpty(userId)) {
                        ClassMember.PlayMidiJsonBean bean = new ClassMember.PlayMidiJsonBean();
                        bean.setCustomType(playMidi.getCustomType());
                        bean.setEnable(playMidi.isEnable());
                        bean.setRate(playMidi.getRate());
                        member.setPlayMidiJson(bean);
                    } else {
                        String[] userIds = userId.split(",");
                        for (String id : userIds) {
                            if (member.getUserId().equals(id)) {
                                ClassMember.PlayMidiJsonBean bean = new ClassMember.PlayMidiJsonBean();
                                bean.setCustomType(playMidi.getCustomType());
                                bean.setEnable(playMidi.isEnable());
                                bean.setRate(playMidi.getRate());
                                member.setPlayMidiJson(bean);
                                break;
                            }
                        }

                    }
                }
                memberList.postValue(memberListValue);
            }
        }
    }

    /**
     * 移除已存在成员
     */
    private void removeClassMember(ClassMember classMember) {
        removeClassMember.postValue(classMember);
        List<ClassMember> memberListValue = memberList.getValue();
        ClassMember removeMember = null;
        if (memberListValue != null) {
            for (ClassMember member : memberListValue) {
                if (member.getUserId().equals(classMember.getUserId())) {
                    removeMember = member;
                    break;
                }
            }

            if (removeMember != null) {
                if (removeMember.getRole() == Role.LECTURER && userInfo.getValue().getRole() == Role.STUDENT) {
                    PlayMidi playMidi = new PlayMidi();
                    playMidi.setEnable(false);
                    onClassEventListener.onPlayMidiMessage(playMidi);
                }
                List<ClassMember> noJoinStu = queryNoJoinStu.getValue();
                boolean isStuInList = false; //成员是否已在列表
                if (null != noJoinStu) {
                    for (ClassMember member : noJoinStu) {
                        if (member.getUserId().equals(classMember.getUserId())) {
                            isStuInList = true;
                            break;
                        }
                    }
                    if (!isStuInList) {
                        noJoinStu.add(classMember);
                        queryNoJoinStu.postValue(noJoinStu);
                    }
                }
                memberListValue.remove(removeMember);
                memberList.postValue(memberListValue);

            }
        }
    }


    /**
     * 添加新的课堂成员
     *
     * @param classMember
     */
    private void addClassMember(ClassMember classMember) {
        addClassMember.postValue(classMember);
        List<ClassMember> memberListValue = memberList.getValue();
        String userId = getDisplay().getValue().getUserId();
        if (userInfo.getValue().getRole() == Role.LECTURER &&
                classMember.getRole() != Role.LECTURER &&
                !TextUtils.isEmpty(StuDisplayUserId) && StuDisplayUserId.equals(classMember.getUserId())) {
            classMember.setOnStage(true);
        }
        if (memberListValue != null) {
            boolean isInList = false; //成员是否已在列表
            for (ClassMember member : memberListValue) {
                if (member.getUserId().equals(classMember.getUserId())) {
                    isInList = true;
                    break;
                }
            }
            //            TODO 学生端只显示自己和老师
            //            UserInfo user = userInfo.getValue();
            //            Role role = user.getRole();
            //            if (role != Role.LECTURER && classMember.getRole() != Role.LECTURER) {
            //                isInList = true;
            //            }
            if (classMember.getRole() == Role.LECTURER && userInfo.getValue().getRole() == Role.STUDENT) { //老师加入退出关闭学生节拍器
                PlayMidi playMidi = new PlayMidi();
                playMidi.setEnable(false);
                onClassEventListener.onPlayMidiMessage(playMidi);
            }

            if (!isInList) {
                memberListValue.add(classMember);
                memberList.postValue(sortClassMember(memberListValue));
            }
        } else {
            if (classMember.getRole() == Role.LECTURER && userInfo.getValue().getRole() == Role.STUDENT) {
                PlayMidi playMidi = new PlayMidi();
                playMidi.setEnable(false);
                onClassEventListener.onPlayMidiMessage(playMidi);
            }
            memberListValue = new ArrayList<>();
            memberListValue.add(classMember);
            memberList.postValue(sortClassMember(memberListValue));
        }

        List<ClassMember> noJoinStu = queryNoJoinStu.getValue();
        if (null != noJoinStu && noJoinStu.size() > 0) {
            for (ClassMember member : noJoinStu) {
                if (member.getUserId().equals(classMember.getUserId())) {
                    noJoinStu.remove(member);
                    queryNoJoinStu.postValue(noJoinStu);
                    break;
                }
            }
        }

    }

    /**
     * 更新课堂成员
     *
     * @param classMember
     */
    private void updateClassMember(ClassMember classMember) {
        List<ClassMember> memberListValue = memberList.getValue();
        if (memberListValue != null) {
            for (ClassMember member : memberListValue) {
                if (member.getUserId().equals(classMember.getUserId())) {
                    member.setRole(classMember.getRole().getValue());
                    member.setCamera(classMember.isCamera());
                    member.setMicrophone(classMember.isMicrophone());
                    member.setJoinTime(classMember.getJoinTime());
                    member.setUserName(classMember.getUserName());
                    memberList.postValue(memberListValue);
                    break;
                }
            }
        }
    }

    /**
     * 更新课堂成员角色
     *
     * @param userId
     * @param role
     */
    private void updateClassMember(String userId, Role role) {
        List<ClassMember> memberListValue = memberList.getValue();
        if (memberListValue != null) {
            for (ClassMember member : memberListValue) {
                if (member.getUserId().equals(userId)) {
                    member.setRole(role.getValue());
                    memberList.postValue(memberListValue);
                    break;
                }
            }
        }
    }


    //排序
    private List<ClassMember> sortClassMember(List<ClassMember> members) {
        // 自己永远在第一个， 然后是助教讲师，学员， 旁听， 学员和旁听是按照时间顺序排列
        if (members == null || members.size() <= 0) {
            return null;
        }
        List<ClassMember> sortList = new ArrayList<>();
        List<ClassMember> students = new ArrayList<>();
        List<ClassMember> listeners = new ArrayList<>();
        UserInfo user = userInfo.getValue();
        for (ClassMember member : members) {
            if (user.getUserId().equals(member.getUserId())) {
                member.setUserName("我");
                sortList.add(0, member);
            }  else if (member.getRole() == Role.LECTURER) {
                sortList.add(member);
            } else if (member.getRole() == Role.STUDENT) {
                students.add(member);
            } else if (member.getRole() == Role.LISTENER) {
                listeners.add(member);
            }
        }

        Collections.sort(students, new Comparator<ClassMember>() {
            @Override
            public int compare(ClassMember o1, ClassMember o2) {
                long l = o1.getJoinTime() - o2.getJoinTime();
                int i = l > 0 ? 1 : l < 0 ? -1 : 0;
                return i;
            }
        });

        Collections.sort(listeners, new Comparator<ClassMember>() {
            @Override
            public int compare(ClassMember o1, ClassMember o2) {
                long l = o1.getJoinTime() - o2.getJoinTime();
                int i = l > 0 ? 1 : l < 0 ? -1 : 0;
                return i;
            }
        });

        sortList.addAll(students);
        sortList.addAll(listeners);
        //        TODO 学生端只显示自己和老师
        //        Role role = user.getRole();
        //        List<ClassMember> classMembers = new ArrayList<>();
        //        if (role != Role.LECTURER && members.size() > 1) {
        //            for (ClassMember member : sortList) {
        //                if (member.getRole() == Role.LECTURER || user.getUserId().equals(member.getUserId())) {
        //                    classMembers.add(member);
        //                }
        //            }
        //        } else {
        //            classMembers.addAll(sortList);
        //        }

        //        return classMembers;
        return sortList;
    }


    /**
     * 更新课堂成员设备状态
     *
     * @param userId
     * @param deviceType
     * @param isEnable
     */
    private void updateDeviceState(String userId, DeviceType deviceType,
                                   boolean isEnable, String musicScoreAccompanimentId) {

        //此处应优化为只更新可发言的用户
        List<ClassMember> memberListValue = memberList.getValue();
        UserInfo info = userInfo.getValue();
        if (info.getUserId().equals(userId)) {
            // 相同的话就不要提示了
            boolean isNotify = false; // 如果提前值变了， 那说明是自己手动禁止的
            switch (deviceType) {
                case Camera:
                    if (info.isCamera() != isEnable) {
                        info.setCamera(isEnable);
                        isNotify = true;
                    }
                    break;
                case Microphone:
                    if (info.isMicrophone() != isEnable) {
                        info.setMicrophone(isEnable);
                        isNotify = true;
                    }
                    break;
                case musicMode:
                    if (info.isMusicMode() != isEnable) {
                        info.setMusicMode(isEnable);
                        isNotify = true;
                    }
                    break;
                case handUpOn:
                    if (info.isHandUpOn() != isEnable) {
                        info.setHandUpOn(isEnable);
                        isNotify = true;
                    }
                    break;
                case MusicScore:
                    if (info != null) {
                        if (!isEnable) {
                            playExamSong.postValue(new ClassMember.ScheduleStudentMusicScoresBean(0, 0));
                            break;
                        }

                        List<ClassMember.ScheduleStudentMusicScoresBean> musicScoresBeans = info.getScheduleStudentMusicScores();
                        if (null == musicScoresBeans && musicScoreAccompanimentId != null) {
                            break;
                        }
                        for (ClassMember.ScheduleStudentMusicScoresBean bean : musicScoresBeans) {
                            if (musicScoreAccompanimentId.equals(bean.getMusicScoreAccompanimentId()) && isEnable) {
                                bean.setPlayStatus(1);
                                bean.setAccompanimentPlayStatus(0);
                                playExamSong.postValue(bean);
                                break;
                            } else {
                                bean.setPlayStatus(0);
                                bean.setAccompanimentPlayStatus(0);
                            }
                        }
                    }
                    break;

                case MusicScoreAccompaniment:
                    if (info != null) {
                        if (!isEnable) {
                            playExamSong.postValue(new ClassMember.ScheduleStudentMusicScoresBean(0, 0));
                            break;
                        }
                        List<ClassMember.ScheduleStudentMusicScoresBean> musicBeans = info.getScheduleStudentMusicScores();
                        if (null == musicBeans && musicScoreAccompanimentId != null) {
                            break;
                        }
                        for (ClassMember.ScheduleStudentMusicScoresBean bean : musicBeans) {
                            if (musicScoreAccompanimentId.equals(bean.getMusicScoreAccompanimentId()) && isEnable) {
                                bean.setPlayStatus(0);
                                bean.setAccompanimentPlayStatus(1);
                                playExamSong.postValue(bean);
                                break;
                            } else {
                                bean.setPlayStatus(0);
                                bean.setAccompanimentPlayStatus(0);
                            }
                        }
                    }
                    break;
            }

            if (isNotify) {
                userInfo.postValue(info);
                // 自己的设备被停用时提醒
                if (!isEnable) {
                    onDisableDevice.postValue(deviceType);
                }
            }
        }


        if (memberListValue != null) {
            for (ClassMember member : memberListValue) {
                if (member.getUserId().equals(userId)) {
                    switch (deviceType) {
                        case Camera:
                            member.setCamera(isEnable);
                            // 如果当前的用户是助教或者讲师， 则需要判断一下关闭设备的人
                            // 假如关闭设备的人是正是在共享区域显示的人， 则需要本地显示null，提示可以创建白板
                            ScreenDisplay value = display.getValue();
                            String displayUserId = value.getUserId();
                            if (value != null && userId.equals(displayUserId)) {
                                if (!isEnable && (value.getType() == ScreenDisplay.Display.LECTURER  ||
                                        (info.getRole() != Role.LECTURER && value.getType() == ScreenDisplay.Display.STUDENT))) {
                                    value.setType(ScreenDisplay.Display.NONE);
                                    display.postValue(value);
                                } else if (isEnable && value.getType() == ScreenDisplay.Display.NONE && value.getClassMember() != null) {
                                    ClassMember classMember = value.getClassMember();
                                    if (classMember.getRole() == Role.LECTURER) {
                                        value.setType(ScreenDisplay.Display.LECTURER);
                                    } else if (classMember.getRole() == Role.STUDENT) {
                                        value.setType(ScreenDisplay.Display.STUDENT);
                                    }
                                    display.postValue(value);
                                }
                            }
                            isUserListRefreshData = false;
                            break;
                        case Microphone:
                            member.setMicrophone(isEnable);
                            isUserListRefreshData = true;
                            break;
                        case musicMode:
                            member.setMusicMode(isEnable);
                            break;
                        case handUpOn:
                            member.setHandUpOn(isEnable);
                            break;
                        case MusicScore:
                            if (member != null && member.getScheduleStudentMusicScores() != null) {
                                List<ClassMember.ScheduleStudentMusicScoresBean> musicScoresBeans = member.getScheduleStudentMusicScores();
                                for (ClassMember.ScheduleStudentMusicScoresBean bean : musicScoresBeans) {
                                    bean.setAccompanimentPlayStatus(0);
                                    if (isEnable && bean.getMusicScoreAccompanimentId().equals(musicScoreAccompanimentId)) {
                                        bean.setPlayStatus(1);
                                    } else {
                                        bean.setPlayStatus(0);
                                    }
                                }

                            }
                            break;
                        case MusicScoreAccompaniment:
                            if (member != null && member.getScheduleStudentMusicScores() != null) {
                                List<ClassMember.ScheduleStudentMusicScoresBean> musicBeans = member.getScheduleStudentMusicScores();
                                for (ClassMember.ScheduleStudentMusicScoresBean bean : musicBeans) {
                                    bean.setPlayStatus(0);

                                    if (isEnable && bean.getMusicScoreAccompanimentId().equals(musicScoreAccompanimentId)) {
                                        bean.setAccompanimentPlayStatus(1);
                                    } else {
                                        bean.setAccompanimentPlayStatus(0);
                                    }
                                }
                            }
                            break;
                    }
                    isUserListNoUpdate = true;
                    //                    if (deviceType == DeviceType.Camera || deviceType == DeviceType.handUpOn) {
                    memberList.postValue(memberListValue);
                    //                    }
                }
            }
        }
        // 设备变化通知
        deviceChange.postValue(new DeviceChange(userId, deviceType, isEnable));
    }

    /**
     * 添加白板，若有重复则不进行添加
     *
     * @param whiteBoard
     */
    private void addWhiteBoard(WhiteBoard whiteBoard) {
        List<WhiteBoard> whiteBoardListValue = whiteBoardList.getValue();
        if (whiteBoardListValue != null) {
            boolean isAdded = false;
            for (WhiteBoard board : whiteBoardListValue) {
                if (board.getWhiteboardId().equals(whiteBoard.getWhiteboardId())) {
                    isAdded = true;
                    break;
                }
            }

            if (!isAdded) {
                whiteBoardListValue.add(whiteBoard);
                whiteBoardList.postValue(whiteBoardListValue);
            }
        } else {
            whiteBoardListValue = new ArrayList<>();
            whiteBoardListValue.add(whiteBoard);
            whiteBoardList.postValue(whiteBoardListValue);
        }
    }

    /**
     * 删除白板
     *
     * @param whiteBoard
     */
    private void deleteWhiteBoard(WhiteBoard whiteBoard) {
        List<WhiteBoard> whiteBoardListValue = whiteBoardList.getValue();
        if (whiteBoardListValue != null) {
            WhiteBoard removeBoard = null;
            for (WhiteBoard board : whiteBoardListValue) {
                if (board.getWhiteboardId().equals(whiteBoard.getWhiteboardId())) {
                    removeBoard = board;
                    break;
                }
            }

            if (removeBoard != null) {
                whiteBoardListValue.remove(removeBoard);
                whiteBoardList.postValue(whiteBoardListValue);
            }
        }
    }

    /**
     * 从成员列表中差出特定的角色，并刷新
     */
    private void findAndUpdateSpecialRole() {
        List<ClassMember> list = memberList.getValue();
        if (list != null && list.size() > 0) {
            for (ClassMember member : list) {
                tryToUpdateSpecialRole(member);
            }
        }
    }

    /**
     * 刷新特定的角色信息，用于单独刷新该角色触发刷新
     *
     * @param member
     */
    private void tryToUpdateSpecialRole(ClassMember member) {
        Role role = member.getRole();

        if (role == Role.LECTURER) {
            ClassMember lecturer = lecturerRole.getValue();
            if (lecturer == null
                    || !lecturer.getUserId().equals(member.getUserId())) {
                lecturerRole.postValue(member);
            }
        }
    }


    /**
     * 按加入时间顺序排序成员列表
     *
     * @param list
     */
    private void sortClassMemberListByJoinTimeASC(List<ClassMember> list) {
        Collections.sort(list, new Comparator<ClassMember>() {
            @Override
            public int compare(ClassMember member1, ClassMember member2) {
                return (int) (member1.getJoinTime() - member2.getJoinTime());
            }
        });
    }


    public ScreenDisplay getDisplayWithClassMember(ScreenDisplay screenDisplay) {
        if (!TextUtils.isEmpty(screenDisplay.getUserId())) {
            List<ClassMember> value = memberList.getValue();
            if (value != null && value.size() > 0) {
                for (ClassMember member : value) {
                    if (screenDisplay.getUserId().equals(member.getUserId())) {
                        screenDisplay.setClassMember(member);
                        break;
                    }
                }
            }
        }

        if (!TextUtils.isEmpty(screenDisplay.getUserId()) && screenDisplay.getClassMember() == null) {
            ClassMember classMember = new ClassMember();
            classMember.setUserId(screenDisplay.getUserId());
             if (screenDisplay.getType() == ScreenDisplay.Display.LECTURER) {
                classMember.setRole(Role.LECTURER.getValue());
            }
            screenDisplay.setClassMember(classMember);
        }

        return screenDisplay;
    }

    public LiveData<RequestState> joinRtcRoom(String roomId) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        RtcManager.getInstance().joinRtcRoom(roomId, new ResultCallback<String>() {
            @Override
            public void onSuccess(String roomId) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });
        return stateLiveData;
    }

    public LiveData<RequestState> quitRtcRoom(String roomId) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.quitRtcRoom(roomId, new ResultCallback<String>() {
            @Override
            public void onSuccess(String roomId) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });
        return stateLiveData;

    }

    public LiveData<RequestState> startRtcChat(RCRTCVideoView view) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.startRtcChat(view, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean aBoolean) {
                stateLiveData.success();
                localUserStartVideoChat.postValue(true);
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
                localUserStartVideoChat.postValue(false);
            }
        });
        return stateLiveData;
    }

    public LiveData<RequestState> stopRtcChat() {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.stopRtcChat(new ResultCallback<Boolean>() {

            @Override
            public void onSuccess(Boolean aBoolean) {
                stateLiveData.success();
                localUserStartVideoChat.postValue(false);

            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });
        return stateLiveData;
    }

    public void setLocalVideoEnable(boolean enable) {
        UserInfo userInfoValue = userInfo.getValue();
        userInfoValue.setCamera(enable);
        userInfo.postValue(userInfoValue);
        classRepository.setLocalVideoEnable(enable);
    }

    public void setLocalMicEnable(boolean enable) {
        UserInfo userInfoValue = userInfo.getValue();
        userInfoValue.setMicrophone(enable);
        userInfo.postValue(userInfoValue);
        RtcManager.getInstance().setLocalMicEnable(enable);
    }

    public void switchCamera() {
        RtcManager.getInstance().switchCamera();

    }

    //注册房间统计信息监听
    public void registerStatusReportListener(IRCRTCStatusReportListener
                                                     statusReportListener) {
        RtcManager.getInstance().registerStatusReportListener(statusReportListener);
    }

    public void setEnableSpeakerphone(boolean enable) {
        RtcManager.getInstance().setEnableSpeakerphone(enable);
    }

    public LiveData<RequestState> muteRoomVoice(boolean mute) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.muteRoomVoice(mute, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean bmete) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });
        return stateLiveData;
    }


    public LiveData<RequestState> subscribeAllResource
            (HashMap<String, RCRTCVideoView> videoViews) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        classRepository.subscribeAllResource(videoViews, new ResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean b) {
                stateLiveData.success();

            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);
            }
        });
        return stateLiveData;
    }

    public LiveData<RequestState> subscribeResource(String userId, RCRTCVideoView
            videoView) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        boolean isSimulcast = false;
        ScreenDisplay display = getDisplay().getValue();
        if (null != display) {
            String screendisplay = display.getUserId();
            if (!TextUtils.isEmpty(screendisplay) && userId.equals(screendisplay)) {
                isSimulcast = true;
            }
        }
        boolean isPlayUserAudio = true;//是否播放音频
        UserInfo user = userInfo.getValue();
        UserInfo.PlayMidiJsonBean playMidiBean = user.getPlayMidiJson();
        ClassMember lecturerMember = lecturerRole.getValue();
        if (Role.STUDENT == user.getRole()) {
            List<ClassMember.ScheduleStudentMusicScoresBean> musicScoresBeans = user.getScheduleStudentMusicScores();
            boolean isPlayMusic = false;//学生判断是否开启伴奏
            if (musicScoresBeans != null && musicScoresBeans.size() > 0) {
                for (ClassMember.ScheduleStudentMusicScoresBean musicScoresBean : musicScoresBeans) {
                    if (musicScoresBean.getPlayStatus() == 1 || musicScoresBean.getAccompanimentPlayStatus() == 1) {
                        isPlayMusic = true;
                        break;
                    }
                }
            }

            boolean userIdIsLecture = false; //判断订阅UserId是否为老师
            if (lecturerMember == null) {
                List<ClassMember> members = memberList.getValue();
                if (members != null) {
                    for (ClassMember member : members) {
                        if (member.getRole() == Role.LECTURER) {
                            userIdIsLecture = userId.equals(member.getUserId());
                            break;
                        }
                    }
                }
            } else {
                userIdIsLecture = userId.equals(lecturerMember.getUserId());
            }

            if (!userIdIsLecture && ((null != playMidiBean && playMidiBean.isEnable()) || isPlayMusic)) {
                isPlayUserAudio = false;
            }
        }

        List<ClassMember> classMembers = memberList.getValue();


        if (Role.LECTURER == user.getRole() && null != classMembers && classMembers.size() >= 2 &&
                (onMetronomeIsPlay || onMusicIsPlay) && !userId.equals(display.getUserId())) {
            isPlayUserAudio = false;
        }

        classRepository.subscribeResource(isPlayUserAudio, isSimulcast, userId, videoView, new ResultCallback<String>() {
            @Override
            public void onSuccess(String b) {
                stateLiveData.success();
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);

            }
        });
        return stateLiveData;
    }

    public LiveData<RequestState> subscribeResource(String userId, RCRTCVideoView
            videoView, RCRTCVideoView screenShareVideo) {
        final StateLiveData stateLiveData = new StateLiveData();
        stateLiveData.loading();
        boolean isSimulcast = false;//大小流切换
        ScreenDisplay display = getDisplay().getValue();
        if (null != display) {
            String screendisplay = display.getUserId();
            if (!TextUtils.isEmpty(screendisplay) && userId.equals(screendisplay)) {
                isSimulcast = true;
            }
        }
        classRepository.subscribeResource(true, isSimulcast, userId, videoView, screenShareVideo, new ResultCallback<String>() {
            @Override
            public void onSuccess(String b) {
                stateLiveData.success();

            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.failed(errorCode);

            }
        });
        return stateLiveData;
    }


    public LiveData<RequestState> unSubscribeResource(String userId) {
        final MutableLiveData<RequestState> stateLiveData = new MutableLiveData<>();
        stateLiveData.postValue(RequestState.loading());
        classRepository.unSubscribeResource(userId, new ResultCallback<String>() {
            @Override
            public void onSuccess(String b) {
                stateLiveData.postValue(RequestState.success());

            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.postValue(RequestState.failed(errorCode));

            }
        });
        return stateLiveData;
    }


    public LiveData<RequestState> subscribeVideo(String userId, RCRTCVideoView
            videoView) {
        final MutableLiveData<RequestState> stateLiveData = new MutableLiveData<>();
        stateLiveData.postValue(RequestState.loading());
        classRepository.subscribeVideo(userId, videoView, new ResultCallback<String>() {
            @Override
            public void onSuccess(String b) {
                stateLiveData.postValue(RequestState.success());

            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.postValue(RequestState.failed(errorCode));

            }
        });
        return stateLiveData;
    }

    public LiveData<RequestState> unSubscribeVideo(String userId) {
        final MutableLiveData<RequestState> stateLiveData = new MutableLiveData<>();
        stateLiveData.postValue(RequestState.loading());
        classRepository.unSubscribeVideo(userId, new ResultCallback<String>() {
            @Override
            public void onSuccess(String b) {
                stateLiveData.postValue(RequestState.success());

            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.postValue(RequestState.failed(errorCode));

            }
        });
        return stateLiveData;
    }

    public LiveData<RequestState> subscribeAudio(String userId) {
        final MutableLiveData<RequestState> stateLiveData = new MutableLiveData<>();
        stateLiveData.postValue(RequestState.loading());
        classRepository.subscribeAudio(userId, new ResultCallback<String>() {
            @Override
            public void onSuccess(String b) {
                stateLiveData.postValue(RequestState.success());

            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.postValue(RequestState.failed(errorCode));

            }
        });
        return stateLiveData;
    }

    public LiveData<RequestState> unSubscribeAudio(String userId) {
        final MutableLiveData<RequestState> stateLiveData = new MutableLiveData<>();
        stateLiveData.postValue(RequestState.loading());
        classRepository.unSubscribeAudio(userId, new ResultCallback<String>() {
            @Override
            public void onSuccess(String b) {
                stateLiveData.postValue(RequestState.success());
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.postValue(RequestState.failed(errorCode));

            }
        });
        return stateLiveData;
    }

    public void enableRTCAVInputStream(String userId, boolean isEnable) {
        classRepository.enableRTCAVInputStream(userId, isEnable);
    }


    public LiveData<RequestState> subscribeScreen(String userId, RCRTCVideoView
            videoView) {
        final MutableLiveData<RequestState> stateLiveData = new MutableLiveData<>();
        stateLiveData.postValue(RequestState.loading());
        classRepository.subscribeScreen(userId, videoView, new ResultCallback<String>() {
            @Override
            public void onSuccess(String s) {
                stateLiveData.postValue(RequestState.success());
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.postValue(RequestState.failed(errorCode));
            }
        });
        return stateLiveData;
    }

    public LiveData<RequestState> unSubscribeScreen(String userId) {
        final MutableLiveData<RequestState> stateLiveData = new MutableLiveData<>();
        stateLiveData.postValue(RequestState.loading());
        classRepository.unSubscribeScreen(userId, new ResultCallback<String>() {
            @Override
            public void onSuccess(String s) {
                stateLiveData.postValue(RequestState.success());
            }

            @Override
            public void onFail(int errorCode, String errorStr) {
                stateLiveData.postValue(RequestState.failed(errorCode));
            }
        });
        return stateLiveData;
    }

    OnClassVideoEventListener onClassVideoEventListener = new OnClassVideoEventListener() {

        @Override
        public void onInitVideoList(List<StreamResource> resources) {
            SLog.d("ss_rtcuser", "onInitVideoList==>" + resources);
            //            UserInfo user = userInfo.getValue();
            //            //            TODO 学生端只显示自己和老师
            //            Role role = user.getRole();
            List<StreamResource> lecturerList = new ArrayList<>();
            //            if (role != Role.LECTURER) {
            //                String lecturerId = null;
            //                List<ClassMember> members = memberList.getValue();
            //                for (ClassMember member : members) {
            //                    if (member.getRole() == Role.LECTURER) {
            //                        lecturerId = member.getUserId();
            //                    }
            //                }
            //                if (TextUtils.isEmpty(lecturerId)) {
            //                    return;
            //                }
            //                for (StreamResource resource : resources) {
            //                    if (resource.userId.equals(lecturerId)) {
            //                        lecturerList.add(resource);
            //                    }
            //                }
            //            } else {
            lecturerList.addAll(resources);
            //            }
            if (lecturerList != null && lecturerList.size() > 0) {
                initUserVideoList.postValue(lecturerList);
            }
        }

        @Override
        public void onAddVideoUser(StreamResource resource) {
            //            TODO 学生端只显示自己和老师
            //            Role role = userInfo.getValue().getRole();
            //            String lecturerId = null;
            //            List<ClassMember> members = memberList.getValue();
            //            for (ClassMember member : members) {
            //                if (member.getRole() == Role.LECTURER) {
            //                    lecturerId = member.getUserId();
            //                }
            //            }
            //            if (TextUtils.isEmpty(lecturerId)) {
            //                return;
            //            }
            //            if (role == Role.LECTURER || (!TextUtils.isEmpty(lecturerId) && resource.userId.equals(lecturerId))) {
            addVideoUser.postValue(resource);
            //            }
        }

        @Override
        public void onRemoveVideoUser(StreamResource resource) {
            removeVideoUser.postValue(resource);
        }

        @Override
        public void onFirstFrameDraw(String userId, String tag) {
            FirstFrameUserInfo info = new FirstFrameUserInfo();
            info.setUserId(userId);
            info.setTag(tag);
            fisrtFrameDraw.postValue(info);
        }

        @Override
        public void onVideoEnabled(String userId, boolean enable) {
            //            String lecturerId = null;
            //            for (ClassMember member : memberList.getValue()) {
            //                if (member.getRole() == Role.LECTURER) {
            //                    lecturerId = member.getUserId();
            //                    break;
            //                }
            //            }
            //            if (userId.equals(lecturerId)) {
            //                ScreenDisplay value = display.getValue();
            //                if (enable&&!value.getUserId().equals(userId)) {
            //                    value.setType(ScreenDisplay.Display.LECTURER);
            //                } else {
            //                    value.setType(ScreenDisplay.Display.NONE);
            //                }
            //
            //                display.postValue(value);
            //            }
        }
    };

    private ClassMember getVideoClassMember(String userId) {
        ClassMember member = null;
        List<ClassMember> value = memberList.getValue();
        for (int j = 0; j < value.size(); j++) {
            if (userId.equals(value.get(j).getUserId())) {
                member = value.get(j);
                break;
            }
        }
        return member;
    }

    private List<ClassMember> getVideoClassMember(List<String> userIds) {
        List<ClassMember> tmpList = new ArrayList<>();
        List<ClassMember> value = memberList.getValue();

        if (userIds != null && value != null) {
            for (int i = 0; i < userIds.size(); i++) {
                for (int j = 0; j < value.size(); j++) {
                    if (userIds.get(i).equals(value.get(j).getUserId())) {
                        tmpList.add(value.get(j));
                        break;
                    }
                }
            }
        }
        return tmpList;
    }

    /**
     * 订阅大流
     */
    public void exchangeStreamToNormalStream(String userid) {
        RtcManager.getInstance().exchangeStreamToNormalStream(userid);
    }

    /**
     * 订阅小流
     */
    public void exchangeStreamToTinyStream(String userid) {
        RtcManager.getInstance().exchangeStreamToTinyStream(userid);
    }

    @Override
    public void onCleared() {
        super.onCleared();
        if (classRepository != null && onClassEventListener != null) {
            classRepository.removeOnClassEventListener(onClassEventListener);
        }
        if (countPassTimeTimer != null) {
            countPassTimeTimer.cancel();
        }
    }
}
