'use strict';
import io from 'socket.io-client';
/* eslint-disable no-console */

const SERVER_URL = process.env.VUE_APP_SERVER_CONN + '://' + process.env.VUE_APP_SERVER_HOST;
const SERVER_PORT = process.env.VUE_APP_SERVER_PORT;

export default function SocketService(socketEventBus, vuexStore) {
  let store = vuexStore;
  let ioClient = null;
  let connect = function (name) {
    let promise = new Promise((resolve, reject) => {
      let serverUrl = SERVER_URL;
      if (SERVER_PORT != "") {
        serverUrl += ':' + SERVER_PORT;
      }
      ioClient = io(serverUrl, {
        reconnectionAttempts: 2
      });

      ioClient.on('disconnect', reason => {
        if (reason !== 'io client disconnect') {
          console.log('Connection with server lost unexpectidly : ' + reason);
          // this.ioClient.close();
        }
      });

      ioClient.on('connect', () => {
        console.log('Connected to server');
        ioClient.emit('auth', name, function (response) {
          if (response.res === 'ok') {
            resolve(response.message);
          } else {
            reject(response.message);
          }
        });
      });

      ioClient.on('connect_error', () => {
        console.log('connect_error to server');
      });

      ioClient.on('reconnect_failed', () => {
        console.log('reconnect_failed to server');
        reject(new Error('Cannot reach server'));
      });

      ioClient.on('reload-games-list', () => {
        console.log('force reload games list !');
        store.dispatch('menu/fetchJoinableGames');
      });
      ioClient.on('message', message => {
        store.dispatch('addMessageToQueue', message);
      });
      ioClient.on('update-game-data', data => {
        if (data && data.game) {
          store.dispatch('game/update', data);
        }
      });
    });
    return promise;
  };

  let checkConnection = function (playername) {
    if (ioClient && ioClient.connected === false) {
      return connect(playername);
    } else {
      return Promise.resolve('Still connected');
    }
  };

  let disconnect = function () {
    console.log('Manual client disconnect');
    ioClient.close();
  };
  let getGamesList = function (playername) {
    return checkConnection(playername).then(
      () => {
        return new Promise((resolve, reject) => {
          ioClient.emit('games-list', playername, function (response) {
            if (response.res === 'ok') {
              resolve(response.message);
            } else {
              reject(response.message);
            }
          });
        });
      },
      error => Promise.reject(error)
    );
  };

  let createGame = function (game) {
    return checkConnection(game.player1).then(
      () => {
        return new Promise((resolve, reject) => {
          ioClient.emit('create-game', game, function (response) {
            if (response.res === 'ok') {
              resolve(response.message);
            } else {
              reject(response.message);
            }
          });
        });
      },
      error => Promise.reject(error)
    );
  };
  let joinGame = function (username, gameId, joinCreatedGame) {
    return checkConnection(username).then(
      () => {
        return new Promise((resolve, reject) => {
          ioClient.emit('join-game', { id: gameId, joinCreatedGame }, function (
            response
          ) {
            if (response.res === 'ok') {
              resolve(response.message);
            } else {
              reject(response.message);
            }
          });
        });
      },
      error => Promise.reject(error)
    );
  };
  let leaveGame = function (username) {
    return checkConnection(username).then(
      () => {
        return new Promise(resolve => {
          ioClient.emit('leave-game', username, function (response) {
            resolve(response);
          });
        });
      },
      error => Promise.reject(error)
    );
  };
  let endTurn = function (payload) {
    return checkConnection(payload.username).then(
      () => {
        return new Promise(resolve => {
          ioClient.emit('end-turn', payload);
          resolve();
        });
      },
      error => Promise.reject(error)
    );
  };

  let chat = function (message) {
    ioClient.emit('chat', message);
  };
  return {
    connect,
    disconnect,
    getGamesList,
    createGame,
    leaveGame,
    joinGame,
    endTurn,
    chat
  };
}
