<template>
  <main class="entry-page">
    <section class="upload-section">
      <h1 class="settings-title">{{ $t('pages.upload.title') }}</h1>
      <form v-if="!isLoading" @submit.prevent="uploadPicture">
        <InputUpload
          :text="$t('pages.upload.input_label')"
          :text-second-part="$t('pages.upload.import_word')"
          :text-picture-type="$t('pages.upload.import_type')"
          accept="image/jpeg"
          data-test="input-add-pictures"
          @trigger="addPictures"
        />
        <div class="footer-form">
          <span v-if="fileUploaded" class="number-file-text">{{
            fileUploaded
          }}</span>
          <span v-else class="number-file-text">{{
            t('pages.upload.no_uploaded_files')
          }}</span>
          <Button
            :text="$t('pages.upload.button_text')"
            :disabled="!pictures || pictures.length < 1"
            type="submit"
            data-test="button-upload"
            look="button button--blue"
          />
        </div>
      </form>
      <UploadLoader
        v-else
        :load-percentage="loadPercentage"
        :load-text-size="loadTextSize"
        :is-loaded="isLoaded"
        :uploaded-sequences="uploadedSequences"
        :pictures-count="picturesCount"
        @triggerNewUpload="triggerNewUpload"
      />
    </section>
    <ImportedSection
      v-for="(sequence, i) in uploadedSequences"
      :index="i"
      :sequence="sequence"
      :pictures-count="picturesCount"
      :upload-errors="sequence.picturesOnError"
      :upload-pictures="sequence.pictures"
    />
  </main>
</template>

<script lang="ts" setup>
import { ref, computed, watch, onUnmounted } from 'vue'
import { onBeforeRouteLeave } from 'vue-router'
import { useI18n } from 'vue-i18n'
import InputUpload from '@/components/InputUpload.vue'
import Button from '@/components/Button.vue'
import ImportedSection from '@/components/upload/ImportedSection.vue'
import UploadLoader from '@/components/upload/UploadLoader.vue'
import type { sequenceInterface } from './interfaces/UploadPicturesView'
import { formatDate } from '@/utils/dates'
import {
  createAPictureToASequence,
  createASequence
} from '@/views/utils/upload/request'
import {
  formatPictureSize,
  formatTextSize,
  sortByName
} from '@/views/utils/upload/index'
const { t } = useI18n()
let pictures = ref<File[] | []>([])
let picturesCount = ref<number>(0)
let isLoading = ref<boolean>(false)
let isLoaded = ref<boolean>(false)
let uploadingPictures = ref<FileList | []>([])
let uploadedSequences = ref<sequenceInterface[] | []>([])
let picturesUploadingSize = ref<number>(0)
let picturesToUploadSize = ref<number>(0)
let loadPercentage = ref<string>('0%')
let loadTextSize = ref<string>('0 Mo')

watch(isLoading, () => {
  if (isLoading.value) {
    window.onbeforeunload = function (e) {
      e = e || window.event
      if (e) e.returnValue = 'Sure?'
      return 'Sure?'
    }
  } else {
    window.onbeforeunload = null
  }
})

onUnmounted(() => {
  window.onbeforeunload = null
})
onBeforeRouteLeave((to, from, next) => {
  if (isLoading.value) {
    const answer = window.confirm(t('pages.upload.leave_message'))
    if (answer) return next()
    return next(false)
  }
  next()
})
const fileUploaded = computed<string>(() => {
  return t('pages.upload.uploaded_files', { count: picturesCount.value })
})

function picturesToUploadSizeText(): void {
  let fullSize = 0
  for (let i = 0; i < pictures.value.length; i++) {
    fullSize += pictures.value[i].size
  }
  picturesToUploadSize.value = fullSize
  loadTextSize.value = formatTextSize(fullSize, formatPictureSize(fullSize))
}
function calcPercentage(): void {
  if (picturesUploadingSize.value && picturesToUploadSize.value) {
    loadPercentage.value = `${(
      (picturesUploadingSize.value / picturesToUploadSize.value) *
      100
    ).toFixed(0)}%`
  }
}

