/* eslint-disable */
let tt;
let count = 1;
let lockReconnect = false;
function isJsonString(str) {
  try {
    if (typeof JSON.parse(str) === "object") {
      return true;
    }
  } catch (e) { }
  return false;
}

function reconnect(dispatch) {
  if (lockReconnect || count > 5) {
    return;
  }
  lockReconnect = true;
  count = count + 1;
  tt && clearTimeout(tt);
  tt = setTimeout(() => {
    dispatch("createWebSocket");
    lockReconnect = false;
  }, Math.pow(2, count) * 1000);
}

export default {
  namespaced: true,
  state: {
    socket: {
      isConnected: false,
      message: "",
      count: 0,
      lockReconnect: false,
      reconnectError: false
    },
    websocket: null
  },
  getters: {
    message: state => state.socket.message,
    isConnected: state => state.socket.isConnected
  },
  actions: {
    createWebSocket({ state, commit, dispatch }) {
      if ("WebSocket" in window) {
        state.websocket = new WebSocket(process.env.VUE_MESSAGE_WEBSOCKET);
      } else if ("MozWebSocket" in window) {
        state.websocket = new MozWebSocket(process.env.VUE_MESSAGE_WEBSOCKET); // eslint-disable-line
      } else {
        state.websocket = new SockJS(process.env.VUE_MESSAGE_WEBSOCKET); // eslint-disable-line
      }
      state.websocket.onclose = () => {
        reconnect(dispatch);
      };
      state.websocket.onerror = () => {
        reconnect(dispatch);
      };
      state.websocket.onopen = () => {
        count = 1;
        commit("SOCKET_CONNECTED", true);
        setInterval(() => state.websocket.send("ping"), 30000);
      };
      state.websocket.onmessage = event => {
        if (isJsonString(event.data)) {
          commit("SOCKET_MESSAGE", event.data);
        }
      };
    },
    sendMessage({ state }, message) {
      return new Promise((resolve) => {
        state.websocket.send(JSON.stringify(message))
        resolve()
      })
    }
  },
  mutations: {
    SOCKET_CONNECTED(state, isConnected) {
      state.socket = {
        ...state.socket,
        isConnected
      };
    },
    SOCKET_MESSAGE(state, message) {
      state.socket = {
        ...state.socket,
        message
      };
    }
  }
};