CHAT_SOCKET.bindOnNewMessage = function () {
  // New Message
  // #36170
  socket.on(SOCKET_KEY.NEW_MESSAGE, function (message, roomID, roomName) {
    const systemMessageTemplate = getTemplate(TemplateURL.SYSTEM_MESSAGE);

    const unwrappedMessageInfo = CHAT_SOCKET.decodeMessage(message.text);
    if (
      unwrappedMessageInfo ==
      DATA_MESSAGE_SCHEME + FINISH_ALL_COLLABORATION_SIGNAL
    ) {
      CHAT_SOCKET.cleanUpCollaborationMessage();
      return;
    }

    if (unwrappedMessageInfo.includes(messageSeperator)) {
      const messageInfo = unwrappedMessageInfo.split(messageSeperator);
      const messageText = messageInfo[0];
      const messageType = messageInfo[1];

      if (
        messageType == MessageType.COMMUNICATIONSTART ||
        messageType == MessageType.COMMUNICATIONEND
      ) {
        CHAT_SOCKET.addCollaborationMessage(
          messageInfo,
          message.userId,
          roomName,
          message.insertDate,
          message.createdAt
        );
      } else {
        CHAT_SOCKET.addTextMessage(messageText, message, socket.id);
      }
    }

    if (typeof ChatRoom !== "undefined") {
      // 画像、動画の描画を待ってからスクロール
      setTimeout(function () {
        ChatRoom.scrollToBottom();
      }, 300);
    } else {
      Common.dismissLoadingIndicator();
    }
  });
};

CHAT_SOCKET.decodeMessage = function (text) {
  try {
    return decodeURIComponent(text);
  } catch (e) {
    return text;
  }
};

CHAT_SOCKET.addCollaborationMessage = function (
  messageInfo,
  userID,
  roomName,
  insertDate,
  createdAt
) {
  const collaborationType = CHAT_UTIL.getCollaborationType(messageInfo[2]);
  const meetingID = CHAT_SOCKET.getMeetingID(collaborationType, messageInfo);
  const userInCollaboration = JSON.parse(
    NativeBridgeDataSource.getUserInfoList(userID)
  );

  userInCollaboration.forEach(function (user) {
    user.profileUrl = Common.getProfileImgUrl(user.profileUrl);
  });

  const openCollaborationMessageTemplate = getTemplate(
    TemplateURL.OPEN_COLLABORATION_MESSAGE
  );

  const html = CHAT_SOCKET.renderCollaborationMessage(
    openCollaborationMessageTemplate,
    roomName,
    userInCollaboration,
    insertDate,
    collaborationType,
    meetingID,
    createdAt
  );

  $("#messages").prepend(html);
};

CHAT_SOCKET.getMeetingID = function (collaborationType, messageInfo) {
  if (collaborationType == COLLABORATION_TYPE.DOCUMENT) {
    return messageInfo[3];
  } else {
    return 0;
  }
};

CHAT_SOCKET.renderCollaborationMessage = function (
  template,
  roomName,
  userList,
  insertDate,
  collaborationType,
  meetingID,
  createdAt
) {
  let messageTime = CHAT_UTIL.formatDate(createdAt);
  return Mustache.render(template, {
    roomName: roomName,
    messageId: 0,
    userCount: 1,
    userList: userList,
    insertDate: insertDate,
    collaborationType: collaborationType,
    isToday: true,
    meetingId: meetingID,
    createdAtDay: messageTime.createdAtDay,
    createdAtTime: messageTime.createdAtTime,
    isOtherYear: false,
  });
};

CHAT_SOCKET.addTextMessage = function (messageText, message, socketID) {
  const messageTextWithSID = CHAT_SOCKET.insertSID(messageText);
  const messageSender = JSON.parse(
    NativeBridgeDataSource.getUserInfoList(message.userId)
  );
  const shopMemberName = messageSender[0].shopMemberName;
  const textMessageTemplate = CHAT_SOCKET.getTextMessageTemplate(
    message.id === socketID
  );
  const profileImagePath = Common.getProfileImgUrl(message.profileImagePath);
  const html = CHAT_SOCKET.renderTextMessage(
    textMessageTemplate,
    messageTextWithSID,
    shopMemberName,
    profileImagePath,
    message.userId,
    message.createdAt
  );
  $("#messages").prepend(html);
};

CHAT_SOCKET.renderTextMessage = function (
  template,
  text,
  from,
  profileImagePath,
  userID,
  createdAt
) {
  let messageTime = CHAT_UTIL.formatDate(createdAt);
  let dataInsertedTemplate = Mustache.render(template, {
    text: text,
    from: from,
    messageId: 0,
    profileImage: profileImagePath,
    shopMemberId: userID,
    createdAtDay: messageTime.createdAtDay,
    createdAtTime: messageTime.createdAtTime,
    isToday: true,
  });

  // イメージの場合、img tagを追加する
  if (text.includes("attachedImages") || text.includes("attachedVideos")) {
    return CHAT_UTIL.htmlDecode(dataInsertedTemplate);
  } else {
    return dataInsertedTemplate;
  }
};

CHAT_SOCKET.getUserInfoList = function (userID) {
  return JSON.parse(NativeBridgeDataSource.getUserInfoList(userID));
};

CHAT_SOCKET.cleanUpCollaborationMessage = function () {
  $(".collabo_area.start").each(function (index, collaborationMessage) {
    $(collaborationMessage).removeClass("start");
    $(collaborationMessage).addClass("end");
    $(collaborationMessage).addClass("disable");
    $(collaborationMessage)
      .find(".collaboation_join_button")
      .attr("disabled", "disabled");
    $(collaborationMessage)
      .find(".collaboration_join_message")
      .text(getLocalizedString("flex-directionmessage_ended"));
  });
};

CHAT_SOCKET.insertSID = function (text) {
  let replacePath = text;
  replacePath = replacePath.replaceAll(
    "?fileName=",
    "?sid=" + currentUserInfo.sid + "&fileName="
  );
  return replacePath;
};

CHAT_SOCKET.getTextMessageTemplate = function (isSenderMySelf) {
  return getTemplate(
    isSenderMySelf
      ? TemplateURL.MY_MESSAGE // ユーザーが送信したメッセージの場合、自分のメッセージ様式を適用して表示する
      : TemplateURL.USER_MESSAGE
  );
};