<template>
  <message-incoming v-bind="{ ...$props, ...$attrs }" v-if="items.length > 1 || event.isRedacted() || forceMultiview">
    <div class="bubble">
      <div class="original-message" v-if="inReplyToText">
        <div class="original-message-sender">{{ inReplyToSender }}</div>
        <div
          class="original-message-text"
          v-html="linkify($sanitize(inReplyToText))"
        />
      </div>

      <div class="message">
        <SwipeableThumbnailsView :items="items" v-if="!event.isRedacted() && room.displayType == ROOM_TYPE_CHANNEL" v-bind="$attrs" />
        <v-container v-else-if="!event.isRedacted()" fluid class="imageCollection">
          <v-row wrap>
            <v-col v-for="({ size, item }) in layoutedItems()" :key="item.event.getId()" :cols="size">
              <ThumbnailView :item="item" :previewOnly="true" v-on:itemclick="onItemClick($event)" /> 
            </v-col>
          </v-row>
        </v-container>
        <i v-if="event.isRedacted()" class="deleted-text">
          <v-icon :color="this.senderIsAdminOrModerator(this.event) ? 'white' : ''" size="small">block</v-icon>
          {{ redactedBySomeoneElse(event) ? $t('message.incoming_message_deleted_text') : $t('message.outgoing_message_deleted_text')}}
        </i>
        <span v-html="linkify($sanitize(messageText))" v-else-if="messageText" />
        <span class="edit-marker" v-if="event.replacingEventId() && !event.isRedacted()">
          {{ $t('message.edited') }}
        </span>
      </div>
    </div>
    <GalleryItemsView :originalEvent="originalEvent" :items="items" :initialItem="showItem" v-if="!!showItem" v-on:close="showItem = null" />
  </message-incoming>
  <component v-else-if="items.length == 1" :is="componentFn(items[0].event)" 
    v-bind="{...$props, ...$attrs}"
    :originalEvent="items[0].event"
  />
</template>

<script>
import MessageIncoming from "./MessageIncoming.vue";
import messageMixin from "./messageMixin";
import util, { ROOM_TYPE_CHANNEL, ROOM_TYPE_FILE_MODE } from "../../plugins/utils";
import GalleryItemsView from '../file_mode/GalleryItemsView.vue';
import ThumbnailView from '../file_mode/ThumbnailView.vue';
import SwipeableThumbnailsView from "./channel/SwipeableThumbnailsView.vue";
import { reactive } from "vue";

export default {
  extends: MessageIncoming,
  components: { MessageIncoming, GalleryItemsView, ThumbnailView, SwipeableThumbnailsView },
  mixins: [messageMixin],
  data() {
    return {
      ROOM_TYPE_CHANNEL: ROOM_TYPE_CHANNEL,
      items: [],
      showItem: null,
    }
  },
  mounted() {
    this.thread = this.timelineSet.relations.getChildEventsForEvent(this.event.getId(), util.threadMessageType(), "m.room.message");
    if (!this.thread) {
      this.event.on("Event.relationsCreated", this.onRelationsCreated);
    }
  },
  beforeUnmount() {
    this.event.off("Event.relationsCreated", this.onRelationsCreated);
  },
  computed: {
    forceMultiview() {
      return this.room.displayType == ROOM_TYPE_FILE_MODE || (this.room.displayType == ROOM_TYPE_CHANNEL && this.items.length == 1 && util.isFileTypePDF(this.items[0].event));
    }
  },
  methods: {
    onRelationsCreated() {
      this.thread = this.timelineSet.relations.getChildEventsForEvent(this.event.getId(), util.threadMessageType(), "m.room.message");
      this.event.off("Event.relationsCreated", this.onRelationsCreated);
    },
    onItemClick(event) {
      this.showItem = event.item;
    },
    processThread() {
      this.$emit('layout-change', () => {
        this.items = this.timelineSet.relations.getAllChildEventsForEvent(this.event.getId())
          .filter(e => !e.isRedacted() && util.downloadableTypes().includes(e.getContent().msgtype))
          .map(e => {
            let ret = reactive({
              event: e,
              src: null,
            });
            ret.promise = this.$matrix.matrixClient.decryptEventIfNeeded(e)
              .then(() => util.getThumbnail(this.$matrix.matrixClient, this.$matrix.useAuthedMedia, e, this.$config, 100, 100))
              .then((url) => {
                ret.src = url;
              })
              .catch((err) => {
                console.log("Failed to fetch thumbnail: ", err);
              });
            return ret;
          });
      }, this.$el);
    },
    layoutedItems() {
      if (!this.items || this.items.length == 0) { return [] }
      let array = this.items.slice(0);
      let rows = []
      while (array.length > 0) {
        if (array.length >= 7) {
          rows.push({ size: 6, item: array[0] });
          rows.push({ size: 6, item: array[1] });
          rows.push({ size: 12, item: array[2] });
          rows.push({ size: 3, item: array[3] });
          rows.push({ size: 3, item: array[4] });
          rows.push({ size: 3, item: array[5] });
          rows.push({ size: 3, item: array[6] });
          array = array.slice(7);
        } else if (array.length >= 3) {
          rows.push({ size: 6, item: array[0] });
          rows.push({ size: 6, item: array[1] });
          rows.push({ size: 12, item: array[2] });
          array = array.slice(3);
        } else if (array.length >= 2) {
          rows.push({ size: 6, item: array[0] });
          rows.push({ size: 6, item: array[1] });
          array = array.slice(2);
        } else {
          rows.push({ size: 12, item: array[0] });
          array = array.slice(1);
        }
      }
      return rows
    },
    downloadAll() {
      this.items.forEach(item => util.download(this.$matrix.matrixClient, this.$matrix.useAuthedMedia, item.event));
    }
  }
};
</script>

<style lang="scss">
@import "@/assets/css/chat.scss";
</style>

<style lang="scss" scoped>
.bubble {
  width: 100%;
}

.imageCollection {
  border-radius: 15px;
  padding: 0;
  overflow: hidden;

  .row {
    margin: -4px; // Compensate for column padding, so the border-radius above looks round!
    padding: 0;
  }

  .col {
    padding: 2px;
  }
}
</style>