<template>
  <div class="relative w-full py-4 px-6 border border-white border-opacity-10 shadow-lg rounded-md my-6">
    <div class="absolute -top-3 -left-3 w-8 h-8 bg-bg border border-white border-opacity-10 flex items-center justify-center rounded-full">
      <p class="text-base text-white text-opacity-80 font-mono">#{{ item.index }}</p>
    </div>

    <div v-if="!processing && !uploadFailed && !uploadSuccess" class="absolute -top-3 -right-3 w-8 h-8 bg-bg border border-white border-opacity-10 flex items-center justify-center rounded-full hover:bg-error cursor-pointer" @click="$emit('remove')">
      <span class="text-base text-white text-opacity-80 font-mono material-icons">close</span>
    </div>

    <template v-if="!uploadSuccess && !uploadFailed">
      <widgets-alert v-if="error" type="error">
        <p class="text-base">{{ error }}</p>
      </widgets-alert>

      <div class="flex my-2 -mx-2">
        <div class="w-1/2 px-2">
          <ui-text-input-with-label v-model.trim="itemData.title" :disabled="processing" :label="$strings.LabelTitle" @input="titleUpdated" />
        </div>
        <div class="w-1/2 px-2">
          <div v-if="!isPodcast" class="flex items-end">
            <ui-text-input-with-label v-model.trim="itemData.author" :disabled="processing" :label="$strings.LabelAuthor" />
            <ui-tooltip :text="$strings.LabelUploaderItemFetchMetadataHelp">
              <div
                class="ml-2 mb-1 w-8 h-8 bg-bg border border-white border-opacity-10 flex items-center justify-center rounded-full hover:bg-primary cursor-pointer"
                @click="fetchMetadata">
                <span class="text-base text-white text-opacity-80 font-mono material-icons">sync</span>
              </div>
            </ui-tooltip>
          </div>
          <div v-else class="w-full">
            <p class="px-1 text-sm font-semibold">{{ $strings.LabelDirectory }} <em class="font-normal text-xs pl-2">(auto)</em></p>
            <ui-text-input :value="directory" disabled class="w-full font-mono text-xs" />
          </div>
        </div>
      </div>
      <div v-if="!isPodcast" class="flex my-2 -mx-2">
        <div class="w-1/2 px-2">
          <ui-text-input-with-label v-model.trim="itemData.series" :disabled="processing" :label="$strings.LabelSeries" note="(optional)" inputClass="h-10" />
        </div>
        <div class="w-1/2 px-2">
          <div class="w-full">
            <label class="px-1 text-sm font-semibold">{{ $strings.LabelDirectory }} <em class="font-normal text-xs pl-2">(auto)</em></label>
            <ui-text-input :value="directory" disabled class="w-full font-mono text-xs h-10" />
          </div>
        </div>
      </div>

      <tables-uploaded-files-table :files="item.itemFiles" :title="$strings.HeaderItemFiles" class="mt-8" />
      <tables-uploaded-files-table v-if="item.otherFiles.length" :title="$strings.HeaderOtherFiles" :files="item.otherFiles" />
      <tables-uploaded-files-table v-if="item.ignoredFiles.length" :title="$strings.HeaderIgnoredFiles" :files="item.ignoredFiles" />
    </template>
    <widgets-alert v-if="uploadSuccess" type="success">
      <p class="text-base">{{ $strings.MessageUploaderItemSuccess }}</p>
    </widgets-alert>
    <widgets-alert v-if="uploadFailed" type="error">
      <p class="text-base">{{ $strings.MessageUploaderItemFailed }}</p>
    </widgets-alert>

    <div v-if="isNonInteractable" class="absolute top-0 left-0 w-full h-full bg-black bg-opacity-50 flex items-center justify-center z-20">
      <ui-loading-indicator :text="nonInteractionLabel" />
    </div>
  </div>
</template>

<script>
import Path from 'path'

export default {
  props: {
    item: {
      type: Object,
      default: () => { }
    },
    mediaType: String,
    processing: Boolean,
    provider: String
  },
  data() {
    return {
      itemData: {
        title: '',
        author: '',
        series: ''
      },
      error: '',
      isUploading: false,
      uploadFailed: false,
      uploadSuccess: false,
      isFetchingMetadata: false
    }
  },
  computed: {
    isPodcast() {
      return this.mediaType === 'podcast'
    },
    directory() {
      if (!this.itemData.title) return ''
      if (this.isPodcast) return this.itemData.title

      const outputPathParts = [this.itemData.author, this.itemData.series, this.itemData.title]
      const cleanedOutputPathParts = outputPathParts.filter(Boolean).map(part => this.$sanitizeFilename(part))

      return Path.join(...cleanedOutputPathParts)
    },
    isNonInteractable() {
      return this.isUploading || this.isFetchingMetadata
    },
    nonInteractionLabel() {
      if (this.isUploading) {
        return this.$strings.MessageUploading
      } else if (this.isFetchingMetadata) {
        return this.$strings.LabelFetchingMetadata
      }
    }
  },
  methods: {
    setUploadStatus(status) {
      this.isUploading = status === 'uploading'
      this.uploadFailed = status === 'failed'
      this.uploadSuccess = status === 'success'
    },
    titleUpdated() {
      this.error = ''
    },
    async fetchMetadata() {
      if (!this.itemData.title.trim().length) {
        return
      }

      this.isFetchingMetadata = true
      this.error = ''

      try {
        const searchQueryString = new URLSearchParams({
          title: this.itemData.title,
          author: this.itemData.author,
          provider: this.provider
        })
        const [bestCandidate, ..._rest] = await this.$axios.$get(`/api/search/books?${searchQueryString}`)

        if (bestCandidate) {
          this.itemData = {
            ...this.itemData,
            title: bestCandidate.title,
            author: bestCandidate.author,
            series: (bestCandidate.series || [])[0]?.series
          }
        } else {
          this.error = this.$strings.ErrorUploadFetchMetadataNoResults
        }
      } catch (e) {
        console.error('Failed', e)
        this.error = this.$strings.ErrorUploadFetchMetadataAPI
      } finally {
        this.isFetchingMetadata = false
      }
    },
    getData() {
      if (!this.itemData.title) {
        this.error = this.$strings.ErrorUploadLacksTitle
        return null
      }
      this.error = ''
      var files = this.item.itemFiles.concat(this.item.otherFiles)
      return {
        index: this.item.index,
        directory: this.directory,
        ...this.itemData,
        files
      }
    }
  },
  mounted() {
    if (this.item) {
      this.itemData.title = this.item.title
      this.itemData.author = this.item.author
      this.itemData.series = this.item.series
    }
  }
}
</script>
