<template>
	<div id="app">
		<transition name='fade' mode="out-in">
			<router-view/>
		</transition>
	</div>
</template>

<script>
	import Vue from 'vue';
	export default {
		name: 'App',
		data(){
			return{
				reconnectData:null,
				lockReconnect:false,    //避免重复连接，因为onerror之后会立即触发 onclose
				timeout:5000,          //10s一次心跳检测
				timeoutObj:null,
				serverTimeoutObj:null,
				apiToken:'',
				linkfailure:true,
				Messagenum:0,
				kfuser_info:{}
			}
		},
		methods:{
			/**************************************/
			//初始化weosocket
			initWebSocket(apiToken) {
				// 书写接口信息
				// http://stadmin.bocai108.com/
				const wsuri = "wss://ky.281570.com:9101?apiToken=" + apiToken;//www.service.com 线上
				// const wsuri = "ws://192.168.2.187:9101?apiToken=" + apiToken;//www.service.com //192.168.2.186 本地
				// 创建websocket实例
				Vue.prototype.$websocket = new WebSocket(wsuri);
				this.$websocket.onopen = this.websocketonopen; //连接成功
				this.$websocket.onmessage = this.websocketonmessage; //接收消息
				this.$websocket.onerror = this.websocketonerror;//链接错误提示
				this.$websocket.onclose = this.socket_close;//链接断开提示
			},
			// 得到保存好的当前客服信息
			getCustomerUserInfo()
			{

				if(typeof this.$store.getters.get_user_info  != 'string'){
					this.kfuser_info = this.$store.getters.get_user_info;
				}else if(this.$store.getters.get_user_info!= ""){
					this.kfuser_info =  JSON.parse(this.$store.getters.get_user_info);
				}
				return this.kfuser_info;
			},

			/**************************************/
			//连接成功
			websocketonopen() {
				console.log('已经链接');
				let user_info = '';
				// console.log(this.$store.getters.get_user_info != "");
				user_info=this.getCustomerUserInfo();

				if(user_info){
					this.$websocket.send(JSON.stringify({
						type: 'init',
						data: {
							uid: 'KF' + user_info.id,
							group: user_info.group_id,
							token: user_info.token,
							name: user_info.user_name,
							avatar: user_info.user_avatar,
						}
					}));
				}
		
			
				this.$store.dispatch("SET_SOCKET_OPEN",true);//列表下标  
				this.heatBeat();
			},

			/*******************************************/
			//连接关闭触发
			socket_close(e){
				console.log('断开连接',e);
				//this.init()
				this.reconnect();
			},
			getVisitorList(){
				this.kfuser_info=this.getCustomerUserInfo();
				this.$websocket.send(JSON.stringify({
						type: 'kfusersmaps',
						data: {
							kfuid:  this.kfuser_info.id
						}
					}));
			},

			/******************************************/
			//数据接收
			websocketonmessage(e){
				this.heatBeat();//收到消息会刷新心跳检测，如果一直收到消息，就推迟心跳发送
				const redata = JSON.parse(e.data);//接收数据源
				if(!redata) {
					return
				}
				//
				if(redata.message_type == "ping"){
					this.$websocket.send('{"type":"pong"}')
					return false;
				}

				if(redata.type == "pong") return false;
				if(redata.type != "pong" || redata.message_type != "ping"){
		
					if(redata.message_type === 'connct') {
						this.$store.dispatch("SET_SESSSION_USER", redata.data.user_info);
					}
				}
				// this.getVisitorList();
				console.log(redata);
				let getters = this.$store.getters;
				// console.log({'getters':this.$store})
				//获取vuex数据
				let session = getters.get_session;//会话列表
				let offline  = getters.get_offline;//离线列表
				let sessionType  = getters.get_type;//选择状态(会话/离线)
				let dataIndex  = getters.get_num;//列表下标
				let current_session  = getters.get_current;//当前会话
				let session_name  = getters.get_session_name;//当前用户名
				this.$store.dispatch("SET_SESSION_MESSAGE",JSON.parse(e.data));

				// 用户接入数据
				if(redata.message_type == "connect"){
					this.$message({
						message: '访客已进入对话',
						type: 'success'
					});
					let _this  = this;
					let arr =[
						redata.data,
						offline,
						session,
						sessionType,
						dataIndex,
						current_session,
						session_name,
					]
					_this.$public.visitorsConnect(arr,function(data){
						//离线匹配列表访客链接回调
						_this.$store.dispatch("SET_OFFLINE",data);

					},function(data,session,offline,type,num,dataList,name){
						//将用户添加到会话列表中 
						// console.log('接入用户昵称',name);
						if(name){
							data.user_info.name = name;
							_this.$store.dispatch("SET_SESSION_NAME",name);//当前会话对象名
						}

						session.push(data.user_info);
						//获取接入的用户信息
						//_this.get_user_info(list);
						//获取接入的用户信息写入vuex
						_this.$store.dispatch("SET_SESSION",session);//会话列表
						_this.$store.dispatch("SET_OFFLINE",offline);//离线列表
						_this.$store.dispatch("SET_TYPE",type);//选择类型(会话/离线)
						_this.$store.dispatch("SET_NUM",num);//列表下标
						_this.$store.dispatch("SET_CURRENT",dataList);//当前会话数据

					})
				}

				//登录验证失败跳转登录页面
				if(redata.message_type == 'checkfalse'){
					// this.$router.push({
					// 	path:'/login',
					// 	query: { pid:escape("这就是一个编码没有什么用啊") }
					// })
				}

				//用户离线后会话窗口切换
				if(redata.message_type == "userClose"){
					let _this =this;
					let	arr= [
						redata.data,
						session,
						offline,
						sessionType,
						dataIndex,
						session_name,
						current_session,
					]
					_this.$public.userOffline(arr,function(session,offline,type,index,name,list,userInfo){
						_this.$store.dispatch("SET_CURRENT",list);//当前会话数据
						_this.$store.dispatch("SET_SESSION_NAME",name);//当前会话对象名
						_this.$store.dispatch("SET_NUM",index);
						_this.$store.dispatch("SET_TYPE",type);
						_this.$store.dispatch("SET_SESSION",session);
						_this.$store.dispatch("SET_OFFLINE",offline);
						// _this.get_user_info(userInfo);
					})
				}


				//用户会话结束窗口切换
				if(redata.message_type == "delUser"){
					this.$message({
						message: '访客已退出会话',
						type: 'warning'
					});

					let _this =this;
					let	arr= [
						redata.data,
						session,
						offline,
						sessionType,
						dataIndex,
						session_name,
						current_session,
					]
					_this.$public.sessionEnd(arr,function(session,offline,type,index,name,list,userInfo){
						_this.$store.dispatch("SET_CURRENT",list);//当前会话数据
						_this.$store.dispatch("SET_SESSION_NAME",name);//当前会话对象名
						_this.$store.dispatch("SET_NUM",index);
						_this.$store.dispatch("SET_TYPE",type);
						_this.$store.dispatch("SET_SESSION",session);
						_this.$store.dispatch("SET_OFFLINE",offline);
						//	_this.get_user_info(userInfo);
					})
				}

				//接收用户消息数据
				if(redata.message_type == "chatMessage"){
					this.Messagenum = this.$store.getters.get_megnum;
					this.Messagenum = ++this.Messagenum;
					this.$store.dispatch("SET_MEGNNUM", this.Messagenum);
					this.receiveAudio();
					let _this =this;
					this.$public.receivesMessage(redata.data,session,this.$frce,function(data,chatList,index){
						//判断是否是当前对话信息
						if(dataIndex == index){
							_this.$store.dispatch("SET_CURRENT",chatList.data);//当前会话数据
						}else{
							let num = Number.isInteger(chatList.num) ? chatList.num : 0;
							// session[index].num = num+1;
							_this.$set(session[index],'num',num+1)
						}
						//更新会话时间
						session[index].intime =data.time;

						//更新会话列表中最新回复消息
						if(data.content.text){
							// _this.$set(chatList,'text',data.content.text)
							session[index].text =data.content.text;
						}
						_this.$store.dispatch("SET_SESSION",session);
					})
				}
				// history

				//reLoginErr
				if(redata.message_type == "reLoginErr"){
					// console.log('haha');
					this.init()
				}

			},

			/**************************************/
			//连接断开，失败
			websocketonerror(e) {
				console.log('失败',e);
				if(this.linkfailure){
					this.init()
				}
			},

			/******************************************/
			//断开链接数据初始化
			init(){
				this.$store.dispatch("SET_STATEVALUE",'在线');
				this.$store.dispatch("SET_SESSION",[]);
				this.$store.dispatch("SET_USER",'');
				this.$store.dispatch("SET_OFFLINE",[]);
				this.$store.dispatch("SET_SESSION",[]);//会话列表
				this.$store.dispatch("SET_OFFLINE",[]);//离线列表
				this.$store.dispatch("SET_TYPE",1);//选择类型(会话/离线)
				this.$store.dispatch("SET_NUM",0);//列表下标
				this.$store.dispatch("SET_CURRENT",[]);//当前会话数据
				this.$store.dispatch("SET_SESSION_NAME",'');//当前会话对象名
				this.$store.dispatch("SET_SESSION_MESSAGE",{});
				this.$store.dispatch("SET_NAVSTATE",'TheCurrentSession');
				this.$store.dispatch("SET_IS_INIT",false);
				this.$token = '';
				this.$router.push('/login')
				this.linkfailure = true;
				
				//this.reconnect();
			},

			/*******************************************/
			// 接收消息音频提示
			receiveAudio() {
				let receive = new Audio()
				receive.src = "../static/audio/receive.wav";
				receive.play();
			},
			/***************************************/
			//socket重连
			reconnect(){
				if(this.lockReconnect){   //这里很关键，因为连接失败之后之后会相继触发 连接关闭，不然会连接上两个 WebSocket
					return
				}
				this.lockReconnect = true;
				this.reconnectData && clearTimeout(this.reconnectData);
				this.reconnectData = setTimeout(()=>{
					this.initWebSocket(this.apiToken);
					this.lockReconnect = false;
				},3000)
			},

			/*************************************/
			//心跳检测
			heatBeat(){
				this.timeoutObj && clearTimeout(this.timeoutObj);
				this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
				this.timeoutObj = setTimeout(()=>{
					// console.log('发送',{type:'ping'});
					this.$websocket.send(JSON.stringify({type:'ping'}))   //根据后台要求发送
					this.serverTimeoutObj = setTimeout(()=> {
						this.$websocket.close(); //如果4秒之后我们没有收到 后台返回的心跳检测数据 断开socket，断开后会启动重连机制
					}, 4000);
				}, this.timeout)
			},

			/******************************/

		},
		mounted() {
			Vue.prototype.$socket_open = false;
			this.apiToken = this.$md5('customer-service'+window.location.origin)
			this.initWebSocket(this.apiToken);
			// 获取系统时间
			//let t = new Date().getTime();
			//this.get('api'+this.$ports.TIME+'?t='+t).then(res => {
			// this.$http.get(this.$ports.TIME+'?t='+t).then(res => {
			// 	if (res.data.code == 1) {
			// 		let time = res.data.data.time.split(' ');
			// 		time[0] =(new Date( time[0].replace(/-/g,'/')).getTime()) /1000;
			// 		sessionStorage.setItem("time",JSON.stringify(time));
			// 		sessionStorage.setItem("logo",res.data.data.logo);
					
			// 	}
			// });
		},
		destroyed() {
			this.lockReconnect = true;
			this.$websocket.close();
			// this.websock.close()                //离开路由之后断开websocket连接
			clearTimeout(this.reconnectData);      //离开清除 timeout
			clearTimeout(this.timeoutObj);         //离开清除 timeout
			clearTimeout(this.serverTimeoutObj);   //离开清除 timeout
			localStorage.removeItem('user');
		}
	}
</script>

<style>
	.fade-enter-active, .fade-leave-active {
		transition: opacity .5s;
	}

	.fade-enter, .fade-leave-to {
		opacity: 0;
	}
</style>
