<template>
  <div>
    <input class="focus-catcher" />

    <div
      class="asset-picker"
      @click="openModal"
      @dragenter="hovering = true"
      @dragleave="hovering = false"
      :class="{ hovering: hovering, readonly: readonly }"
    >
      <span class="icon-cross" v-if="!required && valueCopy && !readonly" @click.stop="deleteItem"></span>

      <div class="card" v-if="asset">
        <div class="img-wrap" :class="{ 'is-img': assetIsImage }">
          <img :src="previewUrl" v-if="previewUrl" class="card-img-top" />
        </div>
        <div class="card-footer">
          <small class="text-muted">
            <strong v-text="asset.title"></strong><br />
            <i>Type</i>: <span v-text="asset.contentType"></span>
          </small>
        </div>
      </div>

      <div v-else class="asset-picker_drag-drop">
        <span class="choose" v-html="schema.placeholder || 'Kies bestand'"></span>
        <input type="file" @change="onFileDrop" @click.prevent />
      </div>
    </div>

    <modal ref="modal">
      <header class="modal-header">
        <h3 class="modal-title">Kies bestand</h3>
        <button type="button" class="close" @click.prevent="closeModal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </header>
      <div class="modal-body" v-if="isInOverviewMode">
        <button class="btn btn-primary" @click="createAsset">Upload bestand</button>
        <p class="modal-label">of selecteer uit de lijst</p>
        <asset-overview v-model="valueCopy" :asset-type-filter-key="assetTypeFilterKey"></asset-overview>
      </div>
      <asset-detail v-else ref="asset-detail" @cancel="closeModal" v-model="valueCopy" :is-in-modal="true"></asset-detail>
    </modal>
  </div>
</template>

<style lang="scss" scoped>
.asset-picker {
  position: relative;
  width: 100%;
  height: 17vw;
  display: flex;
  cursor: pointer;

  .img-wrap {
    overflow: hidden;

    &.is-img {
      background: url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%202%202%22%3E%3Cpath%20d%3D%22M1%202V0h1v1H0v1z%22%20fill-opacity%3D%22.05%22%2F%3E%3C%2Fsvg%3E');
      background-size: 16px 16px;
    }
  }

  img {
    width: 100%;
    height: 100%;
    object-fit: contain;
  }

  .choose {
    text-align: center;
  }

  .icon-cross {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    opacity: 0;
    transition: 0.3s opacity ease;
    z-index: 1;
  }

  &:hover .icon-cross {
    opacity: 0.5;

    &:hover {
      opacity: 1;
    }
  }

  &.hovering {
    border-color: currentColor;
  }

  &.readonly {
    cursor: default;
    background-color: rgba(0, 0, 0, 0.07);
  }

  &_drag-drop {
    display: flex;
    flex-direction: column;
    justify-content: center;
    width: 100%;
    height: 100%;
    border: 2px dashed #ddd;
    border-radius: 5px;
  }

  input[type='file'] {
    position: absolute;
    cursor: pointer;
    top: 0px;
    right: 0;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
  }

  .card {
    width: 100%;
  }
}

.modal-header {
  min-width: 60vw;
}

.modal-body {
  height: 70vh;
  overflow-y: auto;

  .modal-label {
    margin: 1rem 0;
  }
}

.focus-catcher {
  position: absolute;
  visibility: hidden;
}
</style>

<script lang="ts">
import { Component, Prop, Ref, Vue, Watch } from 'vue-property-decorator';
import { namespace } from 'vuex-class';
import AssetApi from '../../api/asset-api';
import { isImage } from '../../api/asset-api-helpers';
import assetDetail from '../../assets/asset-detail.vue';
import assetOverview from '../../assets/asset-overview.vue';
import loader from '../../shared/loader.vue';
import modal from '../../shared/modal.vue';
import { ValueSync } from '../../tools/decorators';
import { Asset, AssetTypeFilter, SchemaProperty } from '../../types/api';

const TranslationsStore = namespace('translations');

@Component({
  components: {
    assetOverview,
    assetDetail,
    modal,
    loader
  }
})
export default class AssetPicker extends Vue {
  @ValueSync('value', { type: String }) valueCopy!: string | null;

  @Prop(Number) readonly assetTypeFilterMember!: AssetTypeFilter;
  @Prop() readonly schema!: SchemaProperty;
  @Prop({ default: null }) readonly variantId!: string | null;
  @Prop({ default: false }) readonly required!: boolean;
  @Prop({ default: false }) readonly readonly!: boolean;
  @Ref('asset-detail') readonly assetDetail!: typeof assetDetail;

  asset: Asset | null = null;
  hovering = false;
  previewUrl: string | null = null;
  isInOverviewMode = true;

  @TranslationsStore.State('languageInfos') readonly languageInfos!: Function;

  get assetIsImage() {
    return isImage(this.asset);
  }

  get assetTypeFilterKey() {
    return this.assetTypeFilterMember ?? AssetTypeFilter.All;
  }

  @Watch('valueCopy')
  async updateAssetFromServer() {
    if (this.valueCopy) {
      this.closeModal();
      this.asset = await AssetApi.getAssetById(this.valueCopy);
    }

    this.setPreviewUrl();
  }

  @Watch('variantId')
  onVariantChange() {
    this.setPreviewUrl();
  }

  mounted() {
    this.updateAssetFromServer();
  }

  async setPreviewUrl() {
    this.previewUrl = await AssetApi.getPreviewUrlForAsset(this.asset, this.variantId, 600);
  }

  createAsset() {
    this.isInOverviewMode = false;
  }

  openModal(isInOverviewMode = true) {
    if (this.readonly) {
      return;
    }

    this.isInOverviewMode = isInOverviewMode;

    (this.$refs.modal as modal).show();
  }

  closeModal() {
    (this.$refs.modal as modal).hide();
  }

  deleteItem(): void {
    this.asset = null;
    this.valueCopy = null;
  }

  onFileDrop(e: Event) {
    const target = e.target as HTMLInputElement;
    this.hovering = false;

    this.openModal(false);
    this.$nextTick(() => {
      if (target.files) {
        this.assetDetail.selectFile(target.files[0]);
      }
    });
  }
}
</script>
