var socket;

// 名前空間
var CHAT_SOCKET = {};

CHAT_SOCKET.socketCheck = function () {
  if (socket == null || socket.disconnected) {
    window.location.reload();
  }
};

CHAT_SOCKET.connectSocket = function () {
  if (serverInfo.isOnline == true) {
    socket = io(serverInfo.chatURL);
    setSocketAction();
  } else {
    //オフラインの場合、DBからルーム一覧を表示。
    if (deviceInfo.isiOS()) {
      //TODO IOSの場合
    } else if (deviceInfo.isAndroid()) {
    }
  }
};

function setSocketAction() {
  /* ---------------------------------------------------
   * Socket Connect/Disconnect
   * --------------------------------------------------- */
  bindOnConnect();
  bindOnDisconnect();
  bindOnConnectError();

  /* ---------------------------------------------------
   * Chat Room List Tab
   * --------------------------------------------------- */
  CHAT_SOCKET.bindOnNewMessage();
  bindOnNewNotification();
  bindOnRefreshGroupList();
  bindOnRefreshUserListInGroup();

  /* ---------------------------------------------------
  /* Show Error Log
  /* --------------------------------------------------- */
  bindOnShowServerError();
  bindOnRetryJoinProcess();
}

var bindOnConnect = function () {
  socket.on(SOCKET_KEY.CONNECT, function () {
    // socketが接続されたらチャット画面で画面を更新する
    $(".overlay").removeClass("active undismissable");
  });
};

var bindOnDisconnect = function () {
  socket.on(SOCKET_KEY.DISCONNECT, function () {
    //socketが切断されたら黒画面で画面を更新する
    $(".overlay").addClass("active undismissable");
    Common.dismissLoadingIndicator();
  });
};

var bindOnConnectError = function () {
  socket.on(SOCKET_KEY.CONNECT_ERROR, function () {
    Common.dismissLoadingIndicator();
  });
};

var bindOnNewNotification = function () {
  // Notification
  socket.on(SOCKET_KEY.NEW_NOTIFICATION, function (keyword, event) {
    const notificationString = getLocalizedString(event, keyword);
    $("#messageNotification")
      .finish()
      .text(notificationString)
      .delay(500)
      .slideDown()
      .delay(1500)
      .slideUp();
  });
};

var bindOnRefreshGroupList = function () {
  // Update Group List(Invite)
  socket.on(SOCKET_KEY.REFRESH_GROUPLIST, function (groups, isInvite) {
    const groupListElement = $("#group_list");
    groupListElement.html("");

    if (groups.length === 0) {
      groupListElement.append(
        '<center class="text-secondary">' +
          getLocalizedString(everyoneIsHere) +
          "</center>"
      );
    }

    $("#newRoomName").hide();
  });
};

var bindOnShowServerError = function () {
  socket.on(SOCKET_KEY.SHOW_SERVER_ERROR, function (message) {
    // #36215
    if (message.includes("SC_FORBIDDEN")) {
      alert("SC_FORBIDDEN");
      return;
    }

    if (message == "server error Ocurred") {
      message = getLocalizedString("serverErrorOccured");
    } else if (message == "Room not found") {
      message = getLocalizedString("errorRoomNotFound");
    }
    $("#customAlertTitle").text(message);
    $("#customAlertOk").text(getLocalizedString("yesTitle"));

    $("#customAlert")
      .appendTo("body")
      .modal({
        backdrop: "static",
        keyboard: false,
      })
      .on("click", "#customAlertOk", function (e) {});
    Common.dismissLoadingIndicator();

    if (message == "Room not found") {
      CHAT_SOCKET.saveRoomInfo();
    }
  });
};

var bindOnRetryJoinProcess = function () {
  socket.on(SOCKET_KEY.RETRY_JOIN_PROCESS, function () {
    currentUserInfo.configureLanguage();
    const joinInfo = new JoinInfo(
      currentUserInfo.sid,
      currentUserInfo.loginID,
      currentUserInfo.shopName,
      roomInfo.roomID,
      roomInfo.roomName,
      currentUserInfo.shopMemberID
    );
    // webでのsocket connect
    CHAT_SOCKET.emitJoin(joinInfo, true, true);
  });
};

CHAT_SOCKET.emitJoin = function (
  joinInfo,
  needsDismissLoadingIndicator,
  needsHandlingError
) {
  socket.emit(SOCKET_KEY.JOIN, joinInfo, function (err) {
    if (err) {
      if (needsHandlingError) {
        errorHandlingForEmitJoin();
      }
      if (needsDismissLoadingIndicator) {
        Common.dismissLoadingIndicator();
      }
      return;
    }

    if (needsDismissLoadingIndicator) {
      // loadingIndicatorを表示しない
      Common.dismissLoadingIndicator();
    }
  });
};

