<template>
  <LayoutContainer>
    <div id="anchor" />

    <h4><span class="line" /> Veuillez remplir le formulaire ci-dessous</h4>

    <v-form
      v-if="!contactRequestSent"
      ref="form"
      validate-on="submit lazy"
      @submit.prevent="submit"
    >
      <v-container>
        <i
          >Les champs dont le nom est suivi d'un astérisque (*) sont
          obligatoires.</i
        >

        <h6>Vos coordonnées</h6>

        <!-- Gender selection -->
        <v-row>
          <v-col cols="12">
            <v-select
              v-model="contactRequest.gender"
              label="Genre*"
              :items="['Madame', 'Monsieur']"
              mandatory
            />
          </v-col>
        </v-row>

        <!-- Name and Surname -->
        <v-row>
          <v-col cols="12" md="6">
            <v-text-field
              v-model="contactRequest.name"
              :rules="[validateName]"
              label="Nom*"
              required
            />
          </v-col>

          <v-col cols="12" md="6">
            <v-text-field
              v-model="contactRequest.surname"
              :rules="[validateSurname]"
              label="Prénom*"
              required
            />
          </v-col>
        </v-row>

        <!-- Postal code and city -->
        <v-row>
          <v-col cols="12" md="6">
            <v-text-field
              v-model="contactRequest.postalCode"
              label="Code postal*"
              :rules="[validatePostalCode]"
            />
          </v-col>

          <v-col cols="12" md="6">
            <v-text-field
              v-model="contactRequest.city"
              label="Ville*"
              :rules="[validateCity]"
            />
          </v-col>
        </v-row>

        <!-- Email and phone on the same line -->
        <v-row>
          <v-col cols="12" md="6">
            <v-text-field
              v-model="contactRequest.email"
              :rules="[validateEmail]"
              label="Email*"
              required
              type="email"
            />
          </v-col>

          <v-col cols="12" md="6">
            <v-text-field
              v-model="contactRequest.phone"
              :rules="[validatePhone]"
              label="Téléphone*"
              type="tel"
            />
          </v-col>
        </v-row>

        <!-- Structure name  -->
        <v-row>
          <v-col cols="12">
            <v-text-field
              v-model="contactRequest.structureName"
              :rules="[validateStructureName]"
              label="Nom de la structure*"
              required
            />
          </v-col>
        </v-row>

        <h6>Votre demande concerne *</h6>

        <!-- Request type and product concerned  -->
        <v-row>
          <v-col cols="12" md="6">
            <v-select
              v-model="contactRequest.requestType"
              :items="requestTypes"
              item-value="id"
              item-title="label"
              variant="outlined"
            />
          </v-col>

          <v-col cols="12" md="6">
            <v-select
              v-model="contactRequest.concernedProduct"
              label="Produit concerné (facultatif)"
              :items="products"
              item-value="id"
              item-title="label"
              variant="outlined"
            />
          </v-col>
        </v-row>

        <h6>Votre message</h6>

        <!-- Message  -->
        <v-row class="mb-8">
          <v-col cols="12">
            <v-textarea
              v-model="contactRequest.message"
              :rules="[validateNonEmptyMessage, validateMessageLength]"
              label="Votre message*"
              required
              maxlength="400"
            />
            <span class="remaining-cars-notice"
              >{{ leftCars }} caractères restants</span
            >
          </v-col>
        </v-row>

        <!-- Policy and  checkboxes -->
        <v-checkbox
          v-model="contactRequest.privacyPolicyAccepted"
          :rules="[
            (v: boolean) =>
              v || 'Vous devez accepter la politique de confidentialité',
          ]"
          label="J'ai pris connaissance de la politique de confidentialité et j'accepte le traitement de mes données personnelles par Opentalent. *"
        />

        <v-checkbox
          v-model="contactRequest.newsletterSubscription"
          label="Je souhaite recevoir des communications d'Opentalent par email (promotions, informations logiciel…). Je pourrai me désinscrire à tout moment."
        />

        <div class="d-flex flex-row justify-center">
          <!-- @see https://github.com/hCaptcha/vue-hcaptcha -->
          <LayoutCaptcha />
        </div>

        <!-- Submit Button -->
        <div class="d-flex flex-row justify-center my-10">
          <v-btn
            type="submit"
            variant="outlined"
            :height="54"
            :width="180"
            class="submit-btn"
          >
            Envoyer
          </v-btn>
        </div>

        <div v-if="errorMsg" class="error">
          {{ errorMsg }}
        </div>
      </v-container>

      <div class="legal">
        Les données recueillies par Opentalent sont utilisées pour le traitement
        de votre demande et pour vous informer sur nos offres. Elles sont
        destinées aux services Opentalent et à ses sous-traitants pour
        l’exécution des contrats. Conformément à la loi "Informatique et
        Libertés du 6 Janvier 1978", vous disposez d’un droit d’accès, de
        modifications, de rectification et de suppression des données vous
        concernant. Pour toute demande, adressez-vous à : OPENTALENT, 265 rue de
        la Grange 74950 SCIONZIER - FRANCE, opentalent.fr s’engage à la
        confidentialité et à la protection de vos données.”
      </div>
    </v-form>

    <div v-else class="confirmation-message d-flex flex-row justify-center">
      <v-card>
        <v-icon icon="fas fa-check mr-1" />
        Votre demande de contact a bien été enregistrée, nous reviendrons vers
        vous dès que possible.
      </v-card>
    </div>
  </LayoutContainer>
