const saas = require(path.join(__dirname, '../js/module', 'saas.js'))
const heartbeat = require(path.join(__dirname, '../js/module', 'heartbeat.js'))
const { dialog, clipboard } = require('electron').remote


let class_app = new Vue({
    el: '#class_app',
    mounted: function () {
        this.onWindowLoad();
    },
    data: {
        /** 机构信息 */
        app_name: '',
        app_icon_url: '',
        client_version: '',
        /** 弹窗信息 */
        is_loading: true,
        is_show_msg: false,
        is_show_dialog: false,
        dialog_title: '',
        dialog_msg: '',
        dialog_button: [],
        dialog_allow_close: true,
        dialog_callback: 0,
        is_dialog_input: false,
        dialog_tip: '问题反馈',
        dialog_input_msg: '',
        is_show_menu: false,
        /** 状态信息 */
        info_head: '',
        info_delay: "0ms",
        info_drop: "0%",
        info_cpu: "0%",
        info_net: '优良',
        info_time: '',
        platform: '',
        /** 成员信息 */
        memberMap: {},
        /** 课堂信息 */
        user_id: '',
        teacher_id: '',
        assistant_id: '',
        up_user_id: '',
        user_icon: '',
        is_class_started: false,
        class_status: '上课',
        class_type: '',
        live_type: 'close',
        live_url: '',
        tick_timer: null,
        question_id: 0,
        layout: 2,
        video_type: 'trtc',
        show_stu_count: 0,
        /** 状态信息 */
        is_full_mode: false,
        is_first_exit: true,
        is_record: false,
        is_share_screen: false,
        is_play_video: false,
        is_mute_all: false,
        has_new_hand_up: false,
        has_sub_stream: false,
        has_screen_share: false,
        is_uploading: false,
        is_window_max: false,
        /** 聊天数据 */
        input_msg: '',
        messageArr: [],
        checkin_dlg: false,
        /** 录制状态 */
        first_click_time: 0,
        env_click_count: 0,
        debug_mode: false,
        upload_percent: 0,
        task_list: []
    },
    created: function () {

    },
    methods: {
        /** 窗口事件 */
        onWindowLoad: function () {
            log.info("[TAG-CLASS] onWindowLoad->app_name: " + this.app_name);
            this.client_version = this.getVersion();
            this.platform = process.platform;
            saas.setDebugMode(g_data.test);
            saas.syncInfo(g_data.companyId, g_data.classId, g_data.userId, g_data.userToken, (ret, json) => {
                if (!ret) {
                    this.showErrorMessage("" + json, true);
                    return;
                }
                log.info('[TAG-CLASS] syncInfo->rsp: ' + JSON.stringify(json));
                g_data.sdkAppId = saas.sdkAppId;
                g_data.appName = saas.appName;
                g_data.appIconUrl = saas.iconUrl;
                g_data.token = saas.token;
                g_data.userSig = saas.userSig;
                g_data.classInfo = json;

                g_storage.setItem('mode', g_data.mode);
                g_storage.setItem('companyId', g_data.companyId);
                g_storage.setItem('appName', json.name);
                g_storage.setItem('appIconUrl', json.icon);
                g_storage.setItem('userId', g_data.userId);
                g_storage.setItem('userToken', g_data.userToken);
                g_storage.setItem('classId', g_data.classId);

                this.app_name = g_data.appName;
                this.app_icon_url = g_data.appIconUrl;
                this.info_head = '' + g_data.classId;
                document.title = this.app_name;

                this.class_type = json.class_type;
                this.live_type = json.class_live_type;
                this.user_id = g_data.userId;
                this.teacher_id = json.teacher_id;

                this.video_type = json.class_video_type;
                this.layout = json.settings.layout;

                if (json.class_status == 'ing') {
                    this.is_class_started = true;
                    this.startClassTick();
                }

                this.addMember(this.user_id, false);
                this.addMember(this.teacher_id);
                this.memberMap[this.teacher_id].camera_auth = true;
                this.memberMap[this.teacher_id].mic_auth = true;
                if (json.assistant_id) {
                    this.assistant_id = json.assistant_id;
                    this.addMember(this.assistant_id, false);
                }

                this.joinClass();
            });
        },
        onWindowResume: function () {
            this.is_show_dialog = false;
            saas.enableCustomRender(false, onLocalVideoDataRender);
        },
        onWindowMax: function () {
            this.is_window_max = true;
            this.updateViewSize();
        },
        onWindowUnMax: function () {
            this.is_window_max = false;
            this.updateViewSize();
        },
        closeWindow: function () {
            log.info("[TAG-CLASS] closeWindow->enter with first: "+this.is_first_exit);
            if (this.is_first_exit) {
                this.showDialog((this.is_uploading?"当前录制文件上传尚未完成，":"")+'是否确定退出课堂', ['是', '否'], (index) => {
                    if (index == 0) {
                        this.is_first_exit = false;
                        if (this.is_record){
                            saas.stopRecord();
                            this.is_record = false;
                        }                 
                        saas.exitClass((ret, json) => {
                            if (!g_data.component && g_data.mode=='saas' && !g_data.guest)
                                sendIpcMessage('WIN_LOGIN:OPEN', {});
                                //sendIpcMessage('WIN_CLASSLIST:OPEN', {});
                            log.transports.file.flush()
                            sendIpcMessage('WIN_CLASS:CLOSE');
                        })
                    }
                })
            } else {
                sendIpcMessage('ComWin:Sys', 'close');
            }
        },
        minWindow: function () {
            sendIpcMessage('ComWin:Sys', 'min');
        },
        maxWindow: function () {
            sendIpcMessage('ComWin:Sys', 'max');
        },
        openClassDocDlg: function () {
            sendIpcMessage('WIN_DOCLIST:OPEN', g_data.classId);
            this.is_show_dialog = true;
        },
        openMemberDlg: function () {
            this.has_new_hand_up = false;
            sendIpcMessage('WIN_MEMBER:OPEN', this.getVideoMemberCount());
            this.is_show_dialog = true;
        },
        openCtrlDlg: function () {
            this.is_show_menu = true;
        },
        openToolDlg: function () {
            sendIpcMessage('WIN_TOOL:OPEN', 0, false);
            this.is_show_dialog = true;
        },
        openSettingDlg: function () {
            g_data.speakerVolume = saas.getSpeakerVolume();
            sendIpcMessage('WIN_SET:OPEN', g_data.classId, true);
            saas.enableCustomRender(true, onLocalVideoDataRender);//打开的
            this.is_show_dialog = true;
        },
        showLiveInfo: function () {
            //var playAddr = calcPlayAddr(true);
            var playAddr = saas.classInfo.live_url;
            this.showDialogEx('复制以下链接发送给学员，对方就能收看您的课程啦!', '直播课地址: ' + playAddr, ['复制链接', '关闭'], (index) => {
                if (index == 0) {
                    clipboard.writeText(playAddr);
                }
            })
        },
        changeFullMode: function () {
            this.is_full_mode = !this.is_full_mode;
            this.$nextTick(() => {
                if (this.video_type == 'live' && g_data.classInfo.class_status == 'ing') {
                    this.startLivePush();
                }
            })
        },
        setDebug: function(){
            var clickTime = new Date().getTime();
            if (clickTime - this.first_click_time > 1000){
                this.first_click_time = clickTime;
                this.env_click_count = 0;
            }else{
                this.env_click_count ++;
                if (this.env_click_count > 4){
                    this.env_click_count = 0;
                    this.debug_mode = !this.debug_mode;
                    log.info("[TAG-CLASS] setDebug->debug: "+this.debug_mode);
                }                
            }            
        },

        /** 布局方法 */
        isTeacher: function () {
            return this.user_id == this.teacher_id;
        },
        isAssistant: function () {
            return this.user_id == this.assistant_id;
        },
        getShowTopic: function(){
            if ((saas.classInfo.class_topic && saas.classInfo.class_topic.length<10)||this.is_window_max){
                return saas.classInfo.class_topic;
            }else{
                return saas.classInfo.class_topic.substring(0, 8)+"...";
            }
        },
        getVersion: function () {
            var package = require("../package.json");
            log.info("[TAG-CLASS] getVersion->" + package.version + "." + g_data.minVer);
            return "互动课堂 桌面版v" + package.version + "." + g_data.minVer;
        },
        showVersion: function () {
            this.showDialogEx('问题反馈', '当前版本信息  ' + this.getVersion(), ['确定'], (index) => {
                if (0 == index) {
                    log.info("[TAG-FEEDBACK] message->" + this.dialog_input_msg);
                }
                this.dialog_input_msg = "";
            }, true);
        },
        scrollLeft: function (pos) {
            document.getElementsByClassName("tic-tab__list")[0].scrollLeft += pos;
        },
        handsUp: function () {
            this.memberMap[this.user_id].hand_up = !this.memberMap[this.user_id].hand_up;
            saas.reportEvent(this.memberMap[this.user_id].hand_up ? 'hand_up' : 'hand_down');
        },
        ctlSwitchCamera: function (id) {
            if (id == this.user_id) {
                this.enableCamera(!this.memberMap[this.user_id].camera, false);
            } else {
                //Vue.set(this.memberMap[id], 'camera', !this.memberMap[id].camera)
                //saas.enableMemberRight(id, 'camera', this.memberMap[id].camera);
            }
        },
        ctlSwitchMic: function (id) {
            if (id == this.user_id) {
                this.enableMic(!this.memberMap[this.user_id].mic, false);
            } else {
                //Vue.set(this.memberMap[id], 'mic', !this.memberMap[id].mic)
                //saas.enableMemberRight(id, 'mic', this.memberMap[id].mic);
            }
        },
        changeChatStatus: function () {
            this.is_mute_all = !this.is_mute_all;
            saas.slienceAll(this.is_mute_all);
            //this.addSystemMessage(new Date(), "您已" + (this.is_mute_all ? "开启" : "关闭") + "全体禁言");
        },
        changeShareStatus: function () {
            if (this.is_share_screen) {
                this.showDialog('是否关闭屏幕分享', ['是', '否'], (index) => {
                    if (0 == index) {
                        saas.stopShareScreen();
                        this.is_share_screen = false;
                        this.addSystemMessage(new Date(), "您已关闭全屏分享");
                    }
                })
            } else {
                if (this.is_play_video) {
                    this.showAlertMessage('请先关闭播片功能!');
                    return;
                }
                saas.shareScreen();
                this.is_share_screen = true;
                this.addSystemMessage(new Date(), "您已开启全屏分享");
            }
        },

        /** 内部方法 */
        joinClass: function () {
            log.info("[TAG-CLASS] joinClass->enter");
            saas.init(g_data.test);
            saas.setUserEvent(this.onUserEvent);
            saas.setClassEvent(this.onClassEvent);
            saas.setErrorEvent(this.onErrorEvent);
            saas.setUserVideoData(this.onVideoDataEvent);
            saas.setRecvMsgListener(this.onRecvMsg);
            saas.setStatisticsListener((upLoss, downLoss, appCpu, systemCpu, rtt, recvBytes, sentBytes) => {
                this.info_delay = rtt + "ms";
                this.info_drop = upLoss + "%";
                this.info_cpu = systemCpu + "%";
            });

            saas.joinClass(g_data.classId, g_data.classToken, (json, elapse) => {
                log.info("[TAG-CLASS] joinClass->elapse: " + elapse);
                this.is_loading = false;
                g_data.role = json.role;
                this.info_time = this.getShowTopic();
                this.live_url = json.live_url;
                this.is_mute_all = saas.classInfo.settings.enable_all_silence;
                this.updateAuthList(json.member_permission_list);

                saas.setLocalViewMirror(g_data.mirror);
                if (this.isTeacher()) {
                    // 启动录制子进程
                    sendIpcMessage('MAIN:EXEC', path.join(__dirname, '../tools/record', 'TXCloudRecord.exe'))
                    if (this.video_type != 'live') {   // 非大型直播课直接打开摄像头
                        this.enableCamera(true);
                    }
                    this.enableMic(true);
                    this.$nextTick(() => {
                        if (this.video_type == 'live' && g_data.classInfo.class_status == 'ing') {
                            this.startLivePush();
                        }
                    })
                }  else {
                    if (g_data.mode=='demo'){
                        setTimeout(()=>{
                            this.addSystemMessage(new Date(), "课堂已存在，直接加入课堂");
                        }, 300); 
                    }
                    if (this.isAssistant()){
                        sendIpcMessage('MAIN:EXEC', path.join(__dirname, '../tools/record', 'TXCloudRecord.exe'))
                    }
                    var chat_status = -1 != json.history_silence ? json.history_silence : 0
                    saas.enableChat(chat_status ? false : true);
                }
                g_data.speakerVolume = saas.getSpeakerVolume();
                /** 初始化内容大屏 */
                if (this.video_type == 'live' && !this.isTeacher()) {  // 大型直播课非老师端观看快直播
                    var urls = saas.classInfo.live_url.split('/');
                    var domain = urls[2];
                    var app = urls[3];
                    var streamid = urls[4].split('?')[0];
                    var webrtc_url = "webrtc://" + domain + "/" + app + "/" + streamid;
                    var play_url = "https://test.tedu.qcloudtrtc.com/player/#/" + webrtc_url;
                    saas.initWebRtcFrame(document.getElementById('board_iframe'), play_url);
                } else {
                    saas.initContentBoard(document.getElementById('board_iframe'));
                }
                if (saas.classInfo.current_question_id != 0) {   // 当前有答题卡
                    if (this.isTeacher()) {
                        saas.cancelQuestion(saas.classInfo.current_question_id);
                        g_data.curQuestionId = 0;
                        g_data.curTickCount = 0;
                    } else if (!this.isAssistant()) {
                        this.loadQuestion(saas.classInfo.current_question_id);
                    }                    
                }

                // 聊天添加回车支持
                this.$nextTick(()=>{
                    var dom = document.getElementById("chatroom-input");
                    if (dom){
                        log.info("[TAG-CLASS] onWindowLoad->add enter key event");
                        dom.addEventListener('keyup', (event)=>{
                            if (event.keyCode == 13){
                                this.onSendClick();
                            }
                        })
                    }


                    if (saas.classInfo.current_check_in_id != "") { //正在签到
                        if(this.isTeacher()){
                            g_data.is_checkin_ing=true;
                            sendIpcMessage('WIN_CHECKIN_DLG:OPEN', 0);
                        }else if (!this.isAssistant()){
                            saas.updateStudentCheckin(g_data.classId, saas.classInfo.current_check_in_id, g_data.userId, (ret, json) => {

                                if (ret == true) {
                                    if(json.error_code==0){
                                        this.showDialogEx('签到本', '教室发起了课堂签到，请点击下方按钮确认签到  ', ['点击签到'], (index) => {
                                            if (0 == index) {
                                                saas.reportEvent("check_in", {
                                                    check_id:  saas.classInfo.current_check_in_id,
                                                    "user_id": g_data.userId
                                                })
                                            }
                                            this.dialog_input_msg = "";
                                        }, false, false);
                                    }
              
                                }
                            })
                        }     
                    }
                })
            });
            saas.getUserInfo(this.user_id, (ret, json)=>{
                var nickname = (json.nickname && json.nickname.length>0) ? json.nickname : this.user_id;
                this.user_icon = (json.avatar && json.avatar.length>0) ? json.avatar : 'https://main.qcloudimg.com/raw/45e1cd2f9378299a093a6ffa3bb8b9fb.svg'
                Vue.set(this.memberMap[this.user_id], 'nick', nickname);
            })
            saas.getUserNickName(this.user_id, (nick) => {
                Vue.set(this.memberMap[this.user_id], 'nick', nick);
            });
            if (!this.isTeacher()) {
                saas.getUserNickName(this.teacher_id, (nick) => {
                    Vue.set(this.memberMap[this.teacher_id], 'nick', nick);
                })
            }
            // 启动心跳
            this.startClassHeartbeat();
            // 监听录制状态回调
            saas.setRecordStateListener((ret, json)=>{
                if (ret){
                    this.task_list = [];
                    var completed = 0;
                    var total = 0;
                    if (json.Record){
                        this.task_list.push(json.Record.State+":"+json.Record.Duration+"s");
                        total += json.Record.Duration;
                    }
                    if (json.Upload){
                        this.is_uploading = true;                        
                        for (var i=0; i<json.Upload.length; i++){
                            this.task_list.push(json.Upload[i].State+"-"+i+":"+json.Upload[i].Duration+"/"+(json.Upload[i].Total!=0 ? json.Upload[i].Total : "-"));
                            total += json.Upload[i].Total;
                            completed += json.Upload[i].Duration;
                        }
                        this.upload_percent = total!=0 ? Math.floor(completed * 100 / total) : 0;
                    }else{
                        this.is_uploading = false;
                    }
                }else{
                    log.error("[TAG-CLASS] recordStateListener->error:"+json);
                    if (this.is_record){
                        this.addSystemMessage(new Date(), "本地录制异常中断");
                    }
                    this.is_uploading = false;
                    this.is_record = false;
                    saas.recordInit = false;
                    sendIpcMessage('MAIN:EXEC', path.join(__dirname, '../tools/record', 'TXCloudRecord.exe'))             
                }
            })
        },
        startClass: function () {
            if (this.is_class_started) {
                this.showDialog("下课后课堂将销毁，无法再次进入，确定下课吗?", ["确定", "取消"], (index)=>{
                    if (index == 0){
                        if (this.is_record){
                            saas.stopRecord();
                            this.is_record = false;
                        } 
                        saas.endClass((ret, json) => {
                            this.showErrorMessage("课堂已结束", true);
                        })
                    }
                })                
            } else {
                saas.startClass((ret, json) => {
                    if (ret) {
                        this.addSystemMessage(new Date(), "开始上课");
                        this.is_class_started = true;                        
                        this.startClassTick();
                        if (this.video_type == 'live') {
                            this.startLivePush();
                        }
                        if (!this.is_record && process.platform != 'darwin'){
                            this.startRecord();
                        }
                    } else {
                        this.showAlertMessage("上课失败: " + json.error_msg);
                    }
                })
            }
        },
        exitClass: function (callback) {
            if (this.tick_timer) {
                clearInterval(this.tick_timer);
                this.tick_timer = null;
            }
            saas.exitClass(callback);
        },
        enableCamera: function (enable, report = true) {
            Vue.set(this.memberMap[this.user_id], 'camera', enable);
            if (this.video_type == 'live'){
                saas.enableCamera(enable, null, report);
            }else{
                this.$nextTick(() => {
                    var renderView = document.getElementById(this.user_id);
                    if (!enable || renderView){
                        saas.enableCamera(enable, renderView, report);
                    }else if(enable){
                        Vue.set(this.memberMap[this.user_id], 'camera', false);
                        this.addSystemMessage(new Date(), "提示 ！ 当前布局展示的视频已达到上限，无法打开摄像头");
                    }
                    //saas.enableCamera(enable, document.getElementById(this.user_id), report);
                    //this.updateVideo();
                })
            }            
        },
        enableMic: function (enable, report = true) {
            Vue.set(this.memberMap[this.user_id], 'mic', enable);
            saas.enableMic(enable, report);
        },
        enableDraw: function(enable, showTips=true){
            saas.enableDraw(enable);
            if (showTips || enable){
                this.addSystemMessage(new Date(), "您已被"+(enable?"":"取消")+"授权操作白板");
            }            
        },
        startLivePush: function () {
            // 开启直播
            if (typeof (this.live_url) == "undefined") {
                log.error("[TAG-CLASS] startLivePush->no live url address");
                return;
            }
            var dpr = window.devicePixelRatio || window.webkitDevicePixelRatio || window.mozDevicePixelRatio || 1;
            var iframe = document.getElementById('board_iframe');
            var package = require("../package.json");
            var name = (process.platform != 'darwin') ? package.name + '.exe' : package.name;
            var push_url = this.live_url;
            //var push_url = "rtmp://29734.livepush.myqcloud.com/live/1000134973?txSecret=aa5462b6fca5b77663a88699fff9f51a&txTime=5DB078FF";
            if (this.video_type == 'live') {
                //saas.shareCrop(saas.appName, iframe.offsetLeft*dpr, (iframe.offsetTop+38)*dpr, iframe.offsetWidth*dpr, iframe.offsetHeight*dpr);
                saas.startPush(name, g_data.class_hwnd, push_url,
                    iframe.offsetLeft * dpr, (iframe.offsetTop + 38) * dpr, iframe.offsetWidth * dpr, iframe.offsetHeight * dpr);
            } else {
                saas.startPush(name, g_data.class_hwnd, push_url, 0, 0, 0, 0);
                //saas.shareCrop(saas.appName, 0, 0, 0, 0);
            }
        },
        showDialogEx: function (title, message, buttons, callback, input = false, allowClose = true) {
            this.dialog_title = title;
            this.dialog_msg = message;
            this.dialog_button = buttons;
            this.dialog_callback = callback;
            this.is_dialog_input = input;
            this.is_show_msg = true;
            this.dialog_allow_close = allowClose;
        },
        showDialog: function (message, buttons, callback) {
            this.showDialogEx(saas.appName, message, buttons, callback);
        },
        showAlertMessage: function (message, callback) {
            this.showDialog(message, ['确定'], callback);
        },
        showErrorMessage: function (message, isBackLogin = false) {
            log.error("[TAG-CLASS] showErrorMessage->" + message+"/"+isBackLogin);
            this.showAlertMessage(message, (index) => {
                if (isBackLogin && !g_data.component) {
                    //if (g_data.mode=='saas'){
                    //    sendIpcMessage('WIN_CLASSLIST:OPEN', {});
                    //}else{
                        sendIpcMessage('WIN_LOGIN:OPEN');
                    //}                    
                    sendIpcMessage('WIN_CLASS:CLOSE');
                } else {
                    sendIpcMessage('QUITAPP');
                }
            });
        },
        addSystemMessage: function (date, message) {
            this.messageArr.push({
                id: "system",
                type: 'system',
                message: "[" + formatTime(date) + "  " + message + "]"
            })
            this.$nextTick(() => {
                var msg_tab = document.getElementsByClassName('tic-player__chatroom-bd')[0];
                if (msg_tab) msg_tab.scrollTop = msg_tab.scrollHeight - 110;
            })
            if (this.layout == 2){
                saas.addSystemMessage(Math.floor(date.getTime()/1000), message);
            }
        },
        sortMember: function (orgMap) {
            var newMap = {};
            var tempArr = [];
            for (item in orgMap) {
                tempArr.push(item);
            }
            for (index in tempArr.sort()) {
                newMap[tempArr[index]] = orgMap[tempArr[index]]
            }
            return newMap;
        },
        addMember: function (userId, show = true) {
            if (this.memberMap[userId] == null) {
                Vue.set(this.memberMap, userId, { nick: '', volume: 0, camera_auth: false, mic_auth: false, camera: false, mic: false, screen: false, talk: false, speaker: true, hand_up: false });
                log.info("[TAG-PUBLIC] addMember->add user: " + userId);
                saas.getUserNickName(userId, (nick) => {
                    Vue.set(this.memberMap[userId], 'nick', nick);
                });
            }
        },
        updateVideo: function () {    // 刷新视频
            for (user in this.memberMap) {
                if (this.memberMap[user].camera) {
                    if (user == this.userId) {
                        saas.enableCamera(true, document.getElementById(user));
                    } else {
                        saas.startRemoteView(user, document.getElementById(user));
                    }
                }
            }
        },
        resetMember: function (userId) {
            if (null != this.memberMap[userId]) {
                this.memberMap[userId].camera = false;
                this.memberMap[userId].screen = false;
                this.memberMap[userId].talk = false;
                this.memberMap[userId].hand_up = false;
                this.memberMap[userId].mic = false;
                this.memberMap[userId].volume = 0;
                this.memberMap[userId].show = false;
            }
        },
        getVideoMemberCount: function () {
            var videoCount = 0;
            for (user in this.memberMap) {
                if (this.memberMap[user].camera || this.memberMap[user].mic || this.memberMap[user].screen || user == this.teacher_id) {
                    videoCount++;
                }
            }
            return videoCount;
        },
        startClassTick: function () {
            g_data.classInfo.class_status = 'ing';  // 更新课堂状态
            this.tick_timer = setInterval((classId) => {
                saas.classInfo.duration_time++;
                var hour = Math.floor(saas.classInfo.duration_time / 3600);
                var min = Math.floor((saas.classInfo.duration_time % 3600) / 60);
                var sec = Math.floor(saas.classInfo.duration_time % 60);
                this.info_time = this.getShowTopic() + " " + (hour <= 9 ? '0' + hour : hour) + ':' + (min <= 9 ? '0' + min : min) + ':' + (sec <= 9 ? '0' + sec : sec);
            }, 1000, this.classId);
        },
        checkHandUp: function () {
            for (user in this.memberMap) {
                if (this.memberMap[user].hand_up) {
                    this.has_new_hand_up = true;
                    return;
                }
            }
            this.has_new_hand_up = false;
        },
        startRecordWindow: function (selectPath) {
            var package = require("../package.json");
            var name = (process.platform != 'darwin') ? package.name + '.exe' : package.name;
            var recordPath = path.join(selectPath, "class_" + g_data.classId + "_" + formatDate(new Date()) + (process.platform != 'darwin' ? ".flv" : ".mp4"));
            log.info("[TAG-CLASS] startRecordWindow->path: " + recordPath);
            saas.startRecord(name, g_data.class_hwnd, recordPath, 0, 0, 0, 0);
            this.is_record = true;
            this.is_show_dialog = false;            
        },
        startRecord: function () {
            var recordDir = path.join((process.platform != 'darwin' ? process.env.USERPROFILE : process.env.HOME), 'TClass', 'record');
            if (!fs.existsSync(recordDir)) {
                fs.mkdir(recordDir, function (err) {
                    if (err) {
                        this.is_show_dialog = true;
                        this.showAlertMessage("创建录制文件目录失败");
                    }
                });
            }
            if (this.is_record == false) {
                this.is_show_dialog = true;
                this.showDialog('是否需要启动本地录制功能并保存(' + recordDir + ')', ['开始录制', '修改保存目录并开始录制', '取消录制'], (index) => {
                    if (index == 0) {
                        this.startRecordWindow(recordDir);
                        this.addSystemMessage(new Date(), "您已开启本地录制");
                    } else if (index == 1) {
                        dialog.showOpenDialog({
                            title: '选择录制文件存放目录',
                            defaultPath: recordDir,
                            properties: ['openDirectory']
                        }, (files) => {
                            if (!files){
                                this.is_show_dialog = false;
                                return;
                            }
                            console.log("[TAG-CLASS] showDialog->files:"+files);
                            this.startRecordWindow(files[0]);
                            this.addSystemMessage(new Date(), "您已开启本地录制");
                        })
                    } else {
                        this.is_show_dialog = false;
                    }

                });
            } else {
                this.is_show_dialog = true;
                this.showDialog('是否停止本地录制功能', ['是', '否'], (index) => {
                    if (index == 0) {
                        saas.stopRecord();
                        this.is_record = false;
                        this.addSystemMessage(new Date(), "您已关闭本地录制");
                    }
                    this.is_show_dialog = false;
                })
            }
        },
        updateViewSize: function () {
            if (this.layout == 2) {
                var nw = document.getElementsByClassName('tic-number__list')[0].clientWidth;
                var nh = document.getElementsByClassName('tic-number__list')[0].clientHeight;
                for (user in this.memberMap) {
                    var vd = document.getElementById(user);
                    if (vd) {
                        vd.style.width = nw + "px";
                        vd.style.height = nh + "px";
                    }
                }
            }
            if (this.class_type == 'live' && saas.classInfo.class_status == 'ing') {
                this.startLivePush();
            }
        },
        updateAuthList: function(list){
            var permission_map = {};
                var last_camera_auth = this.memberMap[this.user_id].camera_auth;
                var last_mic_auth = this.memberMap[this.user_id].mic_auth;
                if (list){
                    this.show_stu_count = list.length;
                    this.up_user_id = list[0].user_id;
                    for (var i=0; i<list.length; i++){
                        permission_map[list[i].user_id] = list[i];
                        this.addMember(list[i].user_id);
                    }
                }else{
                    this.up_user_id = '';
                    this.show_stu_count = 0;
                }
                for (user in this.memberMap) {
                    if (permission_map[user]){
                        Vue.set(this.memberMap[user], 'camera_auth', permission_map[user].camera ? true : false);                        
                        Vue.set(this.memberMap[user], 'mic_auth', permission_map[user].mic) ? true : false;
                    }else if (user != this.teacher_id){
                        Vue.set(this.memberMap[user], 'camera_auth', false);
                        Vue.set(this.memberMap[user], 'mic_auth', false);
                    }
                }
                // 更新自己的状态
                if (last_camera_auth != this.memberMap[this.user_id].camera_auth && this.memberMap[this.user_id].camera_auth != this.memberMap[this.user_id].camera){                    
                    this.enableCamera(this.memberMap[this.user_id].camera_auth);
                    this.addSystemMessage(new Date(), "您被"+(this.memberMap[this.user_id].camera_auth?"":"取消")+"授予操作摄像头权限");
                }
                if (last_mic_auth != this.memberMap[this.user_id].mic_auth && this.memberMap[this.user_id].mic_auth != this.memberMap[this.user_id].mic){
                    this.enableMic(this.memberMap[this.user_id].mic_auth);
                    this.addSystemMessage(new Date(), "您被"+(this.memberMap[this.user_id].mic_auth?"":"取消")+"授予操作麦克风权限");
                }
        },
        loadQuestion: function(questionId){
            saas.getQuestionInfo(questionId, (ret, json) => {
                if (ret) {
                    this.question_id = data.question_id;
                    sendIpcMessage('WIN_QUESTION:OPEN', json);
                }
            })
        },
            /** 心跳 */
        startClassHeartbeat: function(){
            heartbeat.init(g_data.test, g_data.sdkAppId, g_data.userId, g_data.userSig, (type, sub, data)=>{
                log.info("[TAG-CLASS] HeartBeat->type:"+type+", sub:"+sub+", data:"+JSON.stringify(data));
                if (type == "saas" && sub == "classing"){
                    if (data.error_code == 0){
                        saas.classInfo.duration_time = data.duration_time;
                    }
                }else if (type == "common"){
                    g_data.lastReportTime = heartbeat.getLastReportTime();
                }else if (type == "error"){
                    this.showErrorMessage("签名过期，请重新登陆!", true);
                }          
            }, g_data.lastReportTime);
            heartbeat.updateModule("saas", ""),
            heartbeat.updateModule("saas", "classing", {
                user_id: g_data.userId,
                class_id: g_data.classId,
                token: g_data.token,
                class_video_type: saas.classInfo.class_video_type,
                resolution: saas.classInfo.resolution
            });
            heartbeat.updateHeartbeat();
        },

        /** 音视频事件 */
        onUserEvent: function (event, userId, data) {
            if (event != 'VOLUME') {
                log.info("[TAG-CLASS] onUserEvent->" + event + ", " + userId + ", " + data);
            }
            try {
                switch (event) {
                    case 'JOIN':
                        if (data) {
                            this.addMember(userId);
                        }
                        break;
                    case 'CAMERA':
                        if (data) {
                            this.addMember(userId);
                        }
                        if (null != this.memberMap[userId]) {
                            Vue.set(this.memberMap[userId], 'camera', data);
                            //新sdk代码
                            if (data) {
                                if (userId != g_data.userId) {
                                    this.$nextTick(() => {
                                        var view = document.getElementById(userId)
                                        if (view) {
                                            //this.updateVideo();
                                            saas.startRemoteView(userId, view)
                                        } else {
                                            setTimeout(() => {
                                                var view = document.getElementById(userId)
                                                saas.startRemoteView(userId, view)
                                                //this.updateVideo();
                                            }, 500);
                                        }
                                    });
                                }
                            } else {
                                saas.stopRemoteView(userId)
                            }
                        }
                        break;
                    case 'MIC':
                        if (data) {
                            this.addMember(userId);
                        }
                        if (null != this.memberMap[userId]) {
                            Vue.set(this.memberMap[userId], 'mic', data);
                        }
                        break;
                    case 'SCREEN':
                        this.has_sub_stream = data;
                        if (data) {
                            this.addMember(userId);
                            if (userId != this.user_id) {
                                this.has_screen_share = true;
                                this.$nextTick(() => {
                                    var view = document.getElementById("screen_view");
                                    saas.startRemoteSubStreamView(userId, view)
                                });
                            }
                        } else {
                            this.has_screen_share = false;
                            if (userId != this.user_id) {
                                saas.stopRemoteSubStreamView(userId);
                                var screenView = document.getElementById("screen_view");
                                if (screenView) {
                                    screenView.classList.remove("screen-background");
                                }
                            }
                        }
                        if (null != this.memberMap[userId]) {
                            Vue.set(this.memberMap[userId], screen, data);
                        }
                        break;
                    case 'FIRSTFRAME':
                        if (data && userId != this.user_id) {
                            //this.has_screen_share = true;
                            var screenView = document.getElementById("screen_view");
                            if (screenView) {
                                screenView.classList.add("screen-background");
                            }
                        }
                        break;
                    case 'VOLUME':
                        if (null != this.memberMap[userId]) {
                            this.memberMap[userId].volume = (9 == data ? 5 : Math.floor(data / 2));
                        }
                        try {
                            if (userId == g_data.userId) {
                                // 若设置窗口打开则转发音量
                                var deviceWin = electron.remote.BrowserWindow.fromId(g_data.deviceTestId);
                                if (null != deviceWin) {
                                    deviceWin.webContents.send('Audio:Local', data);
                                }
                            }
                        } catch (err) {
                            log.error("[TAG-PUBLIC] onUserEvent->post data fail: " + err);
                        }
                        break;
                    case 'PLAYVIDEO':
                        this.is_play_video = data;
                        break;
                }
            } catch (err) {
                log.error("[TAG-CLASS] onUserEvent->process error: " + err);
            }
        },
        onVideoDataEvent: function (id, type, width, height, timestamp, rotation, data) {
            if (type == 2) {    /** 屏幕分享 */
                var canvas;
                canvas = saas.getVideoCanvas();
                if (canvas) {
                    renderVideoData(canvas, width, height, data, false, false);
                } else if (id != this.user_id && this.has_sub_stream) {
                    this.has_screen_share = true;
                    canvas = document.getElementById('screen_view');
                    renderVideoData(canvas, width, height, data, false, false);
                }
            } else {
                var canvas = document.getElementById(id);
                renderVideoData(canvas, width, height, data, id == this.user_id ? g_data.mirror : false);

                try {
                    if (id == this.user_id) {
                        // 若设置窗口打开则转发本地视频数据
                        if (0 != g_data.setDlgId) {
                            var deviceWin = electron.remote.BrowserWindow.fromId(g_data.deviceTestId);
                            if (null != deviceWin) {
                                var buffer = Buffer.from(data);
                                var encData = buffer.toString('base64');
                                deviceWin.webContents.send('Video:Local', width, height, rotation, encData);
                            }
                        }
                    }
                } catch (err) {
                    log.error("[TAG-PUBLIC] onVideoDataEvent->post data fail: " + err);
                }
            }
        },

        /** 课堂事件 */
        onClassEvent: function (event, userId, data) {
            log.info("[TAG-CLASS] onClassEvent->event: "+event);
            if (event == 'HandUp') {
                this.addMember(userId);
                this.memberMap[userId].hand_up = true;
                this.checkHandUp();
            } else if (event == 'HandDown') {
                if (this.memberMap[userId]) {                    
                    if (userId == this.user_id && this.memberMap[userId].hand_up){
                        saas.reportEvent('hand_down');
                    }
                    this.memberMap[userId].hand_up = false;
                    this.checkHandUp();
                }
            } else if (event == 'KickOff') {
                this.exitClass((ret, data) => {
                    this.showErrorMessage("您已被踢出课堂", true);
                })
            } else if (event == 'StartClass') {
                this.startClassTick();
                //if (this.isAssistant()){
                //    this.enableDraw();
                //}
                this.addSystemMessage(new Date(), "开始上课");
            } else if (event == 'EndClass') {
                this.exitClass((ret, data) => {
                    this.showErrorMessage("课堂已结束", true);
                })
            } else if (event == 'OpenCamera') {
                if (!this.isTeacher() && !this.isAssistant()){
                    this.addSystemMessage(new Date(), "您被授予操作摄像头权限");
                    this.enableCamera(true);
                }
            } else if (event == 'Silence'){
                this.addSystemMessage(new Date(), "您已被禁言");
            } else if (event == 'UnSilence'){
                this.addSystemMessage(new Date(), "您已被取消禁言");
            } else if (event == "SilenceAll") {
                this.is_mute_all = true;
                saas.getUserNickName(userId, (nick)=>{
                    this.addSystemMessage(new Date(), nick+"已开启全体禁言");
                })
            } else if (event == "UnSilenceAll") {
                this.is_mute_all = false;
                saas.getUserNickName(userId, (nick)=>{
                    this.addSystemMessage(new Date(), nick+"已取消全体禁言");
                })
            } else if (event == 'CloseCamera') {
                if (!this.isTeacher() && !this.isAssistant()){
                    this.enableCamera(false);
                    this.addSystemMessage(new Date(), "您被取消授予操作摄像头权限");
                }
            } else if (event == 'OpenMic') {
                if (!this.isTeacher() && !this.isAssistant()){
                    this.enableMic(true);
                    this.addSystemMessage(new Date(), "您被授予操作麦克风权限");
                }
            } else if (event == 'CloseMic') {
                if (!this.isTeacher() && !this.isAssistant()){
                    this.enableMic(false);
                    this.addSystemMessage(new Date(), "您被取消授予操作麦克风权限");
                }
            } else if (event == 'EnableDraw') {
                this.enableDraw(true);
            } else if (event == 'DisableDraw') {
                this.enableDraw(false);
            } else if (event == 'Join') {
                saas.getUserNickName(userId, (nick) => {
                    this.addSystemMessage(new Date(), nick + '加入课堂');
                })
            } else if(event == 'Exit'){
                saas.getUserNickName(userId, (nick)=>{
                    this.addSystemMessage(new Date(), nick+'离开课堂');
                })   
            } else if (event == 'Show_Check_In') {
                if (!this.isTeacher()) {
                    if (this.isAssistant()){
                        this.addSystemMessage(new Date(), "老师发起签到操作");
                        return;
                    }
                    this.checkin_dlg = true;
                    this.showDialogEx('签到本', '教室发起了课堂签到，请点击下方按钮确认签到  ', ['点击签到'], (index) => {
                        if (0 == index) {
                            log.info("[TAG-CLASS] Show_Check_In dialog->" + data);
                            saas.reportEvent("check_in", {
                                check_id: data,
                                "user_id": g_data.userId
                            })
                        }
                        this.checkin_dlg = false;
                        this.dialog_input_msg = "";
                    }, false, false);
                }
            } else if (event == 'Hide_Check_In') {
                if (!this.isTeacher() && this.checkin_dlg) {
                    this.is_show_msg = false;
                    this.checkin_dlg = false;
                    this.dialog_input_msg = "";
                }
            } else if (event == 'NewQuestion') {
                if (!this.isTeacher()) {
                    if (this.isAssistant()){
                        this.addSystemMessage(new Date(), "老师发起答题操作");
                        return;
                    }
                    this.question_id = data.question_id;
                    sendIpcMessage('WIN_QUESTION:OPEN', data);
                    this.addSystemMessage(new Date(), '老师发起答题卡');
                }
            } else if (event == 'CancelQuestion') {
                if (!this.isTeacher() && !this.isAssistant()) {
                    if (data.question_id == this.question_id) {
                        sendIpcMessage('WIN_QUESTION:CLOSE', data);
                        this.addSystemMessage(new Date(), '老师已结束答题卡');
                    }
                }
            } else if (event == 'Permissions'){
                this.updateAuthList(data);
            } else {
                log.error("[TAG-CLASS] onClassEvent->ignore event:" + event);
            }
        },


        /** 内部回调 */
        onErrorEvent: function (code, msg) {
            log.error('[TAG-PUBLIC] onErrorEvent->code: ' + code + ", msg: " + msg);
            if (code == -1301 || code == -1314 || code == -1315 || code == -1316) {  // camera error
                Vue.set(this.memberMap[this.user_id], 'camera', false);
                msg = '打开摄像头失败';
                this.enableCamera(false);
            } else if (code == -1302) {
                Vue.set(this.memberMap[this.user_id], 'mic', false);
                this.is_mic_enable = false;
                msg = '打开麦克风失败';
            } else if (code == -104) {
                this.enableCamera(false);
            } else if (code == -105) {
                Vue.set(this.memberMap[this.user_id], 'mic', false);
            } else if (code == -2) {
                this.exitClass((ret, data) => {
                    this.showErrorMessage('失败: ' + msg, true);
                })
                return;
            } else if (code == -100 || code == -101 || code == -102 || code == -103 || code == -3320) {
                this.is_loading = false;
                this.showErrorMessage('失败: ' + msg, true);
                return;
            } else if (code == -1318 || code == -102012) {
                // 忽略部分错误
                return;
            }
            this.is_loading = false;
            this.showAlertMessage('失败: ' + msg, null);
        },
        onDlgClick: function (index) {
            if (null != this.dialog_callback) {
                this.dialog_callback(index);
            }
            this.is_show_msg = false;
        },
        onMenuClose: function () {
            this.is_show_menu = false;
        },
        onMuteAll: function () {
            var members = [];
            for (user in this.memberMap) {
                if (user != this.teacher_id){
                    members.push(user);
                }
            }
            saas.reportEvent("PermissionControl", {
                enable: 0,
                rights: ["mic"],
                objectId: members
            })
            this.is_show_menu = false;
            this.showAlertMessage("您已收回所有学生的麦克风权限");
        },
        onStageOffAll: function () {
            var members = [];
            for (user in this.memberMap) {
                if (user != this.teacher_id){
                    members.push(user);
                }
            }
            saas.reportEvent("PermissionControl", {
                enable: 0,
                rights: ["mic", "camera"],
                objectId: members
            })
            this.is_show_menu = false;
            this.showAlertMessage("您已收回所有学生的音视频权限");
        },
        onSendClick: function () {
            //文本聊天消息
            if (this.isTeacher()) {
                saas.sendTextMessage(this.input_msg);
            } else if (!saas.slience && !this.is_mute_all) {
                saas.sendTextMessage(this.input_msg);
            } else {
                this.showAlertMessage("您已被禁言!");
            }
            this.input_msg = '';
        },
        onRecvMsg: function (senderId, nick, timeStamp, message, icon) {
            this.messageArr.push({
                id: senderId,
                type: 'normal',
                nick_name: nick,
                time_stamp: "(" + formatTime(new Date(timeStamp * 1000)) + ")",
                message: message,
                icon: icon
            })
            this.$nextTick(() => {
                var msg_tab = document.getElementsByClassName('tic-player__chatroom-bd')[0];
                if (msg_tab) msg_tab.scrollTop = msg_tab.scrollHeight - 110;
            })
        }
    }
})

