var serverURL = "avd.nice2meet.cn:9631";  // 媒体服务器地址，https访问请将端口号改为9630
var accessKey = 'demo_access';
var secretKey = 'demo_secret';

var accessToken = null;
var room = null;
var roomId = null;
var userId = Math.uuid();
var userName = 'user' + parseInt(Math.floor(Math.random() * 9000) + 1000);

var AVDEngine = ModuleBase.use(ModulesEnum.avdEngine);
var avdEngine = new AVDEngine();

avdEngine.setLog(Appender.browserConsole, LogLevel.debug);
avdEngine.initDevice().then(checkResult).otherwise(function(err){
    console.log("+++avdEngine.initDevice error: ", err)
    showError(err)
});
// avdEngine.setVideoCoding(VideoCodingType.H264);
var restApi = new RestApi(serverURL);
var self = this;

var localVideo = document.getElementById("localVideo");
var remoteAudio = document.getElementById("remoteAudio");
var remoteVideo = document.getElementById("remoteVideo");
var local_video = document.getElementById("local_video");
var local_audio = document.getElementById("local_audio");
var remote_video = document.getElementById("remote_video");
var remote_audio = document.getElementById("remote_audio");
var frontCam = document.getElementById('frontCam');
var backCam = document.getElementById('backCam');
var isOpenVideoShow = true;
var isOpenAudioShow = true;
var currOpenCameraType = 0 ;// 0 - 未打开  1 - 前置  2 - 后置

var isFirstSafariAudio = false
var firstSafariAudioStream;
restApi.getAccessToken(accessKey, secretKey).then((res) => {
    console.log('Success', res)
    self.accessToken = res.token;
}).otherwise((error) => {
    console.log("Error", error);
    $(".promptMsg").html('getAccessToken(),error:' + error.msg);

})

function checkResult() {
    console.log('+++checkResult success')
}


function checkError(error) {
    $(".promptMsg").html("get device error!error code:" + error.code + "; error message:" + error.message);
}

function createRoom() {
    var topic = 'testingMeeting';
    restApi.createRoom(self.accessToken, topic, self.userId).then((res) => {
        console.log('Success', res)
        $("#first").val(res.room_id);
    }).otherwise((error) => {
        console.log("Error", error)
        $(".promptMsg").html('createRoom(),error:' + error.msg);
    })
}

function joinRoom() {
    if (room) { return }

    if ($("#first").val() == '') {
        $('.promptMsg').html('会议号不能为空，请先创建房间');
    } else {
        self.roomId = $("#first").val();
        avdEngine.init(self.serverURL, self.accessToken).then(initSuccess).otherwise(initError);
    }
}

function initSuccess() {
    room = avdEngine.obtainRoom(self.roomId);
    room.join(self.userId, self.userName, '', null).then(joinSuccess).otherwise(joinError);
}

function initError(error) {
    $(".promptMsg").html("AVDEngine 初始化失败！initError(),error:" + error.message);
    room.join(self.userId, self.userName, '', null).then(joinSuccess).otherwise(joinError);
}


function joinSuccess() {
    openMicrophone()
    registerRoomCallback();

    //加会登陆前，会议中已经发布的视频资源,采取订阅处理
    onPublishCameraNotify(room.pubVideos);

    participantsHandle(room.getParticipants());

    $('.localVideo_userName').html(self.userName + "(我)");
    $('.promptMsg').html('加入会议成功');
    switchCameraBtnStatus();
}

function joinError(error) {
    console.log('==================joinError(),error:', error)
    if (error.code == 404) {
        $(".promptMsg").html("加会失败！原因房间没有找到，请核实。joinError(),error");
    } else {
        $(".promptMsg").html('joinError(),error:' + error.message + "[" + error.code + "]");
    }
}

function openMicrophone() {
    console.log(`+++123openMicrophone`);
    if (isOpenAudioShow) {
        isOpenAudioShow = false;
        var audio = room.selfUser.audio;
        if (audio) {
            localAudioId = audio.id;
            audio.openMicrophone().otherwise(showError);
            local_audio.className = 'openMicrophone';
        }
    }
}



function muteMicrophone() {
    if (!isOpenAudioShow) {
        isOpenAudioShow = true;
        var audio = room.selfUser.getAudio(self.localAudioId);
        if (audio) {
            local_audio.className = 'closeMicrophone';
            audio.muteMicrophone();
        }
    }
}

function unmuteMicrophone(){
    if(isOpenAudioShow){
        isOpenAudioShow = false;
        var audio = room.selfUser.audio;
        if(audio && audio.status == StreamStatus.muted){
            audio.unmuteMicrophone();
            local_audio.className = 'openMicrophone';
        }
    }
}

