import util, { ROOM_TYPE_CHANNEL, STATE_EVENT_ROOM_DELETION_NOTICE } from "../plugins/utils";
import MessageIncomingText from "./messages/MessageIncomingText";
import MessageIncomingFile from "./messages/MessageIncomingFile";
import MessageIncomingImage from "./messages/MessageIncomingImage.vue";
import MessageIncomingAudio from "./messages/MessageIncomingAudio.vue";
import MessageIncomingVideo from "./messages/MessageIncomingVideo.vue";
import MessageIncomingSticker from "./messages/MessageIncomingSticker.vue";
import MessageIncomingPoll from "./messages/MessageIncomingPoll.vue";
import MessageIncomingThread from "./messages/MessageIncomingThread.vue";
import MessageOutgoingText from "./messages/MessageOutgoingText";
import MessageOutgoingFile from "./messages/MessageOutgoingFile";
import MessageOutgoingImage from "./messages/MessageOutgoingImage.vue";
import MessageOutgoingAudio from "./messages/MessageOutgoingAudio.vue";
import MessageOutgoingVideo from "./messages/MessageOutgoingVideo.vue";
import MessageOutgoingSticker from "./messages/MessageOutgoingSticker.vue";
import MessageOutgoingPoll from "./messages/MessageOutgoingPoll.vue";
import MessageOutgoingThread from "./messages/MessageOutgoingThread.vue";
import MessageIncomingImageExport from "./messages/export/MessageIncomingImageExport";
import MessageIncomingAudioExport from "./messages/export/MessageIncomingAudioExport";
import MessageIncomingVideoExport from "./messages/export/MessageIncomingVideoExport";
import MessageIncomingThreadExport from "./messages/export/MessageIncomingThreadExport";
import MessageIncomingFileExport from "./messages/export/MessageIncomingFileExport";
import MessageOutgoingImageExport from "./messages/export/MessageOutgoingImageExport";
import MessageOutgoingAudioExport from "./messages/export/MessageOutgoingAudioExport";
import MessageOutgoingVideoExport from "./messages/export/MessageOutgoingVideoExport";
import MessageOutgoingThreadExport from "./messages/export/MessageOutgoingThreadExport";
import MessageOutgoingFileExport from "./messages/export/MessageOutgoingFileExport";
import ContactJoin from "./messages/ContactJoin.vue";
import ContactLeave from "./messages/ContactLeave.vue";
import ContactInvited from "./messages/ContactInvited.vue";
import ContactKicked from "./messages/ContactKicked.vue";
import ContactBanned from "./messages/ContactBanned.vue";
import ContactChanged from "./messages/ContactChanged.vue";
import RoomCreated from "./messages/RoomCreated.vue";
import RoomAliased from "./messages/RoomAliased.vue";
import RoomNameChanged from "./messages/RoomNameChanged.vue";
import RoomTopicChanged from "./messages/RoomTopicChanged.vue";
import RoomAvatarChanged from "./messages/RoomAvatarChanged.vue";
import RoomHistoryVisibility from "./messages/RoomHistoryVisibility.vue";
import MessageOperations from "./messages/MessageOperations.vue";
import ChatHeader from "./ChatHeader";
import VoiceRecorder from "./VoiceRecorder";
import RoomInfoBottomSheet from "./RoomInfoBottomSheet";
import WelcomeHeaderRoom from "./welcome_headers/WelcomeHeaderRoom.vue";
import MessageOperationsBottomSheet from "./MessageOperationsBottomSheet";
import stickers from "../plugins/stickers";
import StickerPickerBottomSheet from "./StickerPickerBottomSheet";
import BottomSheet from "./BottomSheet.vue";
import CreatePollDialog from "./CreatePollDialog.vue";
import RoomJoinRules from "./messages/RoomJoinRules.vue";
import RoomPowerLevelsChanged from "./messages/RoomPowerLevelsChanged.vue";
import RoomGuestAccessChanged from "./messages/RoomGuestAccessChanged.vue";
import RoomEncrypted from "./messages/RoomEncrypted.vue";
import RoomDeletionNotice from "./messages/RoomDeletionNotice.vue";
import DebugEvent from "./messages/DebugEvent.vue";
import ReadMarker from "./messages/ReadMarker.vue";
import roomDisplayOptionsMixin from "./roomDisplayOptionsMixin";
import roomTypeMixin from "./roomTypeMixin";