// 通用事件
ipcRenderer.on('resume', function (e, data) {
    class_app.onWindowResume();
})
ipcRenderer.on('max', function (e, data) {
    class_app.onWindowMax();
})
ipcRenderer.on('unmax', function (e, data) {
    class_app.onWindowUnMax();
})

// 处理外部请求
ipcRenderer.on('DEVICES:QUERY', (e, data) => {
    var speakers = saas.querySpeakerList();
    var mics = saas.queryMicList(class_app.memberMap[g_data.userId].mic);
    var cameras = saas.queryCameraList(class_app.memberMap[g_data.userId].camera);

    sendIpcMessage('DEVICES:LIST', speakers, mics, cameras)
})
ipcRenderer.on('DEVICES:CHANGE', (e, device, id) => {
    log.info("[TAG-CALSS] changeDevice->device: " + device + ", id: " + id);
    if (id == 0) return;
    switch (device) {
        case 'speaker': saas.setCurrentSpeaker(id); break;
        case 'mic': saas.setCurrentMic(id); break;
        case 'camera': saas.setCurrentCamera(id); break;
        default: log.warn("[TAG-PUBLIC] changeDevice->ignore device: " + device);
    }
})
ipcRenderer.on('DEVICES:SPEAKER', (e, enable) => {
    if (enable) {
        var testFile = path.join(__dirname, "../", "mp3", "test.mp3");
        log.info("[TAG-CALSS] enableSpeakerTest->play file:" + testFile);
        saas.startSpeakerTest(testFile);
    } else {
        log.info("[TAG-CALSS] enableSpeakerTest->stop");
        saas.stopSpeakerTest();
    }
})
ipcRenderer.on('SET:SPEAKERVOLUME', (e, volume) => {
    saas.setSpeakerVolume(volume);
})
ipcRenderer.on('SET:MICVOLUME', (e, volume) => {
})
ipcRenderer.on('SET:BEAUTY', (e, mode, beauty, white, ruddiness) => {
    saas.setBeautyStyle(mode, beauty, white, ruddiness);
})
ipcRenderer.on('SET:MIRROR', (e, enable) => {
    saas.setLocalViewMirror(enable);
})
ipcRenderer.on('TOOL:PLAYVIDEO', (e, videoPath) => {
    if (!class_app.is_share_screen) {
        saas.startPlayVideo(videoPath);
    } else {
        class_app.showAlertMessage("请先关闭屏幕分享");
    }
})
ipcRenderer.on('MEMBER:CLEARHANDUP', (e, enable) => {
    class_app.has_new_hand_up = false;
})

