// 
import {
	paramsToStr
} from './tools'
class Socket {
	constructor(url, data) {
		this.connected = false
		this.error = false
		this.url = `${url}${paramsToStr(data)}`
		this.socketTask = {}
		this.reconnectLock = true
		this.reconnectTimeout = null
		this.reconnectNums = 0
		// 心跳
		this.timeout = 10000
		this.clientTimeout = null
		this.serverTimeout = null
	}
	// 允许的订阅
	events = {
		connect: null,
		close: null,
		message: null,
		error: null,
		open: null
	}

	// 添加订阅
	addEvent(type, callback) {
		this.events[type] = callback
	}

	// 触发订阅
	dispatch(type, data) {
		const fun = this.events[type]
		fun && fun(data)
	}

	connect() {
		// 已经连接则无需重复连接
		if (this.connected) return
		this.dispatch('connect')
		this.socketTask = uni.connectSocket({
			url: this.url,
			complete: () => {}
		})
		this.socketTask.onOpen(this.onOpen.bind(this))
		this.socketTask.onError(this.onError.bind(this));
		this.socketTask.onMessage(this.onMessage.bind(this))
		this.socketTask.onClose(this.onClose.bind(this));
	}
	close() {
		this.reconnectLock = false
		clearTimeout(this.clientTimeout)
		clearTimeout(this.serverTimeout)
		
		this.socketTask.close && this.socketTask.close()
		
	}
	reconnect() {
		if (!this.reconnectLock) {
			return
		}
		// 重连次数过多,断开不重连
		if (this.reconnectNums >= 5) {
			return
		}

		this.reconnectNums++
		this.reconnectLock = false
		// 延迟重连请求过多
		clearTimeout(this.reconnectTimeout)
		this.reconnectTimeout = setTimeout(() => {
			this.connect()
			this.reconnectLock = true
		}, 4000)
	}
	start() {
		clearTimeout(this.clientTimeout)
		clearTimeout(this.serverTimeout)
		this.clientTimeout = setTimeout(() => {
			this.send({
				event: 'ping'
			})
			this.serverTimeout = setTimeout(() => {
				this.socketTask.close()
			}, this.timeout)
		}, this.timeout)
	}

	reset() {
		this.reconnectNums = 0
		this.start()
	}

	send(data) {
		// 如果socket已连接则发送消息
		if (!this.connected) {
			return
		}
		let datas = JSON.stringify(data)
		// console.log('发送信息:' + datas)
		this.socketTask.send({
			data: datas,
		})
	}
	onOpen() {
		this.connected = true

		// 开启心跳
		this.start()

		// console.log('连接成功')

		this.dispatch('open')
	}
	onError(res) {
		this.error = true
		this.connected = false
		this.dispatch('error')
		// console.log('连接错误', res)
	}
	onMessage({data}) {
		this.dispatch('message', JSON.parse(data))
		// console.log('收到信息:', data)
		// 重置心跳
		this.reset()
	}
	onClose(res) {
		this.dispatch('close')
		// console.log('连接已关闭', res)
		this.connected = false
		this.reconnect()
	}

}
export default Socket