import EventEmitter from "./events.js"

export class Msg{
	data = "" // 数据载体
	ev = "" // 事件类型
	_success = 0 // 是否发送成功
	constructor(ev, data, _success) {
		this.ev = ev;
		this.data = data;
		this._success = _success;
	}
}

Msg.create = function(ev, data, _success){
	return new Msg(ev, data, _success)
}

class Sc {
	#isConnected = false;
	#isConnecting = false;
	// #url = "ws://82.157.123.54:9010/ajaxchattest"
	#url = "ws://127.0.0.1:8888"
	#instance = null
	#event = null
	#isClose = false
	#time = 0 // 重连的次数
	#maxTime = 10 // 能够重连的次数
	#timerID = -1 // 心跳检测
	// WILL: 是否需要检测心跳检测没回应的次数断开连接
	#heartTimes = 0 // 心跳检测次数
	constructor() {
		this.#event = new EventEmitter()
	}
	get event(){
		return this.#event;
	}
	close(){
		if(!this.#isConnected) return
		if(!this.#instance) return
		this.#isClose = true
		this.#instance.close()
	}
	/**
	 * 心跳检测
	 */
	heartTime(){
		if(!this.#isConnected) return
		if(!this.#instance) return
		if(this.#timerID!=-1) return
		this.send({ping: new Date().getTime()})
		this.#timerID = setInterval(()=>{
			this.send({ping: new Date().getTime()})
		},5000)
	}
	clearHeartTime(){
		clearInterval(this.#timerID)
		this.#timerID = -1
	}
	send(data){
		return new Promise((resolve,reject)=>{
			const that = this;
			if(this.#isConnected){
				const encryptData = encodeURIComponent(JSON.stringify(data));
				this.#instance.send({
					data: encryptData, 
					success(){
						resolve()
					},
					fail() {
						that.#event.emit('onMessage',{...data, _success: 2})
						// reject()
						resolve()
					}
				});
			}else{
				that.#event.emit('onMessage',{...data, _success: 2})
				// reject()
				resolve()
			}
		})
	}
	initConnect(opts = {}, isReConnect) {
		if(typeof opts === "boolean"){
			isReConnect = opts
			opts = {}
		}
		if(this.#isConnecting&&!isReConnect) return
		if (this.#isConnected) return
		this.#isConnecting = true
		this.#instance = uni.connectSocket({
			url: this.#url,
			header: opts.header || {},
			complete: () => {}
		});
		const onError = (errMsg)=>{
			// console.log(errMsg);
		}
		const onMessage = (data)=>{
			// console.log(data);
		}
		const onOpen = async ()=>{
			
		}
		const onClose = ()=>{
			
		}
		this.#event.on('onMessage', onMessage)
		this.#event.on('onError', onError)
		this.#event.on('onOpen', onOpen)
		this.#event.on('onClose', onClose)
		this.#instance.onOpen(async ()=>{
			this.#isConnected = true
			this.#isConnecting = false
			this.#time = 0
			this.#event.emit('#msg', "客户端已连接")
			this.#event.emit('onOpen', isReConnect)
			// this.heartTime()
			if(isReConnect){
				this.send({"reconnect": true})
			}
		})
		this.#instance.onClose(()=>{
			this.#isConnected = false
			this.#isConnecting = false
			this.#instance = null
			// this.clearHeartTime()
			this.#event.off("onClose", onClose)
			this.#event.off("onError", onError)
			this.#event.off("onOpen", onOpen)
			this.#event.off("onMessage", onMessage)
			if(!this.#isClose){
				this.#time++
				if(this.#time<=this.#maxTime){
					this.#isConnecting = true
					setTimeout(()=>{
						this.#event.emit('#msg', `第${this.#time}次重连`)
						// 重连
						this.initConnect(opts, true)
					},2000)
				}else{ 
					this.#event.emit('#msg', "客户端已离线,请重试")
					this.#event.emit('onClose')
				}
			}else{
				this.isClose = false
				this.#event.emit('#msg', "客户端已离线")
				this.#event.emit('onClose')
			}
		})
		this.#instance.onError((errMsg)=>{
			this.#event.emit('onError', errMsg)
		})
		this.#instance.onMessage((data)=>{
			// let rData = JSON.parse(decodeURIComponent(data.data).slice(0,-66));
			let rData = JSON.parse(decodeURIComponent(data.data));
			if(rData.hasOwnProperty("ping")) return
			this.#event.emit('onMessage',rData)
		})
	}
}

export default new Sc()