<template>
  <main class="entry-page">
    <section class="section">
      <InformationCard
        v-if="informationCardDisplayed"
        :text="$t('pages.upload.description')"
        :title="$t('pages.upload.title')"
      >
        <template v-slot:cross>
          <Button
            icon="bi bi-x-lg"
            look="no-text"
            @trigger="informationCardDisplayed = false"
          />
        </template>
        <template v-slot:button>
          <div class="button-know-more">
            <Link
              :text="$t('pages.upload.know_more_button')"
              :route="{ name: 'why-contribute' }"
              look="button button--white-blue"
              class="entry-button"
            />
          </div>
        </template>
      </InformationCard>
    </section>
    <div class="wrapper-section">
      <section class="sub-section">
        <h2 class="subtitle">{{ $t('pages.upload.subtitle_import') }}</h2>
        <p class="import-text">{{ $t('pages.upload.text_import') }}</p>
        <License
          v-if="authConf && authConf.license && authConf.license.url"
          :url="authConf.license.url"
          :text="authConf.license.id"
          class="entry-license"
        />
        <h2 class="subtitle">{{ $t('pages.upload.title_sequence') }}</h2>
        <p class="import-text">
          {{ $t('pages.upload.description_title_sequence') }}
        </p>
        <EditText
          :default-text="newSequenceTitle || sequenceTitle"
          :is-loading="isLoading"
          :is-loaded="isLoaded"
          @triggerNewText="setNewSequenceTitle"
        />
        <form>
          <div class="wrapper-form">
            <InputUpload
              v-if="inputIsDisplayed"
              :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-displayModal="input-add-pictures"
              @trigger="addPictures"
            />
            <div v-else class="wrapper-uploading">
              <img
                src="@/assets/images/uploading-person.svg"
                alt=""
                class="uploading-img"
              />
              <span>{{ $t('pages.upload.uploading_process') }}</span>
              <span class="loader-text-warning">{{
                $t('pages.upload.leave_message')
              }}</span>
            </div>
          </div>
        </form>
      </section>
      <section class="sub-section">
        <h2 class="subtitle">{{ $t('pages.upload.subtitle_process') }}</h2>
        <UploadLoader
          v-if="isLoading"
          :load-percentage="loadPercentage"
          :is-loaded="isLoaded"
          :uploaded-sequence="uploadedSequence"
          :pictures-count="picturesCount"
          @triggerModal="displayModal"
        />
        <div v-else class="wrapper-no-img">
          <img src="@/assets/images/no-uploaded-img.svg" alt="" />
          <p>{{ $t('pages.upload.no_img_text') }}</p>
        </div>
      </section>
    </div>
    <Modal
      v-if="uploadedSequence && uploadedSequence.picturesOnError"
      ref="modal"
      :upload-errors="uploadedSequence.picturesOnError"
    />
  </main>
</template>

<script lang="ts" setup>
import { ref, computed, watch, onUnmounted, onMounted } 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 Link from '@/components/Link.vue'
import EditText from '@/components/EditText.vue'
import Modal from '@/components/Modal.vue'
import InformationCard from '@/components/InformationCard.vue'
import UploadLoader from '@/components/upload/UploadLoader.vue'
import License from '@/components/License.vue'
import type { SequenceInterface } from './interfaces/UploadPicturesView'
import { formatDate } from '@/utils/dates'
import {
  createAPictureToASequence,
  createASequence
} from '@/views/utils/upload/request'
import { sortByName } from '@/views/utils/upload/index'
import authConfig from '../composables/auth'

const { authConf } = authConfig()
const { t } = useI18n()
let pictures = ref<File[] | []>([])
let picturesCount = ref<number>(0)
let isLoading = ref<boolean>(false)
let isLoaded = ref<boolean>(false)
let informationCardDisplayed = ref<boolean>(true)
let uploadedSequence = ref<SequenceInterface | null>(null)
let picturesUploadingSize = ref<number>(0)
let picturesToUploadSize = ref<number>(0)
let loadPercentage = ref<string>('0%')
let sequenceTitle = ref<string>(formatSequenceTitle())
let newSequenceTitle = ref<string | null>(null)
let modal = ref()

