<template>
  <div class="row mb-3 gy-2 gx-2 p-2 scrolling-container">
    <h3>Files <button type="button" class="btn btn-primary upload-btn" @click="chooseFiles">Upload</button></h3>
    <div class="col-sm-12">
      <div class="form-floating mb-3">
        <input type="text" class="form-control" id="floatingInput" placeholder="Search" v-model="search">
        <label for="floatingInput">Search</label>
      </div>
    </div>
    <div v-for="file in searchedFiles" :key="file.id" class="col-4" style="position: relative;">

      <div class="btn-group dropstart context-menu">
        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="dropdown-toggle bi bi-three-dots-vertical" data-bs-toggle="dropdown" aria-expanded="false" viewBox="0 0 16 16">
          <path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/>
        </svg>
        <ul class="dropdown-menu small-dropdown">
          <li><a class="dropdown-item" href="#" @click="deleteFileBtn(file)">Delete</a></li>
        </ul>
      </div>

      <img @click="toggleSelection(file)" :class="getSelectedClass(file)" class="file-thumbnail img-fluid img-thumbnail" :title="file.name" :src="file.thumbnail"/>
      <figcaption class="figure-caption">{{ getFileName(file) }}</figcaption>
    </div>
    <div v-for="upload in uploads" :key="upload.id" class="col-4">
      <div class="row h-100">
        <div class="col-sm-12 my-auto p-3">
          <div class="progress align-middle">
            <div class="progress-bar" role="progressbar" v-bind:style="{ width: upload.progress + '%'}" :aria-valuenow="upload.progress" aria-valuemin="0" aria-valuemax="100"></div>
          </div>
        </div>
      </div>
    </div>
    <input ref="fileUpload" type="file" @change="fileChanged" multiple hidden>
  </div>
</template>

<script>
import { mapActions, mapState, mapMutations } from "vuex";
import path from 'path'

export default {
  name: "Files.vue",
  props: ['project'],
  data() {
    return {
      search: ""
    }
  },
  methods: {
    chooseFiles() {
      this.$refs.fileUpload.click()
    },
    async fileChanged(event) {
      let results = []
      for (let file of event.target.files) {
        let data = new FormData();
        data.append('media', file);
        data.append('project', this.project.url);
        data.append('json', "{}");
        let payload = {
          project_id: this.project.id,
          project_url: this.project.url,
          data
        }
        // Invoke async upload (keep track of Promise)
        results.push(this.createFile(payload))
      }
      for (let result in results) {
        await result
      }
      // Clear file input
      this.$refs.fileUpload.value = null
    },
    async deleteFileBtn(file) {
      await this.deleteFile(file.id)
    },
    toggleSelection(fileObject) {
      if (fileObject != this.previewFile) {
        this.setPreviewFile(fileObject)
      } else {
        this.setPreviewFile(null)
      }
    },
    getSelectedClass(fileObject) {
      if (this.previewFile && fileObject.id == this.previewFile.id) {
        return 'selected'
      } else {
        return ''
      }
    },
    getFileName(fileObject) {
      let base = path.basename(fileObject.media)
      if (base.length < 20) {
        return base
      } else {
        return `${base.substr(0, 18)}...`
      }
    },
    ...mapActions(['loadFiles', 'createFile', 'deleteFile']),
    ...mapMutations((['setPreviewFile', 'setFiles']))
  },
  computed: {
    searchedFiles() {
      return this.files.filter(file => path.basename(file.media).toLowerCase().includes(this.search.toLowerCase()) && file.thumbnail)
    },
    ...mapState(['files', 'previewFile', 'uploads'])
  },
  mounted() {
    this.setFiles([])
    this.loadFiles(this.project.id)
  },
  unmounted() {
    this.setFiles([])
    this.setPreviewFile(null)
  }
}
</script>

<style scoped>
  .scrolling-container {
    max-height: 300px;
    overflow: scroll;
  }
  .upload-btn {
    float: right;
  }
  .selected {
    border: #0d6efd 4px solid;
  }
  .figure-caption {
    font-size: 0.8em;
  }
  .file-thumbnail {
    cursor: pointer;
  }
  .context-menu {
    color: #ffffff;
    position: absolute;
    top: 0%;
    right: 0%;
    padding: 10px;
    cursor: pointer;
  }
  .small-dropdown {
    min-width: 5em;
    opacity: 80%;
  }
</style>