export const ROOM_READ_MARKER_EVENT_PLACEHOLDER = { getId: () => "ROOM_READ_MARKER" };

export default {
  mixins: [ roomDisplayOptionsMixin, roomTypeMixin ],
  components: {
    ChatHeader,
    MessageIncomingText,
    MessageIncomingFile,
    MessageIncomingImage,
    MessageIncomingAudio,
    MessageIncomingVideo,
    MessageIncomingSticker,
    MessageIncomingThread,
    MessageOutgoingText,
    MessageOutgoingFile,
    MessageOutgoingImage,
    MessageOutgoingAudio,
    MessageOutgoingVideo,
    MessageOutgoingSticker,
    MessageOutgoingThread,
    MessageOutgoingPoll,
    ContactJoin,
    ContactLeave,
    ContactInvited,
    ContactKicked,
    ContactBanned,
    ContactChanged,
    RoomCreated,
    RoomAliased,
    RoomNameChanged,
    RoomTopicChanged,
    RoomAvatarChanged,
    RoomHistoryVisibility,
    RoomJoinRules,
    RoomPowerLevelsChanged,
    RoomGuestAccessChanged,
    RoomEncrypted,
    RoomDeletionNotice,
    DebugEvent,
    MessageOperations,
    VoiceRecorder,
    RoomInfoBottomSheet,
    WelcomeHeaderRoom,
    MessageOperationsBottomSheet,
    StickerPickerBottomSheet,
    BottomSheet,
    CreatePollDialog,
    ReadMarker
  },
  methods: {
    showDayMarkerBeforeEvent(event) {
      const idx = this.events.indexOf(event);
      if (idx <= 0) {
        return true;
      }
      const previousEvent = this.events[idx - 1];
      return util.dayDiff(previousEvent.getTs(), event.getTs()) > 0;
    },

    dayForEvent(event) {
      let dayDiff = util.dayDiffToday(event.getTs());
      if (dayDiff < 7) {
        return this.$tc("message.time_ago", dayDiff);
      } else {
        return util.formatDay(event.getTs());
      }
    },

    dateForEvent(event) {
        return util.formatDay(event.getTs());
    },

    componentForEvent(event, isForExport = false) {
      const isChannel = this.roomDisplayType === ROOM_TYPE_CHANNEL;
      if (event === ROOM_READ_MARKER_EVENT_PLACEHOLDER) {
        return ReadMarker;
      }
      switch (event.getType()) {
        case "m.room.member":
          if (isChannel) break;
          if (event.getContent().membership == "join") {
            if (event.getPrevContent() && event.getPrevContent().membership == "join") {
              // We we already joined, so this must be a display name and/or avatar update!
              return ContactChanged;
            } else {
              if (event.getSender() == this.$matrix.currentUserId && !this.showOwnJoins) {
                return null;
              }
              return ContactJoin;
            }
          } else if (event.getContent().membership == "leave") {
            if ((event.getPrevContent() || {}).membership == "join" &&
              event.getStateKey() != event.getSender()) {
                return ContactKicked;
              }
            return ContactLeave;
          } else if (this.showAllStatusMessages) {
            if (event.getContent().membership == "invite") {
              return ContactInvited;
            } else if (event.getContent().membership == "ban") {
              return ContactBanned;
            }
          }
          break;

        case "m.room.message":
          if (event.getSender() != this.$matrix.currentUserId) {
              if (event.isRedacted()) {
                // Redacted thread, show as text (and hide all media)!
                if (event.getUnsigned().redacted_because.content.reason == "redactedThread") {
                  return MessageIncomingText;
                }
                return null;
              }
              if (event.isMxThread) {
                // Incoming thread, e.g. a file drop!
                return isForExport ? MessageIncomingThreadExport : MessageIncomingThread;
              }
              if (event.getContent().msgtype == "m.image") {
              // For SVG, make downloadable
              if (
                event.getContent().info &&
                event.getContent().info.mimetype &&
                event.getContent().info.mimetype.startsWith("image/svg")
              ) {
                if (isForExport) {
                  return MessageIncomingFileExport;
                }
                return MessageIncomingFile;
              }
              if (isForExport) {
                return MessageIncomingImageExport;
              }
              return MessageIncomingImage;
            } else if (event.getContent().msgtype == "m.audio") {
              if (isForExport) {
                return MessageIncomingAudioExport;
              }
              return MessageIncomingAudio;
            } else if (event.getContent().msgtype == "m.video") {
              if (isForExport) {
                return MessageIncomingVideoExport;
              }
              return MessageIncomingVideo;
            } else if (event.getContent().msgtype == "m.file") {
              if (isForExport) {
                return MessageIncomingFileExport;
              }
              return MessageIncomingFile;
            } else if (stickers.isStickerShortcode(event.getContent().body)) {
              return MessageIncomingSticker;
            }
            return MessageIncomingText;
          } else {
            if (event.isRedacted()) {
              // Redacted thread, show as text (and hide all media)!
              if (event.getUnsigned().redacted_because.content.reason == "redactedThread") {
                return MessageOutgoingText;
              }
              return null;
            }
            if (event.isMxThread) {
              // Outgoing thread
              return isForExport ? MessageOutgoingThreadExport : MessageOutgoingThread;
            }
            if (event.getContent().msgtype == "m.image") {
              // For SVG, make downloadable
              if (
                event.getContent().info &&
                event.getContent().info.mimetype &&
                event.getContent().info.mimetype.startsWith("image/svg")
              ) {
                return MessageOutgoingImage;
              }
              if (isForExport) {
                return MessageOutgoingImageExport;
              }
              return MessageOutgoingImage;
            } else if (event.getContent().msgtype == "m.audio") {
              if (isForExport) {
                return MessageOutgoingAudioExport;
              }
              return MessageOutgoingAudio;
            } else if (event.getContent().msgtype == "m.video") {
              if (isForExport) {
                return MessageOutgoingVideoExport;
              }
              return MessageOutgoingVideo;
            } else if (event.getContent().msgtype == "m.file") {
              if (isForExport) {
                return MessageOutgoingFileExport;
              }
              return MessageOutgoingFile;
            } else if (stickers.isStickerShortcode(event.getContent().body)) {
              return MessageOutgoingSticker;
            }
            return MessageOutgoingText;
          }

        case "m.room.create":
          if (this.showAllStatusMessages) {
            return RoomCreated;
          }
          break;

        case "m.room.canonical_alias":
          if (this.showAllStatusMessages) {
            return RoomAliased;
          }
          break;

        case "m.room.name":
          if (this.showAllStatusMessages) {
            return RoomNameChanged;
          }
          break;

        case "m.room.topic":
          if (this.showAllStatusMessages) {
            return RoomTopicChanged;
          }
          break;

        case "m.room.avatar":
          if (this.showAllStatusMessages) {
            return RoomAvatarChanged;
          }
          break;

        case "m.room.history_visibility":
          if (this.showAllStatusMessages) {
            return RoomHistoryVisibility;
          }
          break;

        case "m.room.join_rules":
          if (this.showAllStatusMessages) {
            return RoomJoinRules;
          }
          break;

        case "m.room.power_levels":
          if (this.showAllStatusMessages) {
            return RoomPowerLevelsChanged;
          }
          break;

        case "m.room.guest_access":
          if (this.showAllStatusMessages) {
            return RoomGuestAccessChanged;
          }
          break;

        case "m.room.encryption":
          if (this.showAllStatusMessages) {
            return RoomEncrypted;
          }
          break;

        case "m.poll.start":
        case "org.matrix.msc3381.poll.start":
          if (event.getSender() != this.$matrix.currentUserId) {
            return MessageIncomingPoll;
          } else {
            return MessageOutgoingPoll;
          }

        case STATE_EVENT_ROOM_DELETION_NOTICE: {
          // Custom event for notice 30 seconds before a room is deleted/purged.
          const deletionNotices = this.room.currentState.getStateEvents(STATE_EVENT_ROOM_DELETION_NOTICE);
          if (deletionNotices && deletionNotices.length > 0 && deletionNotices[deletionNotices.length - 1] == event) {
            // This is the latest/last one. Look at the status flag. Show nothing if it is "cancel".
            if (event.getContent().status != "cancel") {
              return RoomDeletionNotice;
            }
          }
        }
          break;
        case "m.room.encrypted":
         return event.getSender() != this.$matrix.currentUserId ? MessageIncomingText : MessageOutgoingText
      }
      return this.debugging ? DebugEvent : null;
    },
  },
};