var errorHandlingForEmitJoin = function () {
  // #36174
  $("#customAlertTitle").text(err);
  $("#customAlertOk").text(getLocalizedString("yesTitle"));

  $("#customAlert")
    .appendTo("body")
    .modal({
      backdrop: "static",
      keyboard: false,
    })
    .on("click", "#customAlertOk", function (e) {});
};

var bindOnRefreshUserListInGroup = function () {
  // Update User List(Invite)
  // #36170
  socket.on(
    SOCKET_KEY.REFRESH_USERLIST_INGROUP,
    function (users, groupId, isInvite) {
      console.debug(
        SOCKET_KEY.REFRESH_USERLIST_INGROUP +
          "message received but it does nothing."
      );
    }
  );
};

var nextFibonacci = function (num) {
  let nextNum = (num * (1 + Math.sqrt(5))) / 2.0;
  return Math.round(nextNum);
};

CHAT_SOCKET.emitCreateMessage = function (socketKey, sendData) {
  if (socket.connected == false) {
    CHAT_SOCKET.reconnectCreateMessage(socketKey, sendData);
  } else {
    socket.emit(socketKey, { text: sendData });
  }
};

CHAT_SOCKET.emitCreateText = function (sendData) {
  CHAT_SOCKET.emitCreateMessage(SOCKET_KEY.CREATE_TEXT, sendData);
};

CHAT_SOCKET.emitCreateImage = function (sendData) {
  CHAT_SOCKET.emitCreateMessage(SOCKET_KEY.CREATE_IMAGE, sendData);
};

CHAT_SOCKET.emitCreateVideo = function (sendData) {
  CHAT_SOCKET.emitCreateMessage(SOCKET_KEY.CREATE_VIDEO, sendData);
};

CHAT_SOCKET.emitCreateCommunicationStart = function (
  sendData,
  collaborationType,
  meetingID
) {
  if (socket.connected == false) {
    CHAT_SOCKET.reconnectCreateMessage(
      SOCKET_KEY.COMMUNICATION,
      sendData,
      collaborationType,
      meetingID
    );
  } else {
    socket.emit(
      SOCKET_KEY.COMMUNICATION,
      { text: sendData },
      collaborationType,
      meetingID
    );
  }
};

CHAT_SOCKET.reconnectCreateMessage = function (
  socketKey,
  sendData,
  timeout = 100,
  collaborationType = null,
  meetingID = null
) {

  if (socket.connected == false) {
    console.info("socket disconnected, reconnect...  " + timeout);
    CHAT_SOCKET.initialJoin();
    setTimeout(function () {
      CHAT_SOCKET.reconnectCreateMessage(
        socketKey,
        sendData,
        nextFibonacci(timeout)
      );
    }, timeout);
    return;
  }

  console.info("socket reconnected");
  if (collaborationType == null) {
    socket.emit(socketKey, { text: sendData });
  } else {
    socket.emit(socketKey, { text: sendData }, collaborationType, meetingID);
  }
};

CHAT_SOCKET.emitCollaborationFinishMessage = function () {
  if (socket != null && socket.connected) {
    const sendData = DATA_MESSAGE_SCHEME + FINISH_ALL_COLLABORATION_SIGNAL;
    CHAT_SOCKET.emitCreateMessage(SOCKET_KEY.CREATE_MESSAGE, sendData);
  }
};

CHAT_SOCKET.emitGetGroupList = function (isInvite) {
  socket.emit(SOCKET_KEY.GET_GROUP_LIST, isInvite);
};

CHAT_SOCKET.emitLeaveRoom = function () {
  socket.emit(SOCKET_KEY.LEAVE_ROOM, function () {});
};

CHAT_SOCKET.saveRoomInfo = function (roomID, roomName) {
  roomInfo.roomID = roomID;
  roomInfo.roomName = roomName;
  NativeBridgeDelegate.saveVisitRoomInfo(roomID, roomName);
};

CHAT_SOCKET.initialJoin = function () {
  CHAT_SOCKET.connectSocket();
  const joinInfo = new JoinInfo(
    currentUserInfo.sid,
    currentUserInfo.loginID,
    currentUserInfo.shopName,
    roomInfo.roomID,
    roomInfo.roomName,
    currentUserInfo.shopMemberID
  );
  CHAT_SOCKET.emitJoin(joinInfo, false, false);
};
