//心跳检测
const heartCheck = {
  timeout: 10000, //10s发一次心跳
  timeoutObj: null,
  serverTimeoutObj: null,
  start(ws) {
    let self = this;
    this.timeoutObj && clearTimeout(this.timeoutObj);
    this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
    this.timeoutObj = setTimeout(() => {
      // 表示连接已经关闭或者连接不能打开。
      if (ws && ws.readyState === 3) return;
      //发送一个心跳，后端收到后，返回一个心跳消息，onmessage拿到返回的心跳就说明连接正常
      ws && ws.send({ data: "ping" });
      self.serverTimeoutObj = setTimeout(() => {
        ws && ws.close();
        websocket.reconnect();
      }, self.timeout + 3000);
    }, this.timeout);
  }
};

const websocket = {
  ws: null,
  url: '',
  connected: false,
  connecting: false,
  reconnectTimeId: null,
  callback: null, // 存放回调函数
  reconnetCount: 0, // 重连次数
  lockReconnect: false, // 避免ws重复连接
  createWebSocket(callback) {

    if (this.connected || this.connecting) { // 正在连接或者已经连接，请勿重复连接
      return false
    }
    try {
      if (callback) websocket.callback = callback;
      this.connecting = true;
      // 创建
      this.ws = uni.connectSocket({
        url: this.url,
        success(data) {
          console.log("websocket连接成功!");
        }
      });
      // 监听 Ws 连接打开
      this.ws.onOpen((res) => {
        this.connecting = false;
        this.connected = true;
        console.log("websocket连接打开正常!");
        //心跳检测重置
        heartCheck.start(this.ws);
        this.reconnetCount && (this.reconnetCount = 0);
      });
      this.ws.onError((res) => {
        this.connecting = false;
        this.connected = false;
        console.log("ws连接错误!", res);
        this.reconnect();
      });
      this.ws.onMessage((res) => {
        if (res.data === 'ping') {
          heartCheck.start(this.ws); //获取到消息，心跳检测重置
          // console.log("ws 没有收到消息");
          this.reconnetCount && (this.reconnetCount = 0);
        } else {
          // const { type, data } = JSON.parse(res.data);
          const { data } = res;
          // console.log("ws 收到消息啦:" + data);
          if (callback) {
            callback(data);
          } else if (websocket.callback) {
            websocket.callback(data);
          }
        }
      });
      this.ws.onClose((res) => {
        this.connected = false;
        this.ws = null;
        // console.log('WebSocket 已关闭！');
        // this.reconnect();
      });
    } catch (e) {// 重连
      this.connected = false;
      this.ws = null;
      this.reconnect();
    }
  },
  reconnect() { // 重连
    if (this.lockReconnect) return;
    if (this.reconnetCount === 6) {
      this.close();
      return
    }
    this.lockReconnect = true;
    this.reconnetCount++;
    this.reconnectTimeId && clearTimeout(this.reconnectTimeId);
    this.reconnectTimeId = setTimeout(() => {//没连接上会一直重连，设置延迟避免请求过多
      this.createWebSocket(websocket.callback);
      this.lockReconnect = false;
    }, 3000);
  },
  close() { // 关闭
    if (this.ws && this.ws.close) {
      this.ws.close && this.ws.close();
      this.ws = null;
    }
    this.connected = false;
    this.connecting = false;
    this.lockReconnect = false;
    this.reconnetCount = 0;
    this.reconnectTimeId && clearTimeout(this.reconnectTimeId);
    heartCheck.timeoutObj && clearTimeout(heartCheck.timeoutObj);
    heartCheck.serverTimeoutObj && clearTimeout(heartCheck.serverTimeoutObj);
  }
}

export default websocket;