function triggerNewUpload(): void {
  isLoading.value = false
  picturesCount.value = 0
}
function addPictures(value: FileList): void {
  const files = sortByName([].slice.call(value))
  pictures.value = files
  picturesCount.value = pictures.value.length
  picturesUploadingSize.value = 0
  picturesToUploadSize.value = 0
  loadPercentage.value = '0%'
  loadTextSize.value = '0 Mo'
}
function setPictureSizeValue(sequence: sequenceInterface, size: number): void {
  picturesUploadingSize.value = picturesUploadingSize.value + size
  sequence.pictureSize = formatTextSize(
    picturesUploadingSize.value,
    formatPictureSize(picturesUploadingSize.value)
  )
}
async function uploadPicture(): Promise<void> {
  if (!pictures.value || !pictures.value.length) {
    return
  }
  isLoaded.value = false
  isLoading.value = true
  picturesToUploadSizeText()
  const picturesToUpload = [...pictures.value]

  const sequenceTitle = `${t('pages.upload.sequence_title')}${formatDate(
    new Date(),
    'Do MMMM YYYY, hh:mm:ss'
  )}`
  const { data } = await createASequence(sequenceTitle)
  const sequence: sequenceInterface = {
    title: sequenceTitle,
    id: data.id,
    pictures: [],
    picturesOnError: [],
    pictureCount: pictures.value.length,
    pictureSize: ''
  }
  uploadedSequences.value = [sequence, ...uploadedSequences.value]
  let i = 0
  for (let el of picturesToUpload) {
    const body = new FormData()
    i++
    body.append('position', i.toString())
    body.append('picture', el)
    try {
      const pictureUploaded = await createAPictureToASequence(data.id, body)
      const pictures = { ...pictureUploaded.data, name: el.name }
      setPictureSizeValue(sequence, el.size)
      sequence.pictures = [...sequence.pictures, pictures]
      const index = uploadedSequences.value.findIndex(
        (item: sequenceInterface) => item.id === data.id
      )
      uploadedSequences.value.splice(index, 1)
      uploadedSequences.value = [sequence, ...uploadedSequences.value]
      calcPercentage()
    } catch (err: any) {
      setPictureSizeValue(sequence, el.size)
      const picturesOnError = {
        message: err.response.data.message,
        name: el.name
      }
      sequence.picturesOnError = [...sequence.picturesOnError, picturesOnError]
      calcPercentage()
    }
  }
  isLoaded.value = true
  uploadingPictures.value = []
  pictures.value = []
}
</script>

<style scoped lang="scss">
ul {
  padding-left: 0;
  margin-bottom: 0;
}
.entry-page {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  min-height: calc(100vh - #{toRem(27.42)});
}
.upload-section {
  width: 80%;
  padding: toRem(4);
  margin-top: toRem(6);
  margin-bottom: toRem(4);
  box-shadow: 0px 6.45694px 8.60925px rgba(0, 0, 0, 0.05);
}
.settings-title {
  text-align: center;
  @include text(h1);
  margin-bottom: toRem(4);
}
.footer-form {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  margin-top: toRem(3);
}
.number-file-text {
  margin-bottom: toRem(2);
  color: var(--blue-dark);
  @include text(s-regular);
}
::-webkit-scrollbar {
  width: toRem(2);
}
::-webkit-scrollbar-track {
  background: var(--grey-pale);
}
::-webkit-scrollbar-thumb {
  background: var(--blue);
  border-radius: toRem(5);
}
@media (max-width: toRem(76.8)) {
  .entry-page {
    overflow-x: hidden;
  }
  .information-section {
    flex-direction: column;
  }
}
@media (max-width: toRem(50)) {
  .upload-section {
    margin-top: toRem(15);
    width: 100%;
    padding-right: toRem(2);
    padding-left: toRem(2);
  }
  .information-section {
    width: 100%;
  }
}
</style>