function showError(error) {
    $(".promptMsg").html('showError(),error:' + error.message + "[" + error.code + "]");
}

//退会
function leaveRoom() {
    if (!room) { return }
    var close = window.confirm('您确认退出会议?');
    if (close) {
        var reason = 1; //退会原因
        room.leave(reason).then(function () {
            top.location = "index.html";
            return false;
        });
    }
}

function registerRoomCallback() {
    room.addCallback(RoomCallback.connection_status, onConnectionStatus);

    room.addCallback(RoomCallback.user_join_notify, onUserJoinNotify);
    room.addCallback(RoomCallback.user_leave_notify, onUserLeaveNotify);
	room.addCallback(RoomCallback.leave_indication, onLeaveIndication);
	
	room.addCallback(RoomCallback.close_room_result, onCloseRoomResult);
	room.addCallback(RoomCallback.close_room_notify, onCloseRoomNotify);

    room.addCallback(RoomCallback.user_data_notify, onUserDataNotify);
}

function onUserDataNotify(userData, userId){

}

/**
 * @desc 网络状态回调
 */
function onConnectionStatus(status) {
    if(status == ConnectionStatus.connecting) {
		$(".promptMsg").html("网络故障,正在与服务器重连中...");
	} else if(status == ConnectionStatus.connected) {
		//连接成功
		$(".promptMsg").html("");
	} else if(status == ConnectionStatus.reJoinConnected) {
		//重新加会成功
		$(".promptMsg").html("");
	} else if(status == ConnectionStatus.reconnected) {
		//重连接成功
		$(".promptMsg").html("");
	} else if(status == ConnectionStatus.connectFailed) {
		$(".promptMsg").html("网络故障,与服务器重连超时，正在重新加会操作中...");

		//应用层清场
		if(room.connectionInfoCollector) {
			room.connectionInfoCollector.stop(); //停止收集网络情况
		}
	} else if(status == ConnectionStatus.reJoinRoomTimeOut) {
		$(".promptMsg").html("网络故障,重新加会中...");
	    room.continuousReJoin();
	}
}

function turnFront(){
    if(currOpenCameraType === 2){
        room.selfUser.closeMobileBackVideo(localVideo);
    }
    if(currOpenCameraType === 1){return}

    room.selfUser.openMobileFrontVideo(localVideo).then(function () {
        console.log("+++openMobileFrontVideo 成功")
        localVideo.play();
        currOpenCameraType = 1
        switchCameraBtnStatus();
    }).otherwise(function(err){
        console.log('+++openMobileFrontVideo 失败，err: ', err)
        showError(err)
    });
}

function turnBack(){
    if(currOpenCameraType === 1){
        room.selfUser.closeMobileFrontVideo(localVideo);
    }
    if(currOpenCameraType === 2){return}

    room.selfUser.openMobileBackVideo(localVideo).then(function () {
        console.log("+++openMobileBackVideo 成功")
        localVideo.play();
        currOpenCameraType = 2;
        switchCameraBtnStatus();
    }).otherwise(function(err){
        console.log('+++openMobileBackVideo 失败，err: ', err)
        showError(err)
    });
}

function switchCameraBtnStatus() {
    if(currOpenCameraType === 0){
        backCam.disabled = false;
        frontCam.disabled = false;
    }
    if(currOpenCameraType === 1){
        backCam.disabled = false;
        frontCam.disabled = true;
    }
    if(currOpenCameraType === 2){
        backCam.disabled = true;
        frontCam.disabled = false;
    }
}

/**
 * @desc 参会者加会回调
 * @param {Object} users － 参会者数组
 */
function onUserJoinNotify(users) {
    console.log("============onUserJoinNotify(),users:", users);
    participantsHandle(users);
}

/**
 * @desc 参会者退会回调
 * @param {int} opt - 退会类型
 * @param {int} reason  - 退会原因
 * @param {Object} user - 退会用户
 */
function onUserLeaveNotify(opt, reason, user) {
	
	//UDP媒体通道建立超时807错误
    if(reason == 807) {
        if(user.id == room.selfUser.id){
            $(".promptMsg").html("本端 807错误,UDP不通或UDP媒体通道建立超时!").show();
        }else {
            $(".promptMsg").html(user.name +" 807错误,UDP不通或UDP媒体通道建立超时!").show();
        }
        return;
    }
	
	if(reason == 812){//用户心跳超时掉线（如异常退会）
		$(".promptMsg").html(user.name+" 已异常退会").show();
	}else{
		$(".promptMsg").html(user.name+" 已退会").show();
	}
	
	isFirstSafariAudio = false;
	
    room.selfUser.attachVideoElementMediaStream(remoteVideo, null);
    $('.remoteVideo_userName').html('');
    remote_video.className = '';
    remote_audio.className = '';
}


