<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, validateFileSize]"
            label="Dépôt de CV*"
            accept=".pdf, .jpeg, .png"
            show-size
            required
          />

          <v-file-input
            id="jobApplicationMotivationLetter"
            v-model="motivationLetterUpload"
            :rules="[validateFileSize]"
            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, reactive, Ref } 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 { 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 indiqués";

const validateFileSize = () =>
  (resumeUpload.value !== null &&
    resumeUpload.value[0] !== null &&
    // @ts-ignore
    resumeUpload.value[0].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 () => {
  const { valid } = await form.value.validate();

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

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

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

  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>
