<template>
  <div>
    <v-card v-if="!jobApplicationSent">
      <v-card-title class="text-center">
        Formulaire de Candidature
      </v-card-title>

      <v-card-text>
        <v-form ref="form" validate-on="submit lazy" @submit.prevent="submit">
          <v-text-field
            id="jobApplicationName"
            v-model="jobApplication.name"
            :rules="[validateName]"
            label="Nom*"
            required
          />

          <v-text-field
            id="jobApplicationSurname"
            v-model="jobApplication.surname"
            :rules="[validateSurname]"
            label="Prénom*"
            required
          />

          <v-text-field
            id="jobApplicationPhone"
            v-model="jobApplication.phone"
            :rules="[validatePhone]"
            label="Téléphone*"
            required
          />

          <v-text-field
            id="jobApplicationEmail"
            v-model="jobApplication.email"
            :rules="[validateEmail]"
            label="Email*"
            required
          />

          <v-file-input
            id="jobApplicationResume"
            v-model="resumeUpload"
            :rules="[validateResume, validateResumeFileSize]"
            label="Dépôt de CV*"
            accept=".pdf, .jpeg, .png"
            show-size
            required
          />

          <v-file-input
            id="jobApplicationMotivationLetter"
            v-model="motivationLetterUpload"
            :rules="[
              validateMotivationLetter,
              validateMotivationLetterFileSize,
            ]"
            label="Dépôt de lettre de motivation"
            accept=".pdf, .jpeg, .png"
            show-size
          />

          <v-textarea
            id="jobApplicationMessage"
            v-model="jobApplication.message"
            :rules="[validateNonEmptyMessage, validateMessageLength]"
            label="Message*"
            required
          />
          <span class="remaining-cars-notice"
            >{{ leftCars }} caractères restants</span
          >

          <div class="d-flex flex-column align-center mt-4">
            <!-- @see https://github.com/hCaptcha/vue-hcaptcha -->
            <LayoutCaptcha />
          </div>
        </v-form>
      </v-card-text>

      <p class="text-right mr-6">* Champs obligatoires</p>

      <v-card-actions class="justify-center">
        <v-btn class="btn-more mb-4 submit" @click="submit"> Envoyer </v-btn>
      </v-card-actions>
    </v-card>
  </div>
</template>

<script setup lang="ts">
import type { ComputedRef, PropType, Ref } from 'vue'
import { reactive } from 'vue'
import ContactRequest from '~/models/Maestro/ContactRequest'
import { useEntityManager } from '~/composables/data/useEntityManager'
import JobApplication from '~/models/Maestro/JobApplication'
import FileUtils from '~/services/utils/FileUtils'

const props = defineProps({
  jobPostingId: {
    type: Number as PropType<number | null>,
    required: false,
    default: null,
  },
})

const { em } = useEntityManager()

const form: Ref<HTMLElement | null> = ref(null)

const jobApplicationSent: Ref<boolean> = ref(false)

const emit = defineEmits(['submit'])

// @ts-ignore
const jobApplication: ContactRequest = reactive(em.newInstance(JobApplication))

const resumeUpload = ref(null)

const motivationLetterUpload = ref(null)

// --- Validation ---
const maxMessageLength = 2000

const leftCars: ComputedRef<number> = computed(
  () =>
    maxMessageLength -
    (jobApplication.message ? jobApplication.message.length : 0)
)

// Taille maximum en Mo
const maxFileSize = 5

const validateName = (name: string | null) => !!name || 'Le nom est obligatoire'

const validateSurname = (surname: string | null) =>
  !!surname || 'Le prénom est obligatoire'

const validateEmail = (email: string | null) =>
  (!!email && /.+@.+\..+/.test(email)) || "L'adresse e-mail doit être valide"

const validatePhone = (email: string | null) =>
  (!!email && /^((\+|00)33\s?|0)[1-7]([\s.]?\d{2}){4}$/.test(email)) ||
  'Le numéro de téléphone doit être valide'

const validateResume = () =>
  (resumeUpload.value !== null && resumeUpload.value[0] !== null) ||
  "Vous devez joindre un CV à l'un des formats suivants : .pdf, .jpeg, .png"

const validateResumeFileSize = () =>
  (resumeUpload.value !== null &&
    // @ts-ignore
    resumeUpload.value.size < maxFileSize * 1024 * 1024) ||
  'La taille du fichier ne doit pas dépasser ' + maxFileSize + ' Mo'

const validateMotivationLetter = () =>
  motivationLetterUpload.value === null ||
  motivationLetterUpload.value[0] !== null ||
  "Vous devez joindre votre lettre de motivation à l'un des formats suivants : .pdf, .jpeg, .png"

const validateMotivationLetterFileSize = () =>
  motivationLetterUpload.value === null ||
  // @ts-ignore
  motivationLetterUpload.value.size < maxFileSize * 1024 * 1024 ||
  'La taille du fichier ne doit pas dépasser ' + maxFileSize + ' Mo'

const validateNonEmptyMessage = (message: string | null) =>
  (!!message && message.length > 0) || 'Le message ne peut pas être vide'

const validateMessageLength = (message: string | null) =>
  (!!message && message.length <= maxMessageLength) ||
  'Le message ne doit pas dépasser ' + maxMessageLength + ' caractères'

/**
 * Soumet le formulaire de candidature (boite de dialogue)
 */
const submit = async () => {
  jobApplication.jobPostingId = props.jobPostingId

  jobApplication.resume =
    resumeUpload.value !== null
      ? {
          // @ts-ignore
          name: resumeUpload.value.name,
          content: await FileUtils.blobToBase64(resumeUpload.value),
        }
      : null

  jobApplication.motivationLetter =
    motivationLetterUpload.value !== null
      ? {
          // @ts-ignore
          name: motivationLetterUpload.value.name,
          content: await FileUtils.blobToBase64(motivationLetterUpload.value),
        }
      : null

  // @ts-ignore
  const { valid } = await form.value!.validate()

  if (!valid) {
    jobApplicationSent.value = false
    return
  }

  await em.persist(JobApplication, jobApplication)

  jobApplicationSent.value = true

  emit('submit')
}
</script>

<style scoped lang="scss">
.submit {
  width: 100%;
  margin-bottom: 0 !important;
  height: 55px;
  background: var(--secondary-color);
}

.submit:hover {
  background-color: var(--on-neutral-color-extra-light);
}
</style>