/**
 * @desc 被踢出会议室
 * @param {Object} reason - 被踢原因
 * @param {Object} userId - 踢人的操作者
 */
function onLeaveIndication(reason, userId) {
	console.log("+++onLeaveIndication(),reason:" + reason + ",userId:" + userId);
	if(reason == 804) {
		//同一个userid加会， 把前一个人踢下线
		 $(".promptMsg").html("你已在另一个地方登陆，被踢出会议室。被踢原因：" + reason).show();
	} else if(reason == 808) {
		//调用Restful接口把人踢下线或SDK调踢人接口通知会议中的第三方用户
		 $(".promptMsg").html("你被" + userId + "踢出会议室。被踢原因：" + reason).show();
	} else {
		 $(".promptMsg").html("你被" + userId + "踢出会议室。被踢原因：" + reason).show();
	}
	
	top.location = "index.html";
	return false;
}


/**
 * @desc 关闭会议回调结果
 * @param {int} result - 关闭结果
 * @param {String} description - 描述
 */
function onCloseRoomResult(result, description) {
	console.log("+++onCloseRoomResult(),result:"+result+",description:"+description);
	if(result == 0) {
		console.log("关闭会议成功");
		top.location = "index.html";
		return false;
    }
}


/**
 * @desc 收到关闭房间通知，退出会议操作
 * @param {int} roomId - 房间ID
 * @param {int} reason  -关闭会议原因
 */
function onCloseRoomNotify(roomId, reason) {
	console.log("+++onCloseRoomNotify(),roomId:"+roomId+",reason:"+reason);
	
	var tips = "";
	if(reason == 809) {
		tips = "服务没有授权用户入会(最多2个用户),超过15分钟服务器主动关闭房间强制踢人";
	}else if(reason == 810) {
		tips = "SDK调用接口关闭会议";
	}else if(reason == 811){
		tips = "服务更新维护时关闭会议";
	}else if(reason == 815){
		tips = "调用restful接口关闭会议";
	}	
	
	$(".promptMsg").html("会议已关闭。原因:" + tips).show();
	
	
	setTimeout(function() {
		top.location = "index.html";
		return false;
	}, 2000);
	
}	


/**
 * @desc  用户回调事件
 * @param {Object} participants - 用户集数组
 */
function participantsHandle(participants) {
    participants.forEach(function (user) {
        user.addCallback(UserCallback.camera_status_notify, onCameraStatusNotify);
        user.addCallback(UserCallback.microphone_status_notify, onMicrophoneStatusNotify);

        user.addCallback(UserCallback.publish_camera_notify, onPublishCameraNotify);
        user.addCallback(UserCallback.subscrible_camera_result, onSubscribleCameraResult);
        user.addCallback(UserCallback.unpublish_camera_notify, onUnpublishCameraNotify);
        user.addCallback(UserCallback.unsubscrible_camera_result, onUnsubscribleCameraResult);

        user.addCallback(UserCallback.subscrible_microphone_result, onSubscribleMicrophoneResult);
        user.addCallback(UserCallback.unsubscrible_microphone_result, onUnsubscribleMicrophoneResult);
    })
}

/**
 * 麦克风状态更新
 * @param {Object} status － 状态
 * @param {Object} microphoneId － 麦克风设备Id 
 * @param {Object} microphoneName － 麦克风设备名称
 * @param {Object} userId － 麦克风设备所属者ＩＤ
 */
function onMicrophoneStatusNotify(status, microphoneId, microphoneName, userId) {
    if (userId == room.selfUser.id) {
        console.log('+++onMicrophoneStatusNotify, selfUser,  status: ',status );
        if (status == StreamStatus.published) {
            local_audio.className = 'openMicrophone';
        } else if (status == StreamStatus.init) {
            local_audio.className = 'closeMicrophone';
        } else if (status == StreamStatus.muted){
            local_audio.className = 'closeMicrophone';
        }
    } else {
        console.log('+++onMicrophoneStatusNotify, remoteUser,  status: ',status );
        if (status == StreamStatus.published) {
            remote_audio.className = 'openMicrophone';
        } else if (status == StreamStatus.init) {
            remote_audio.className = 'closeMicrophone';
        } else if (status == StreamStatus.muted){
            remote_audio.className = 'closeMicrophone';
        }
    }
}

/**
 * 房间中发布的视频回调
 * @param {Object} video-发布视频集
 */
