import EventEmitter from 'events';
import { Modal } from 'antd';

class Socket extends EventEmitter {
  event = new EventEmitter();

  constructor(options) {
    super();
    this.options = options;
    this.reconnectCount = 0;
    this.socket = null;
    this.taskRemindInterval = null;
    this.connected = false;
    this.waitingSendData = [];
    this.reconnectCount = 0;
    this.heartBeatTimer = null;
    return this;
  }

  connection = () => {
    const { url, timeout = 0 } = this.options;
    // 检测当前浏览器是什么浏览器来决定用什么socket
    if ('WebSocket' in window) {
      console.log('WebSocket');
      this.socket = new WebSocket(url);
    } else if ('MozWebSocket' in window) {
      console.log('MozWebSocket');
      // eslint-disable-next-line no-undef
      this.socket = new MozWebSocket(url);
    } else {
      console.log('SockJS');
      // eslint-disable-next-line no-undef
      this.socket = new SockJS(url);
    }

    // 链接回调
    this.socket.onopen = this.onopen;
    this.socket.onmessage = this.onmessage;
    this.socket.onclose = this.onclose;
    this.socket.onerror = this.onerror;
    this.socket.sendMessage = this.sendMessage;

    // 检测返回的状态码 如果socket.readyState不等于1则连接失败，关闭连接
    if (timeout) {
      const time = setTimeout(() => {
        if (this.socket && this.socket.readyState !== 1) {
          console.log('主动触发关闭');
          this.socket.close();
        }
        clearTimeout(time);
      }, timeout);
    }
  };

  // 连接成功触发
  onopen = () => {
    const { heartBeatTime } = this.options;
    console.log('ws: 连接成功', new Date().getTime());
    this.connected = true;
    this.heartBeat(heartBeatTime);
    this.checkWaitingData();
    this.event.emit('open');
  };

  // 后端向前端推得数据
  onmessage = msg => {
    console.log('ws：接收数据:', msg);
    this.event.emit('message', msg);
    // 打印出后端推得数据
  };

  // 关闭连接触发
  onclose = e => {
    console.log('ws: 关闭连接', new Date().getTime());
    this.connected = false; // 关闭将标识符改为true
    if (this.heartBeatTimer) {
      clearTimeout(this.heartBeatTimer);
    }
    this.event.emit('close', e);
    // 最多重连10次
    if (this.reconnectCount > 10) {
      this.reconnectCount = 0;
      return;
    }
    const reconnect = () => {
      if (this.taskRemindInterval) {
        clearTimeout(this.taskRemindInterval);
      }
      this.taskRemindInterval = setTimeout(() => {
        if (!this.connected) {
          this.reconnectCount++;
          this.connection();
          reconnect();
        }
      }, 5000);
    };
    if (process.env.NODE_ENV === 'production') {
      reconnect();
    }
  };

  onerror = e => {
    try {
      this.socket = null;
      this.event.emit('error', e);
    } catch {
      console.log('ws: error', e);
    }
  };

  sendMessage = value => {
    console.log('ws: send', value);
    // 向后端发送数据
    if (this.socket) {
      if (!this.connected) {
        this.waitingSendData.unshift(value);
        return;
      }
      const sendValue = typeof value === 'string' ? value : JSON.stringify(value);
      this.socket.send(sendValue);
    }
  };

  checkWaitingData() {
    console.log('ws: checkWaitingData', this.waitingSendData);
    if (this.waitingSendData.length) {
      this.sendMessage(this.waitingSendData.splice(0, 1));
      this.checkWaitingData();
    }
  }

  // 保持连接-默认每3分钟重置一下服务器关闭时间
  heartBeat(time) {
    // console.log('ws: call heartBeat', new Date().getTime());
    this.heartBeatTimer = setTimeout(() => {
      // console.log('ws: sent heart beat', new Date().getTime());
      this.sendMessage('HeartBeat');
      this.heartBeat(time);
    }, time || 45000);
  }
}

export default Socket;
