<template>
  <DialogBase
    ref="dialogWindow"
    :closeOnButtonClick="false"
    :closeOnFocusLost="false"
    :maxSize="true"
    :enableFooterButtons="uploadable"
    title="Upload audio files..."
    buttonText="Upload"
    buttonClass="success large"
    @accept="uploadFiles(0)"
    @closing="closing"
  >
    <div class="flex-column grow">
      <input
        style="display: none"
        ref="files"
        type="file"
        accept="audio/*"
        @change="openFiles"
        multiple
      />
      <ul id="audioUploadFiles">
        <li v-for="(file, i) in files" :key="i" class="pa-top">
          <h4 class="ma-left darkgray-text">{{ file.name }}</h4>
          <div class="flex-row ma">
            <awesome-icon
              :icon="file.state == 'uploading' ? 'upload' : 'check'"
              size="2x"
              :class="{
                'success-text': file.state == 'done',
                'gray-text': file.state == 'ready',
                'primary-text': file.state == 'uploading',
              }"
            />
            <input
              placeholder="artist name"
              type="text"
              v-model="file.tags.artist"
              class="left pa8"
            />
            <input
              placeholder="album name"
              type="text"
              v-model="file.tags.album"
              class="pa8"
            />
            <input
              placeholder="track number"
              title="track number"
              type="text"
              v-model="file.tags.track"
              style="width: 32px"
              class="right pa8"
            />
            <input
              placeholder="track title"
              type="text"
              v-model="file.tags.title"
              class="pa8 grow"
            />
            <input
              placeholder="genre"
              type="text"
              v-model="file.tags.genre"
              class="pa8"
            />
            <input
              placeholder="year"
              type="text"
              v-model="file.tags.year"
              style="width: 48px"
              class="right pa8"
            />
            <button
              class="danger"
              title="Remove from list"
              @click="remove(file)"
            >
              <awesome-icon icon="minus" />
            </button>
          </div>
          <hr />
        </li>
      </ul>

      <div
        class="flex-column grow center ma primary-text"
        id="dropzone"
        @dragover="dropover"
        @drop="droped"
        @click="emitFileClick"
      >
        <h2>
          Drop your files here<br />
          <awesome-icon icon="plus" size="4x" />
        </h2>
      </div>
    </div>
  </DialogBase>
</template>



<script>
import mmreader from "mp3tag.js";

export default {
  data() {
    return {
      files: [],
    };
  },
  methods: {
    open() {
      this.$refs.dialogWindow.open();
    },
    closing() {
      this.files = [];
    },
    dropover(e) {
      e.preventDefault();
      e.stopPropagation();
    },
    droped(e) {
      e.preventDefault();
      e.stopPropagation();
      let files = [];
      for (let i = 0; i < e.dataTransfer.files.length; i++) {
        let file = e.dataTransfer.files[i];
        if (file.type.indexOf("audio/") == 0) {
          files.push({ file: file, state: "ready" });
        }
      }
      if (files.length > 0) {
        this.readTags(files, 0);
      }
    },
    emitFileClick() {
      this.$refs.files.click();
    },
    openFiles(e) {
      let files = [];
      if (e.srcElement.value) {
        for (let i = 0; i < e.srcElement.files.length; i++) {
          let file = e.srcElement.files[i];
          files.push({ file: file, state: "ready" });
        }
        this.readTags(files, 0);
      }
    },
    readTags(files, index) {
      let fileReader = new FileReader();
      var file = files[index];
      fileReader.onload = () => {
        if (!this.files.find((f) => f.file.name == file.file.name)) {
          const mp3tag = new mmreader(fileReader.result);
          mp3tag.read();
          file.tags = {};
          file.tags.title = mp3tag.tags.title;
          file.tags.artist = mp3tag.tags.artist;
          file.tags.album = mp3tag.tags.album;
          file.tags.track = mp3tag.tags.track;
          file.tags.year = mp3tag.tags.year;
          if (!file.tags.title || file.tags.title.trim() == "") {
            file.tags.title = file.file.name;
          }
          this.files.push(file);
        }
        if (files.length > index + 1) {
          this.readTags(files, ++index);
        } else {
          this.files.sort((a, b) => {
            if (
              a.tags.artist > b.tags.artist ||
              (a.tags.artist == b.tags.artist && a.tags.album > b.tags.album) ||
              (a.tags.artist == b.tags.artist &&
                a.tags.album == b.tags.album &&
                a.tags.track > b.tags.track) ||
              (a.tags.artist == b.tags.artist &&
                a.tags.album == b.tags.album &&
                a.tags.track == b.tags.track &&
                a.tags.title > b.tags.title)
            ) {
              return 1;
            }
            return -1;
          });
        }
      };
      fileReader.readAsArrayBuffer(file.file);
    },
    remove(file) {
      this.files.splice(this.files.indexOf(file), 1);
    },
    uploadFiles(index = 0) {
      if (this.files.length > index) {
        let file = this.files[index];
        if (file.state == "ready") {
          file.state = "uploading";
          let formData = new FormData();

          formData.append("file", file.file);
          formData.append("track", JSON.stringify(file.tags));

          this.$store
            .dispatch("tracks/upload", formData)
            .then(() => {
              file.state = "done";
              this.uploadFiles(++index);
            })
            .catch((err) => {
              console.log(err);
              this.$refs.dialogWindow.messageText = err;
            });
        } else {
          this.uploadFiles(++index);
        }
      } else {
        this.$store.dispatch("albums/loadNewest");
        this.$refs.dialogWindow.close();
      }
    },
  },
  computed: {
    uploadable() {
      let has_empty_artist =
        this.files.find((f) => (f.tags.artist || "").trim() == "") != undefined;
      let has_empty_album =
        this.files.find((f) => (f.tags.album || "").trim() == "") != undefined;
      let has_empty_title =
        this.files.find((f) => (f.tags.title || "").trim() == "") != undefined;
      let has_empty_track =
        this.files.find((f) => (f.tags.track || "").trim() == "") != undefined;
      return (
        !has_empty_artist &&
        !has_empty_album &&
        !has_empty_title &&
        !has_empty_track
      );
    },
  },
};
</script>

<style scoped>
#audioUploadFiles input {
  border: none;
  font-size: large;
}
#audioUploadFiles button {
  height: 32px;
  min-width: 32px;
  justify-content: center;
  align-self: center;
  border-radius: 16px;
}
#dropzone {
  border: 2px dashed var(--primary);
  cursor: pointer;
}
</style>