<template>
  <component
    :is="rootComponent"
    ref="root"
    v-bind="{ ...$props, ...$attrs }">
    <div class="bubble image-bubble" ref="imageRef">
      <ImageWithProgress v-if="attachment"
        :aspect-ratio="16 / 9"
        ref="image"
        :src="attachment.src ? attachment.src : attachment.thumbnail"
        :cover="cover"
        :contain="contain"
        :loadingProgress="attachment.thumbnailProgress"
      />
    </div>
    <v-dialog v-model="dialog" :width="smAndUp ? '940px' : '90%'">
      <ImageWithProgress :src="attachment?.src ? attachment.src : attachment?.thumbnail" :loadingProgress="attachment?.srcProgress" />
    </v-dialog>
  </component>
</template>

<script setup lang="ts">
import { computed, inject, onMounted, ref, useTemplateRef, watch } from "vue";
import MessageIncoming from "./MessageIncoming.vue";
import MessageOutgoing from "./MessageOutgoing.vue";
import ImageWithProgress from "../../ImageWithProgress.vue";
import { useLazyLoad } from "./useLazyLoad";
import { useI18n } from "vue-i18n";
import { MessageEmits, MessageProps, useMessage } from "./useMessage";
import { EventAttachment } from "../../../models/eventAttachment";
import { useDisplay } from "vuetify";
import utils from "@/plugins/utils";
import Hammer from "hammerjs";

const { t } = useI18n()
const $matrix: any = inject('globalMatrix');

type RootType = InstanceType<typeof MessageOutgoing | typeof MessageIncoming>
const rootRef = useTemplateRef<RootType>("root");
const imageRef = useTemplateRef("imageRef");

const emits = defineEmits<MessageEmits>();  
const props = defineProps<MessageProps>();

const cover = ref(true);
const contain = ref(false);
const dialog = ref(false);

const { smAndUp } = useDisplay();

const {
  isVisible
} = useLazyLoad({ root: rootRef });

const {
  event,
  isIncoming,
  attachment,
} = useMessage($matrix, t, props, emits, undefined);

const rootComponent = computed(() => {
 return isIncoming.value ? MessageIncoming : MessageOutgoing;
})

watch([isVisible, attachment], ([_v, _a]: [_v: boolean, _a: EventAttachment | undefined]) => {
  if (_v && _a) {
    _a.loadThumbnail();
  }
});

onMounted(() => {
    const info = event.value?.getContent().info;
    // JPEGs use cover, PNG and GIF ect contain. This is because PNG and GIF are expected to
    // be stickers and small emoji type things.
    if (info && info.mimetype && info.mimetype.startsWith("image/jp")) {
      cover.value = true;
      contain.value = false;
    } else {
      cover.value = false;
      contain.value = true;
    }
    if (imageRef.value) {
      const hammerInstance = utils.singleOrDoubleTabRecognizer(imageRef.value);
      hammerInstance.on("singletap doubletap", (ev: Hammer.HammerInput) => {
        if (ev.type === "singletap") {
          attachment.value?.loadSrc();
          dialog.value = true;
        }
      });
    }
});

</script>

<style lang="scss">
@use "@/assets/css/chat.scss" as *;
</style>