<template>
  <div v-bind="{ ...$attrs }" class="send-attachments">
    <div class="send-attachments__title">{{ $t("message.send_attachements_dialog_title") }}</div>

    <!-- ATTACHMENT SELECTION MODE -->
    <template v-if="attachments && attachments.length > 0 && status == mainStatuses.SELECTING">
      <div class="attachment-wrapper" ref="attachmentWrapper" v-if="currentAttachment">
        <div
          :class="{ 'file-drop-current-item': true, 'drop-target': dropTarget }"
          @drop.prevent="filesDropped"
          @dragover.prevent="dropTarget = true"
          @dragleave.prevent="dropTarget = false"
          @dragenter.prevent="dropTarget = true"
        >
          <v-img v-if="currentAttachment.src && currentAttachment.status === 'loaded'" :src="currentAttachment.src" />
          <div v-else class="filename">
            <div>{{ currentAttachment.file.name }}</div>
            <div v-if="currentAttachment.status === 'loading'" style="font-size: 0.7em; opacity: 0.7">
              {{ $t("message.preparing_to_upload") }}
              <v-progress-linear indeterminate class="mb-0"></v-progress-linear>
            </div>
          </div>
        </div>

        <div class="send-attachments__current-item__info">
          <div class="send-attachments__current-item__info__size">
            <span
              v-if="currentAttachment.scaledFile && currentAttachment.useScaled && currentAttachment.scaledDimensions"
            >
              {{ currentAttachment.scaledDimensions.width }} x {{ currentAttachment.scaledDimensions.height }}</span
            >
            <span v-else-if="currentAttachment.dimensions">
              {{ currentAttachment.dimensions.width }} x {{ currentAttachment.dimensions.height }}
            </span>

            <span v-if="currentAttachment.scaledFile && currentAttachment.useScaled">
              ({{ formatBytes(currentAttachment.scaledFile.size) }})
            </span>
            <span v-else> ({{ formatBytes(currentAttachment.file.size) }}) </span>

            <span class="send-attachments__current-item__info__size__filename" v-if="currentAttachment.src && currentAttachment.file.name">
              - {{ currentAttachment.file.name }}
            </span>
          </div>

          <v-switch
            v-if="currentAttachment.scaledFile"
            :label="$t('message.scale_image')"
            v-model="currentAttachment.useScaled"
            :disabled="currentAttachment.sendInfo !== undefined"
          />

          <C2PABadge :proof="currentAttachment.proof" />
        </div>

        <div class="file-drop-thumbnail-container">
          <div
            :class="{ 'file-drop-thumbnail': true, clickable: true, current: id == currentItemIndex }"
            @click="currentItemIndex = id"
            v-for="(currentImageInput, id) in attachments"
            :key="id"
          >
            <v-img v-if="currentImageInput && currentImageInput.src" :src="currentImageInput.src" />
            <div v-if="currentItemIndex == id" class="remove clickable" @click.stop="$emit('remove-file', id)">
              <v-icon>$vuetify.icons.ic_trash</v-icon>
            </div>
          </div>
          <div class="file-drop-thumbnail noborder">
            <div class="add clickable" @click.stop="$emit('pick-file')">+</div>
          </div>
        </div>
        <div class="file-drop-input-container">
          <v-textarea
            ref="input"
            full-width
            variant="solo"
            flat
            auto-grow
            v-model="messageInput"
            no-resize
            class="input-area-text"
            rows="1"
            :placeholder="$t('file_mode.add_a_message')"
            hide-details
            background-color="transparent"
            v-on:keydown.enter.prevent="
              () => {
                sendAll();
              }
            "
          />
          <div class="input-container__buttons">
            <v-btn @click="close">{{ $t("menu.cancel") }}</v-btn>
            <v-btn @click="sendAll" :disabled="!attachments || attachments.length == 0">{{ $t("menu.send") }}</v-btn>
          </div>
        </div>
      </div>
    </template>

    <!-- ATTACHMENT SENDING/SENT MODE -->
    <template
      v-if="attachments && attachments.length > 0 && (status == mainStatuses.SENDING || status == mainStatuses.SENT)"
    >
      <div class="attachment-wrapper">
        <div class="file-drop-sent-stack" ref="stackContainer">
          <div v-if="status == mainStatuses.SENDING && attachmentsSentCount == 0" class="no-items">
            <div class="file-drop-stack-item direct" :style="stackItemTransform(null, -1)"></div>
            <div>{{ $t("file_mode.sending_progress") }}</div>
          </div>
          <div
            v-else
            v-for="(info, index) in attachmentsSent"
            :key="info.file.name"
            class="file-drop-stack-item animated"
            :style="stackItemTransform(info, index)"
          >
            <v-img v-if="info.src" :src="info.src" />
          </div>
          <div v-if="status == mainStatuses.SENT" class="items-sent" :style="stackItemTransform(null, -1)">
            <v-icon>$vuetify.icons.ic_check_circle</v-icon>
          </div>
        </div>

        <!-- Middle section -->
        <div v-if="status == mainStatuses.SENDING" class="file-drop-sending-container">
          <div class="file-drop-sending-item" v-for="(attachment) in attachmentsSending" :key="attachment.file.name">
            <v-img v-if="attachment.src" :src="attachment.src" />
            <div v-else class="filename">{{ attachment.file.name }}</div>
            <v-progress-linear :model-value="attachment.sendInfo?.progress ?? 0"></v-progress-linear>
            <div class="file-drop-cancel clickable" @click.stop="cancelSendAttachmentItem(attachment)">
              <v-icon size="14" color="white">close</v-icon>
            </div>
          </div>
        </div>
        <div v-else-if="status == mainStatuses.SENT" class="file-drop-sending-container">
          <div class="file-drop-files-sent">
            {{
              $t(
                messageInput && messageInput.length > 0
                  ? "file_mode.files_sent_with_note"
                  : "file_mode.files_sent",
                attachmentsSent.length
              )
            }}
          </div>
          <div class="file-drop-section">
            <v-textarea
              disabled
              full-width
              variant="solo"
              flat
              auto-grow
              v-model="messageInput"
              no-resize
              class="input-area-text"
              rows="1"
              hide-details
              background-color="transparent"
            />
          </div>
        </div>

        <!-- Bottom section -->
        <div v-if="status == mainStatuses.SENDING" class="file-drop-sending-input-container">
          <v-textarea
            disabled
            full-width
            variant="solo"
            flat
            auto-grow
            v-model="messageInput"
            no-resize
            class="input-area-text"
            rows="1"
            :placeholder="$t('file_mode.add_a_message')"
            hide-details
            background-color="transparent"
          />
          <v-btn
            >{{ $t("file_mode.sending")
            }}<v-progress-circular indeterminate size="18" width="2" color="#4642F1"></v-progress-circular
          ></v-btn>
        </div>
        <div v-else-if="status == mainStatuses.SENT" class="file-drop-sent-input-container">
          <v-btn class="close" @click.stop="close">{{ $t("file_mode.close") }}</v-btn>
        </div>
      </div>
    </template>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import messageMixin from "../messages/messageMixin";
