import {showToast} from "@/utils/app";
import config from "@/utils/config";
import {logs} from "@/utils/util";
import store from "@/store";

export class Socket {

  constructor() {
    this.socketTask = null
    this.connectRun = false
    this.isOpen = false //避免重复连接
    this.option = {
      connectNum: 1,// 重连次数
      connectMaxNum: 3,// 重连最大次数
      reconnectTime: 3000,// 重连最大间隔时间
      heartInterval: 15000, // 心跳间隔
    }
    this.followFlake = false // followFlake == true 重连
    //心跳检测
    this.heartbeatInterval = null //检测服务器端是否还活着
    this.reconnectTimeOut = null //重连之后多久再次重连

    this.connectList = {}
    this.openFun = {}
    this.messageFun = {}
    this.closeFun = {}
  }

  // 进入这个页面的时候创建websocket连接【整个页面随时使用】
  async connect() {
    return new Promise(async (resolve, reject) => {
      if (this.socketTask || this.connectRun) {
        resolve()
        return;
      }
      let that = this
      this.connectRun = true
      try {
        this.socketTask = uni.connectSocket({
          url: config.get('socketWss') + `?form=teacher&token=${store.getters['user/loginToken']}`,
          // header: {
          //   // 'content-type': 'application/json',
          //   form: 'teacher',
          //   token: store.getters['user/loginToken'],
          // },
          success: () => {
            logs("正准备建立websocket中...");
            // 返回实例
          },
          fail: (err) => {
            logs("× 建立websocket失败");
            reject()
            // 返回实例
          },
        });


        this.socketTask.onOpen((res) => {
          console.log('onOpen', res)
          this.option.connectNum = 1
          logs("WebSocket连接正常！");
          clearInterval(this.reconnectTimeOut)
          clearInterval(this.heartbeatInterval)
          this.isOpen = true;
          this.start();
          resolve()
        })
        this.connectRun = false
        this.socketTask.onMessage(async (e) => {
          // 字符串转json
          let res = JSON.parse(e.data);
          // if (res.type != 'ping') logs("res---------->", res) // 这里 查看 推送过来的消息
          let k = res.type
          if (k) {
            let key = this.connectList[k]
            if (!key) return
            let fun = this.messageFun[key]
            if (fun) await fun(res)
          } else {
            console.log('未知内容', res)
          }
        });
        // 监听连接失败，这里代码我注释掉的原因是因为如果服务器关闭后，和下面的onclose方法一起发起重连操作，这样会导致重复连接
        this.socketTask.onError((res) => {
          logs('WebSocket连接打开失败，请检查！', res);
          // this.socketTask = null
          // this.isOpen = false;
          // uni.$off('getPositonsOrder')

          // if (!this.isOpen) {
          //   if (this.option.connectNum < this.option.connectMaxNum) {
          //     uni.showToast({
          //       title: `WebSocket连接失败，正尝试第${this.option.connectNum}次连接`,
          //       icon: "none"
          //     })
          //     this.reconnect();
          //     this.option.connectNum += 1
          //   } else {
          //     // uni.$emit('connectError');
          //     this.reconnect(false);
          //   }
          // }
        });
        // 这里仅是事件监听【如果socket关闭了会执行】
        this.socketTask.onClose(async () => {
          logs("socketTask 已经被关闭了-------")
          clearInterval(this.heartbeatInterval)
          clearInterval(this.reconnectTimeOut)
          this.socketTask = null
          this.isOpen = false;
          for (const k in that.closeFun) {
            that.closeFun[k]()
          }
        })
      } catch (e) {

      }
    })
  }

  // 主动关闭socket连接
  close() {
    if (!this.socketTask) return
    this.socketTask.close({
      success() {
        showToast('SocketTask 关闭成功')
      }
    });
  }

  //发送消息
  send(data, success = null, fail = null) {
    // 注：只有连接正常打开中 ，才能正常成功发送消息
    if (this.socketTask && this.isOpen) {
      this.socketTask.send({
        data: JSON.stringify(data),
        async success() {
          if (success) success()
        },
        async fail(e) {
          console.error(`推送服务器失败：${e}`)
          if (fail) fail()
        },
      });
    }
  }

  //开启心跳检测
  start() {
    this.heartbeatInterval = setInterval(() => {
      this.send({
        "type": "ping"
      });
    }, this.option.heartInterval)
    // 重连
    for (const k in this.openFun) {
      this.openFun[k]()
    }
  }

  //重新连接
  reconnect(run = true) {
    //停止发送心跳
    clearInterval(this.heartbeatInterval)
    //如果不是人为关闭的话，进行重连
    clearTimeout(this.reconnectTimeOut)
    this.reconnectTimeOut = null
    if (run && !this.isOpen && !this.connectRun) {
      this.reconnectTimeOut = setTimeout(() => {
        this.connect();
      }, this.option.reconnectTime)
    } else if (!run) {
      this.option.connectNum = 1
    }
  }

  stopHeartRate() {
    clearInterval(this.heartbeatInterval)
  }

  addConnect(type, key) {
    this.connectList[type] = key
  }

  delConnect(deviceId) {
    if (this.connectList[deviceId]) delete this.connectList[deviceId]
  }

  // init() {
  //   if (this.connectState) return;
  //   let socketWss = config.get('socketWss')
  //   if (!socketWss) return;
  //   this.username = store.getters['user/username']
  //   let that = this
  //   let connectSocket = uni.connectSocket({
  //     url: socketWss,
  //     header: {
  //       'content-type': 'application/json'
  //     },
  //   });
  //   uni.onSocketOpen(function (res) {
  //     that.connect = connectSocket
  //     that.connectState = !0
  //     showSuccess('投影成功')
  //     that.sendMessage({
  //       cmd: 'login',
  //       port: 'TeacherPc',
  //       username: that.username,
  //     })
  //   });
  //   uni.onSocketError(function (res) {
  //     showToast('连接实时投影展示失败')
  //     that.connectState = !1
  //   });
  //   uni.onSocketMessage(function (res) {
  //     if (!res.data) return;
  //     let {code, data, msg} = JSON.parse(res.data)
  //     logs('onSocketMessage', res.data)
  //     if (code == 50003) {
  //       that.sendMessage({
  //         cmd: 'online'
  //       })
  //     } else {
  //       logs('onSocketMessage', code, data, msg)
  //     }
  //   });
  // }
  //
  // /**
  //  * 发送信息
  //  * @param data
  //  */
  // sendMessage(data = {}) {
  //   if (!this.connectState) return;
  //   uni.sendSocketMessage({
  //     data: JSON.stringify(data)
  //   });
  // }
  //
  // /**
  //  * 关闭连接
  //  */
  // closeSocket() {
  //   if (!this.connectState) return;
  //   uni.closeSocket()
  // }

}
