//一个websocket调度中心类的示例
import { API_CHAT_SEND } from '@/constants/api'

class IMManager {
  //构造消息类，需要参数：消息类型
  constructor() {
    this.wss = null
    this.socketMsgQueue = []
    this.socketOpen = false
    this.lockReconnect = false
    this.limit = 12
    this.selfClose = false
    this.timeTicker = undefined
    this.messageListeners = []
    this.imMessageListener = undefined
  }

  reconnect() {
    if (!this.option) return;
    if (this.socketOpen) return;
    if (this.lockReconnect) return;

    this.lockReconnect = true;
    clearTimeout(this.timer)
    console.log('reconnect')

    if (this.limit--) {
      this.timer = setTimeout(() => {
        this.createSocket(this.option);
        this.lockReconnect = false;
      }, 100);
    } else {
      console.warn('您已重新连接' + this.limit + '次了,已达上限')
    }
  }

  //建立socket连接
  createSocket(option) {
    const { id, success, close, receive, fail } = option
    this.option = option
    this.selfClose = false

    this.wss = wx.connectSocket({
      url: `${API_CHAT_SEND}/${id}`,
      header: {
        'content-type': 'application/json'
      },
      method: 'GET'
    })

    this.wss.onOpen(res => {
      this.socketOpen = true
      for (let i = 0; i < this.socketMsgQueue.length; i++) {
        this.sendSocketMessage(this.socketMsgQueue[i])
      }
      this.socketMsgQueue = []
      success && success(res)
    })

    this.wss.onMessage((data) => {
      if (data.data === 'ping') {
        this.wss.send({ data: 'pong'  })
      } else if (data.data === 'pong') {
        console.log('[websocket]: 接收心跳')
      } else {
        if (this.imMessageListener) {
          this.imMessageListener(data)
        } else {
          this.messageListeners.forEach(fn => fn(data))
        }
      }
    })

    this.wss.onClose(res => {
      console.log('已关闭', res)
      close && close(res)
      this.socketOpen = false

      // 手动关闭的就不要重启了 
      if (!this.selfClose) {
        this.reconnect()
      }
    })

    this.wss.onError(err => {
      console.log('打印错误', err)
      fail && fail(err)
      this.socketOpen = false
      
      if (!this.selfClose) {
        this.reconnect()
      }
    })

    this.timeTicker = setInterval(() => {
      if (this.limit <= 0) {
        clearInterval(this.timeTicker)
      }

      if (this.socketOpen) {
        this.wss.send({ data: 'ping', success: () => console.log('[websocket]: 发送心跳') })
      }
    }, 60000)
  };

  //组装消息
  makeUpNotice(send_id, consult_id, room_id, type, content, duration) {
    return {
      send_id: send_id,
      consult_id: consult_id,
      room_id: room_id,
      type: type,
      content: content,
      time_long: duration,
      read_status: type == 2 ? 0 : 1
    }
  };

  closeSocket() {
    if (this.socketOpen) {
      this.selfClose = true
      clearTimeout(this.timer)
      wx.closeSocket({
        code: 1000,
        reason: '退出页面'
      })
      this.socketOpen = false
      console.log('已退出 scoket')
    } else {
      console.error('scoket 没有启动')
    }
  }

  //向服务器发送notice
  sendNotice(payload, cb) {
    if (this.socketOpen) {
      this.wss.send({
        data: JSON.stringify(payload),
        success: function (res) {
          cb && cb(res)
          console.log('socket发送成功')
        },
        fail(err) {

          console.log(err, '发送失败了')
          Taro.showToast({
            title: '发送失败',
            icon: 'none'
          })
        }
      })
    } else {
      // this.socketMsgQueue.push(payload)
          Taro.showToast({
            title: '失败: 请退出小程序重试',
            icon: 'none'
          })
    }
  }

  onMessage(callback, isIMPage) {
    if (!isIMPage) {
      this.messageListeners = [callback]
    } else {
      this.imMessageListener = callback

      // 取消订阅
      return () => this.imMessageListener = undefined
    }
  }
}

export default new IMManager()

const MESSAGETYPE = {
  IMAGE: 'image',
  TEXT: 'text',
  CARD: 'card',
}

export {
  MESSAGETYPE
}