import sendAttachmentsMixin from "../sendAttachmentsMixin";
import prettyBytes from "pretty-bytes";
import type { PropType } from "vue";
import { Attachment } from "../../models/attachment";
import C2PABadge from "../c2pa/C2PABadge.vue";

export default defineComponent({
  mixins: [messageMixin, sendAttachmentsMixin],
  components: { C2PABadge },
  emits: ["add-files", "remove-file", "pick-file", "close"],
  props: {
    attachments: {
      type: Array as PropType<Attachment[]>,
      default: function () {
        return [] as Attachment[];
      },
    },
  },
  data() {
    return {
      currentItemIndex: 0,
      messageInput: "",
      mainStatuses: Object.freeze({
        SELECTING: 0,
        SENDING: 1,
        SENT: 2,
      }),
      status: 0,
      dropTarget: false,
    };
  },
  mounted() {
    this.$audioPlayer.setAutoplay(false);
  },
  computed: {
    currentAttachment(): Attachment {
      return this.attachments[this.currentItemIndex];
    },
    currentItemHasImagePreview() {
      return (
        this.currentItemIndex >= 0 &&
        this.currentItemIndex < this.attachments.length &&
        this.attachments[this.currentItemIndex].src
      );
    },
  },
  watch: {
    attachments(newValue, oldValue) {
      // Added or removed?
      if (newValue && oldValue && newValue.length > oldValue.length) {
        this.currentItemIndex = oldValue.length;
      } else if (newValue) {
        this.currentItemIndex = newValue.length - 1;
      }
    },
    messageInput() {
      this.scrollToBottom();
    },
  },
  methods: {
    filesDropped(e: DragEvent) {
      this.dropTarget = false;
      let droppedFiles: FileList | undefined = e.dataTransfer?.files;
      if (!droppedFiles) return;
      this.$emit("add-files", [... droppedFiles]);
    },
    scrollToBottom() {
      const el = this.$refs.attachmentWrapper;
      if (el) {
        // Ugly - need to wait until input is auto-sized, THEN scroll to bottom.
        //
        this.$nextTick(() => {
          this.$nextTick(() => {
            this.$nextTick(() => {
              el.scrollTop = el.scrollHeight;
            });
          });
        });
      }
    },
    formatBytes(bytes: number) {
      return prettyBytes(bytes);
    },
    close() {
      this.sendingAttachments = [];
      this.status = this.mainStatuses.SELECTING;
      this.messageInput = "";
      this.currentItemIndex = 0;
      this.$emit("close");
    },
    sendAll() {
      this.status = this.mainStatuses.SENDING;
      this.sendAttachments(
        this.messageInput && this.messageInput.length > 0 ? this.messageInput : this.$t("file_mode.files"),
        this.attachments
      ).then(() => {
        this.status = this.mainStatuses.SENT;
      });
    },
    stackItemTransform(item, index) {
      const size =
        0.6 *
        (this.$refs.stackContainer
          ? Math.min(this.$refs.stackContainer.clientWidth, this.$refs.stackContainer.clientHeight)
          : 176);
      let transform = "";
      if (item != null && index != -1) {
        transform =
          "transform: rotate(" +
          item.randomRotation +
          "deg) translate(" +
          item.randomTranslationX +
          "px," +
          item.randomTranslationY +
          "px); z-index:" +
          (index + 2) +
          ";";
      }
      return transform + "width:" + size + "px;height:" + size + "px;border-radius:" + size / 8 + "px";
    },
  },
});
</script>

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