function onUnpublishCameraNotify(video) {
    video.unsubscrible();
}

/**
 * 摄像头状态更新
 * @param {Object} status － 状态
 * @param {Object} cameraId － 摄像头设备Id
 * @param {Object} cameraName－ 摄像头设备名称
 * @param {Object} userId－ 摄像头设备所属者ＩＤ
 */
function onCameraStatusNotify(status, cameraId, cameraName, userId) {
    console.log('+++onCameraStatusNotify, status: ' + status + ',userId: ', userId)
}

//订阅未订阅的视频
function onPublishCameraNotify(videos) {
    videos.forEach(function (video) {
        //只订阅未订阅过的视频
        var subVideoIdsLen = room.selfUser.subVideoIds.length;
        if (subVideoIdsLen > 0) {
            var isSub = false;
            for (var i = 0; i < subVideoIdsLen; i++) {
                var videoId = room.selfUser.subVideoIds[i];
                if (video.id == videoId) {
                    isSub = true;
                    break;
                }
            }
            if (!isSub) {
                video.subscrible();
            }
        } else {
            video.subscrible();
        }
    });
}

/**
 * 订阅远端视频流反馈
 * @param {Object} stream － 远端视频流
 * @param {Object} userId － 所属用户ＩＤ
 * @param {Object} userName－ 所属用户名称
 * @param {Object} cameraId－ 摄像头设备ＩＤ
 */
function onSubscribleCameraResult(stream, userId, userName, cameraId) {
    $('.remoteVideo_userName').html(userName + "(远端)");
    remote_video.className = 'openCamera';
    room.selfUser.attachVideoElementMediaStream(remoteVideo, stream);
    remoteVideo.oncanplay = function() {
        console.log('+++onSubscribleCameraResult, 手动开启播放远端视频');
        remoteVideo.play();
    }
}

/**
 * 取消订阅远端视频流反馈
 * @param {Object} userId－ 所属用户ＩＤ
 * @param {Object} userName－所属用户名称
 * @param {Object} cameraId－摄像头设备ＩＤ
 */
function onUnsubscribleCameraResult(userId, userName, cameraId) {
    room.selfUser.attachVideoElementMediaStream(remoteVideo, null);
}

/**
 * 订阅远端音频流反馈
 * @param {Object} stream－ 远端音频流
 * @param {Object} userId－ 所属用户ＩＤ
 * @param {Object} userName－所属用户名称
 */
function onSubscribleMicrophoneResult(stream, userId, userName) {
    log.info(`+++123, onSubscribleMicrophoneResult, ${userName}'s microphone stream ${stream}`);
    remote_audio.className = 'openMicrophone';
    var remoteAudio = document.getElementById('remoteAudio');
    if(room.avdEngine.isSafari || (room.avdEngine.getBrowserDetect().osName == 'iOS' && room.avdEngine.isMicroMessenger)){
        if(isFirstSafariAudio && remoteAudio){
            room.selfUser.attachAudioElementMediaStream(remoteAudio, stream);
        }
        else{
            isFirstSafariAudio = true;
            firstSafariAudioStream = stream;
            $('.safariAudioNotice').show();
        }
    }
    else{
        room.selfUser.attachAudioElementMediaStream(remoteAudio, stream);
    }
}

function safariAudioHandle(){
    $('.safariAudioNotice').hide();
    var remoteAudio = document.getElementById('remoteAudio');
    if(remoteAudio){
        room.selfUser.attachAudioElementMediaStream(remoteAudio, firstSafariAudioStream);
    }
}

/**
 * 取消订阅远端音频流反馈
 * @param {Object} userId－ 所属用户ＩＤ
 * @param {Object} userName－所属用户名称
 */
function onUnsubscribleMicrophoneResult(userId, userName) {
	isFirstSafariAudio = false;
    room.selfUser.attachAudioElementMediaStream(remoteAudio, null);
}



//iPhone手机上，QQ浏览器,搜狗浏览器,火狐浏览器等切换到后台再切回前台，或接听电话后，音视频控件的播放状态会变成暂停，通过监听进行处理。
document.addEventListener("visibilitychange", () => { 
    //当浏览器的某个标签页切换到后台就会触发
	if(document.hidden) {
		console.info("+++visibilitychange页面被挂起");
	//从后台切换到前台时就会触发
	}else {
		console.info("+++visibilitychange页面呼出");
		var videos = document.getElementsByTagName("video");
		for(var video of videos){
		   video.play();
		}
		
		var audios = document.getElementsByTagName("audio");
		for(var audio of audios){
		   audio.play();
		}
    }
});