// 发送IM消息处理
ipcRenderer.on('IM:SENDTEXTMSG', (e, groupId, data, ext) => {
    saas.sendTextMessage(data, ext);
})
ipcRenderer.on('IM:SENDCUSTOMMSG', (e, groupId, data, ext) => {
    // alert("custom " + data + " " + ext);
    saas.sendCustomMessage(data, ext);
})
/** 添加课件 */
ipcRenderer.on('CLASS:OpenDoc', (e, doc) => {
    saas.addClassDoc(doc);
})


/** 全局弹窗 */
window.showMessageBox = function (message, buttons, callback) {
    class_app.showDialog(message, buttons, callback);
}

window.sendChannel = function (type, data) {
    //log.info("[TAG-CLASS] sendChannel text: " + data + ", type:" + type + ", silence: " + saas.slience);
    var ext;
    if (type == "CHAT") {
        if (class_app.isTeacher()) {
            saas.sendTextMessage(data);
        } else if (!saas.slience && !class_app.is_mute_all) {
            saas.sendTextMessage(data);
        } else {
            class_app.showAlertMessage("您已被禁言!");
        }
    } else if (type == "Ctrl") {
        //控制信令
        ext = "CTRL";
        saas.sendCustomMessage(data, ext);
    } else if (type == "BOARD") {
        //白板数据
        ext = "TXWhiteBoardExt";
        saas.sendCustomMessage(data, ext);
    } else if (type == "CONTAINER") {
        //容器数据
        log.info("sendChannel [TAG-CONTAINER]  data : " + data + "  type " + type);
        ext = "CONTAINER";
        saas.sendCustomMessage(data, ext);
    } else if (type == "TRTC") {
        //容器数据
        log.info("sendChannel TRTC data : " + data + "  type " + type);
        //liteav.sendCustomCmdMsg(parseInt(data),"test",true,true);
    } else if (type == "onPageFinished") { // 同步白板
        saas.syncContentBoard();
    } else if (type == "onContainerLoaded") {
        log.info("[TAG] onContainerLoaded->enter");
        if (class_app.video_type == 'live' && class_app.isTeacher()) {   // 大型直播课此时才开摄像头
            log.info("[TAG] onContainerLoaded->enableCamera");
            class_app.enableCamera(true);
        }
    }
}

function onLocalVideoDataRender(id, type, width, height, timestamp, rotation, data) {
    try {
        if (id == g_data.userId) {
            // 若设置窗口打开则转发本地视频数据
            if (0 != g_data.setDlgId) {
                var deviceWin = electron.remote.BrowserWindow.fromId(g_data.deviceTestId);
                if (null != deviceWin) {
                    var buffer = Buffer.from(data);
                    var encData = buffer.toString('base64');
                    deviceWin.webContents.send('Video:Local', width, height, rotation, encData);
                }
            }
        }
    } catch (err) {
        log.error("[TAG-PUBLIC] onVideoDataEvent->post data fail: " + err);
    }
}

Vue.config.errorHandler = (err, vm) => {
    let { message, name, script, line, column, stack } = err;
    // 在vue提供的error对象中，script、line、column目前是空的。但这些信息其实在错误栈信息里可以看到。
    script = script ? script : '';
    line = line ? line : 0;
    column = line ? line : 0;
    // 解析错误栈信息
    let stackStr = stack ? stack.toString() : `${name}:${message}`;

    log.error("[TAG-LOGIN] exception->" + stackStr);
}