watch(isLoading, () => {
  if (isLoading.value) {
    window.onbeforeunload = function (e) {
      e = e || window.event
      if (e) e.returnValue = 'Sure?'
      return 'Sure?'
    }
  } else {
    window.onbeforeunload = null
  }
})
onMounted(() => {
  setInterval(() => {
    sequenceTitle.value = formatSequenceTitle()
  }, 1000)
})
onUnmounted(() => {
  window.onbeforeunload = null
})
onBeforeRouteLeave((to, from, next) => {
  if (!isLoaded.value && isLoading.value) {
    const answer = window.confirm(t('pages.upload.leave_message'))
    if (answer) return next()
    return next(false)
  }
  next()
})
const inputIsDisplayed = computed<boolean | null>(
  () =>
    !isLoading.value ||
    isLoaded.value ||
    (uploadedSequence.value && !uploadedSequence.value.pictures)
)
function setNewSequenceTitle(value: string | null): void {
  newSequenceTitle.value = value
}
function formatSequenceTitle(): string {
  return `${t('pages.upload.sequence_title')}${formatDate(
    new Date(),
    'Do MMMM YYYY, hh:mm:ss'
  )}`
}
function picturesToUploadSizeText(): void {
  let fullSize = 0
  for (let i = 0; i < pictures.value.length; i++) {
    fullSize += pictures.value[i].size
  }
  picturesToUploadSize.value = fullSize
}
function calcPercentage(): void {
  if (picturesUploadingSize.value && picturesToUploadSize.value) {
    loadPercentage.value = `${(
      (picturesUploadingSize.value / picturesToUploadSize.value) *
      100
    ).toFixed(0)}%`
  }
}

function displayModal(): void {
  if (modal.value) modal.value.show()
}
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%'
  uploadPicture()
}
async function uploadPicture(): Promise<void> {
  if (!pictures.value || !pictures.value.length) {
    return
  }
  isLoaded.value = false
  isLoading.value = true
  picturesToUploadSizeText()
  uploadedSequence.value = null
  const picturesToUpload = [...pictures.value]
  const title = newSequenceTitle.value
    ? newSequenceTitle.value
    : sequenceTitle.value
  const { data } = await createASequence(title)
  uploadedSequence.value = {
    title: title,
    id: data.id,
    pictures: [],
    picturesOnError: [],
    pictureCount: pictures.value.length,
    pictureSize: ''
  }
  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 }
      picturesUploadingSize.value = picturesUploadingSize.value + el.size
      uploadedSequence.value.pictures = [
        ...uploadedSequence.value.pictures,
        pictures
      ]
      calcPercentage()
    } catch (err: any) {
      picturesUploadingSize.value = picturesUploadingSize.value + el.size
      const picturesOnError = {
        message: err.response.data.message,
        details: { error: err.response.data.details.error },
        name: el.name
      }
      uploadedSequence.value.picturesOnError = [
        ...uploadedSequence.value.picturesOnError,
        picturesOnError
      ]
      calcPercentage()
    }
  }
  isLoaded.value = true
  pictures.value = []
  picturesCount.value = 0
  newSequenceTitle.value = null
  sequenceTitle.value = formatSequenceTitle()
}
</script>

<style scoped lang="scss">
ul,
h3 {
  padding-left: 0;
  margin-bottom: 0;
}
.entry-page {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  min-height: calc(100vh - #{toRem(13.82)});
  background-color: var(--grey);
  padding: toRem(2) toRem(5) toRem(5);
  color: var(--grey-dark);
}
.logged {
  min-height: calc(100vh - #{toRem(8)});
}
.section {
  width: 100%;
}
.button-know-more {
  width: toRem(15.5);
  margin-right: toRem(3);
  margin-bottom: toRem(1);
}
.wrapper-section {
  display: flex;
  width: 100%;
  margin-top: toRem(2);
}
.sub-section {
  min-height: toRem(48);
  width: 50%;
  background-color: var(--white);
  padding: toRem(2);
  border-radius: toRem(1.5);
  &:first-child {
    margin-right: toRem(2);
  }
}
.subtitle {
  @include text(h3);
  color: var(--blue-dark);
}
.import-text {
  @include text(m-r-regular);
}
.entry-license {
  margin-bottom: toRem(1);
}
.wrapper-form {
  border: toRem(0.1) dashed var(--blue);
  background-color: var(--blue-pale);
  border-radius: toRem(1.5);
  padding: toRem(2);
}
.wrapper-uploading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.uploading-img {
  height: toRem(20);
}
.loader-text-warning {
  text-align: center;
  @include text(s-r-regular);
  color: var(--orange);
  margin-top: toRem(1);
  width: toRem(31);
}
.wrapper-no-img {
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
@media (max-width: toRem(76.8)) {
  .entry-page {
    padding-top: toRem(15);
  }
  .entry-page {
    padding-right: toRem(2);
    padding-left: toRem(2);
  }
  .wrapper-section {
    flex-direction: column;
  }
  .sub-section {
    width: 100%;
    margin-bottom: toRem(2);
    &:first-child {
      margin-right: 0;
    }
  }
  .wrapper-no-img {
    margin-top: toRem(6);
  }
}
@media (max-width: toRem(50)) {
  .sub-section {
    min-height: initial;
  }
  .uploading-img {
    height: toRem(10);
  }
}
</style>
