<template>
  <div class="content__attachments" :id='"content__attachments-" + parent.id'>
    <div class="border-0 border-b border-dashed border-sn-light-grey my-6"></div>
    <div class="content__attachments-actions">
      <div class="title">
        {{ i18n.t('protocols.steps.files', {count: attachments.length}) }}
      </div>
      <div class="flex items-center gap-2" v-if="parent.attributes.attachments_manageble && attachmentsReady">
        <MenuDropdown
          :listItems="this.viewModeMenu"
          :btnText="i18n.t('attachments.preview_menu')"
          :position="'right'"
          :caret="true"
          @attachment:viewMode = "changeAttachmentsViewMode"
        ></MenuDropdown>
        <MenuDropdown
          :listItems="this.sortMenu"
          :btnIcon="'sn-icon sn-icon-sort-down'"
          :btnClasses="'btn btn-light icon-btn'"
          :position="'right'"
          @attachment:order = "changeAttachmentsOrder"
        ></MenuDropdown>
      </div>
    </div>
    <div class="attachments" :data-parent-id="parent.id">
      <component
        v-for="(attachment, index) in attachmentsOrdered"
        :key="attachment.id"
        :is="attachment_view_mode(attachmentsOrdered[index])"
        :attachment="attachment"
        :parentId="parseInt(parent.id)"
        @attachment:viewMode="updateAttachmentViewMode"
        @attachment:delete="deleteAttachment(attachment.id)"
        @attachment:moved="attachmentMoved"
      />
    </div>
  </div>
</template>
<script>
  import AttachmentMovedMixin from './attachments/mixins/attachment_moved.js'
  import listAttachment from './attachments/list.vue'
  import inlineAttachment from './attachments/inline.vue'
  import thumbnailAttachment from './attachments/thumbnail.vue'
  import uploadingAttachment from './attachments/uploading.vue'
  import emptyAttachment from './attachments/empty.vue'
  import MenuDropdown from '../menu_dropdown.vue'

  import WopiFileModal from './attachments/mixins/wopi_file_modal.js'

  export default {
    name: 'Attachments',
    props: {
      attachments: {
        type: Array,
        required: true
      },
      parent: {
        type: Object,
        required: true
      },
      attachmentsReady: {
        type: Boolean,
        required: true
      }
    },
    data() {
      return {
        viewModeOptions: ['inline', 'thumbnail', 'list'],
        orderOptions: ['new', 'old', 'atoz', 'ztoa']
      }
    },
    mixins: [WopiFileModal, AttachmentMovedMixin],
    components: {
      thumbnailAttachment,
      inlineAttachment,
      listAttachment,
      uploadingAttachment,
      emptyAttachment,
      MenuDropdown
    },
    watch: {
      attachmentsReady() {
        if (this.attachmentsReady) {
          this.$nextTick(() => {
            this.initMarvinJS();
          })
        }
      }
    },
    computed: {
      attachmentsOrdered() {
        return this.attachments.sort((a, b) => {
          if (a.attributes.asset_order == b.attributes.asset_order) {
            switch(this.parent.attributes.assets_order) {
              case 'new':
                return b.attributes.updated_at - a.attributes.updated_at;
              case 'old':
                return a.attributes.updated_at - b.attributes.updated_at;
              case 'atoz':
                return a.attributes.file_name.toLowerCase() > b.attributes.file_name.toLowerCase() ? 1 : -1;
              case 'ztoa':
                return b.attributes.file_name.toLowerCase() > a.attributes.file_name.toLowerCase() ? 1 : -1;
            }
          }

          return a.attributes.asset_order > b.attributes.asset_order ? 1 : -1;
        })
      },
      viewModeMenu() {
        let menu = [];
        this.viewModeOptions.forEach((viewMode) => {
          menu.push({
            text: this.i18n.t(`attachments.view_mode.${viewMode}_html`),
            emit: 'attachment:viewMode',
            params: viewMode
          })
        })
        return menu;
      },
      sortMenu() {
        let menu = [];
        this.orderOptions.forEach((orderOption, i) => {
          menu.push({
            text: this.i18n.t(`general.sort_new.${orderOption}`),
            emit: 'attachment:order',
            params: orderOption,
            dividerBefore: i === 2
          })
        })
        return menu;
      }
    },
    mounted() {
      this.initMarvinJS();
      $(this.$refs.actionsDropdownButton).on('shown.bs.dropdown hidden.bs.dropdown', this.handleDropdownPosition);
    },
    methods: {
      changeAttachmentsOrder(order) {
        this.$emit('attachments:order', order)
      },
      changeAttachmentsViewMode(viewMode) {
        this.$emit('attachments:viewMode', viewMode)
      },
      updateAttachmentViewMode(id, viewMode) {
        this.$emit('attachment:viewMode', id, viewMode)
      },
      attachment_view_mode(attachment) {
        if (attachment.attributes.uploading) {
          return 'uploadingAttachment'
        } else if (!attachment.attributes.attached) {
          return 'emptyAttachment'
        }
        return `${attachment.attributes.view_mode}Attachment`
      },
      deleteAttachment(id) {
        this.$emit('attachment:deleted', id)
      },

      initMarvinJS() {
        // legacy logic from app/assets/javascripts/sitewide/marvinjs_editor.js
        MarvinJsEditor.initNewButton(
          `#content__attachments-${this.parent.id} .new-marvinjs-upload-button`,
          () => this.$emit('attachment:uploaded')
        );
      },
      openWopiFileModal() {
        this.initWopiFileModal(this.parent, (_e, data, status) => {
          if (status === 'success') {
            this.$emit('attachment:uploaded', data);
          } else {
            HelperModule.flashAlertMsg(this.i18n.t('errors.general'), 'danger');
          }
        });
      },

      handleDropdownPosition() {
        this.$refs.actionsDropdownButton.classList.toggle("dropup", !this.isInViewport(this.$refs.actionsDropdown));
      },
      isInViewport(el) {
          let rect = el.getBoundingClientRect();

          return (
              rect.top >= 0 &&
              rect.left >= 0 &&
              rect.bottom <= (window.innerHeight || $(window).height()) &&
              rect.right <= (window.innerWidth || $(window).width())
          );
      },
    }
  }
</script>