</template>

<script setup lang="ts">
import { useRouter } from 'vue-router'
import type { ComputedRef, Ref } from 'vue'
import { reactive } from 'vue'
import ContactRequest from '~/models/Maestro/ContactRequest'
import { useEntityManager } from '~/composables/data/useEntityManager'

const route = useRoute()
const router = useRouter()
const { em } = useEntityManager()

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

const requestTypes: Array<{ id: string; label: string }> = [
  { id: 'CONTACT_REQUEST_INFORMATION', label: "Demande d'information" },
  { id: 'CONTACT_REQUEST_ESTIMATE', label: 'Demande de devis' },
  { id: 'CONTACT_REQUEST_DEMO', label: 'Demande de démonstration' },
  { id: 'CONTACT_REQUEST_OPTION', label: "Demande d'option supplémentaire" },
  { id: 'CONTACT_REQUEST_OTHER', label: 'Autre' },
]

const products: Array<{ id: string; label: string }> = [
  { id: 'PRODUCT_AGENDA', label: 'Agenda culturel' },
  { id: 'PRODUCT_ARTIST', label: 'Opentalent Artist' },
  { id: 'PRODUCT_SCHOOL', label: 'Opentalent School' },
  { id: 'PRODUCT_MANAGER', label: 'Opentalent Manager' },
  { id: 'PRODUCT_ADVERTISING', label: 'Publicité' },
  { id: 'PRODUCT_OTHER', label: 'Autre' },
]

const defaultRequestType = route.query.request ?? 'CONTACT_REQUEST_INFORMATION'

// @ts-ignore
const contactRequest: ContactRequest = reactive(
  em.newInstance(ContactRequest, { requestType: defaultRequestType })
)

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

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

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

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

const validatePostalCode = (postalCode: string | null) =>
  (!!postalCode && /^\d{5}$/.test(postalCode)) ||
  'Le code postal doit être valide'

const validateCity = (city: string | null) =>
  !!city || 'La ville est obligatoire'

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

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

const validateStructureName = (structureName: string | null) =>
  !!structureName || 'Le nom de la structure est requis'

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'

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

const errorMsg: Ref<string | null> = ref(null)

/**
 * Submits the contact form.
 *
 * This function validates the form and sets the value of a variable to indicate whether the form submission was successful.
 *
 * @function
 *
 * @returns {void}
 */
const submit = async (): Promise<void> => {
  const { valid } = await form.value!.validate()

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

  try {
    await em.persist(ContactRequest, contactRequest)
  } catch (e) {
    errorMsg.value =
      "Une erreur s'est produite, nous sommes navrés pour le désagrément. Veuillez réessayer plus tard."
    return
  }

  contactRequestSent.value = true
  errorMsg.value = null

  // Défile vers le début de page pour afficher le message de confirmation
  setTimeout(() => router.push({ path: '', hash: '#anchor' }), 30)
}
</script>

<style scoped lang="scss">
h4 {
  display: flex;
  flex-direction: row;
  font-size: 40px;
  line-height: 95px;
  margin-bottom: 1rem;
  align-items: center;
  font-weight: 100;

  @media (max-width: 600px) {
    font-size: 24px;
    line-height: 48px;
  }

  .line {
    display: block;
    height: 1px;
    width: 64px;
    min-width: 64px;
    border-top: solid 1px var(--on-neutral-color);
    margin-right: 18px;
  }
}

.v-form {
  max-width: 1400px;
  margin: 0 auto;

  h6 {
    margin-top: 32px;
    font-size: 16px;
    margin-bottom: 1rem;
    text-transform: uppercase;
    font-weight: 600;
    letter-spacing: 0.1em;
  }

  .v-select {
    .v-field {
      border-radius: 0;
    }
  }

  .remaining-cars-notice {
    font-size: 13px;
    font-weight: 550;
    opacity: 0.6;
  }

  .submit-btn {
    border-radius: 0;
    font-weight: 600;
  }

  .error {
    color: red;
    width: 80%;
    margin: 0 auto 2em;
    text-align: center;
  }

  .legal {
    opacity: 0.7;
    font-size: 14px;
    font-style: italic;
    margin-left: auto;
    margin-right: auto;
    max-width: 80%;
  }
}

.confirmation-message {
  .v-card {
    .v-icon {
      color: green;
    }

    max-width: 1200px;
    padding: 24px;
    margin: 128px 0;
    font-weight: 500;
  }
}
</style>
