    import { socketService } from '../../main';
    import { Constants } from 'const/constants';

    const state = {
      joinableGames: [],
      /** @type {import('type/comm').CommStatus} */
      loadGamesStatus: { status: Constants.REQ_IDLE, text: 'Not connected' },
      connectionStatus: { status: Constants.REQ_IDLE, text: 'Not connected' },
      createGameStatus: { status: Constants.REQ_IDLE, text: 'Not connected' },
      joinGameStatus: { status: Constants.REQ_IDLE, text: 'Not connected' }
    };

    const getters = {
      joinableGames(state) {
        return state.joinableGames;
      },
      connectionStatus(state) {
        return state.connectionStatus;
      },
      loadGamesStatus(state) {
        return state.loadGamesStatus;
      },
      createGameStatus(state) {
        return state.createGameStatus;
      },
      joinGameStatus(state) {
        return state.joinGameStatus;
      }
    };

    const mutations = {
      SET_JOINABLE_GAMES: (state, payload) => {
        state.joinableGames = payload;
      },
      SET_CONNECTION_STATUS: (state, payload) => {
        state.connectionStatus = payload;
      },
      SET_LOAD_GAMES_STATUS: (state, payload) => {
        state.loadGamesStatus = payload;
      },
      SET_CREATE_GAME_STATUS: (state, payload) => {
        state.createGameStatus = payload;
      },
      SET_JOIN_GAME_STATUS: (state, payload) => {
        state.joinGameStatus = payload;
      },
      RESET_ALL_STATUS: state => {
        let status = { status: Constants.REQ_IDLE, text: 'Not connected' };
        state.connectionStatus = status;
        state.loadGamesStatus = status;
        state.createGameStatus = status;
        state.joinGameStatus = status;
      }
    };

    const actions = {
      fetchJoinableGames: ({ commit, rootState }) => {
        let loadGamesStatus = {
          status: Constants.REQ_REQUESTED,
          text: 'Loading Games'
        };
        commit('SET_LOAD_GAMES_STATUS', loadGamesStatus);
        socketService
          .getGamesList(rootState.username)
          .then(games => {
            loadGamesStatus.status = Constants.REQ_SUCCESS;
            if (games.length === 0) {
              loadGamesStatus.text =
                'No games found, wait for a new or create one !';
            } else {
              loadGamesStatus.text = 'Online games loaded';
            }
            commit('SET_JOINABLE_GAMES', games);
            commit('SET_LOAD_GAMES_STATUS', loadGamesStatus);
          })
          .catch(() => {
            loadGamesStatus = {
              status: Constants.REQ_ERROR,
              text: 'Error reaching server'
            };
            commit('SET_LOAD_GAMES_STATUS', loadGamesStatus);
          });
      },
      connect: ({ commit }, payload) => {
        return new Promise((resolve, reject) => {
          let connectionStatus = {};
          if (payload === '') {
            connectionStatus = {
              status: Constants.REQ_ERROR,
              text: 'Enter a valid username'
            };

            commit('SET_CONNECTION_STATUS', connectionStatus);
            reject();
          } else {
            commit('SET_USERNAME', payload, { root: true });
            connectionStatus = {
              status: Constants.REQ_REQUESTED,
              text: 'Connecting...'
            };
            commit('SET_CONNECTION_STATUS', connectionStatus);
            socketService
              .connect(payload)
              .then(() => {
                connectionStatus = {
                  status: Constants.REQ_SUCCESS,
                  text: 'Connected as ' + payload
                };
                commit('SET_CONNECTION_STATUS', connectionStatus);
                commit('SET_IS_CONNECTED', true, { root: true });
                localStorage.setItem('username', payload);
                resolve();
              })
              .catch(err => {
                connectionStatus = {
                  status: Constants.REQ_ERROR,
                  text: 'Could not connect as ' + payload + ' (' + err + ')'
                };
                commit('SET_CONNECTION_STATUS', connectionStatus);
                commit('SET_USERNAME', '', { root: true });
                reject();
              });
          }
        });
      },
      createOnlineGame: ({ commit, rootState }, payload) => {
        let createGameStatus = {
          status: Constants.REQ_REQUESTED,
          text: 'Creating Game'
        };
        let game = {
          player1: rootState.username,
          player2: '',
          deck: payload.deckMode,
          advRules: payload.advRules,
          status: 'CREATED',
          data: '{}'
        };
        commit('SET_CREATE_GAME_STATUS', createGameStatus);

        socketService
          .createGame(game)
          .then(id => {
            createGameStatus.status = Constants.REQ_SUCCESS;
            createGameStatus.text = 'Success creating online game ' + id;
            commit('SET_CREATE_GAME_STATUS', createGameStatus);
            commit('SET_GAME_ID', id, { root: true });
            commit('SET_IS_GAME_RUNNING', true, { root: true });
          })
          .catch(() => {
            createGameStatus = {
              status: Constants.REQ_ERROR,
              text: 'Error reaching server'
            };
            commit('SET_CREATE_GAME_STATUS', createGameStatus);
          });
      },
      joinOnlineGame: ({ commit, rootState }, payload) => {
        let joinGameStatus = {
          status: Constants.REQ_REQUESTED,
          text: 'Joining Game'
        };
        commit('SET_JOIN_GAME_STATUS', joinGameStatus);

        socketService
          .joinGame(rootState.username, payload.id, payload.isNew)
          .then(() => {
            joinGameStatus.status = Constants.REQ_SUCCESS;
            joinGameStatus.text = 'Success joining online game ' + payload.id;
            commit('SET_JOIN_GAME_STATUS', joinGameStatus);
            commit('SET_GAME_ID', payload.id, { root: true });
            commit('SET_IS_GAME_RUNNING', true, { root: true });
            if (!payload.isNew) {
              localStorage.setItem('gameId', payload.id);
            }
          })
          .catch(() => {
            joinGameStatus.status = Constants.REQ_ERROR;
            joinGameStatus.text = 'Error +-reaching server';
            commit('SET_JOIN_GAME_STATUS', joinGameStatus);
          });
      }
    };
    export default {
      namespaced: true,
      state,
      getters,
      mutations,
      actions
    };