<template>
  <main>
    <LayoutContainer>
      <UiForm
        ref="form"
        v-model="subdomain"
        :submit-actions="submitActions"
        :validation-pending="validationPending"
        :refresh-profile="true"
      >
        <v-container :fluid="true" class="container">
          <v-row>
            <v-col cols="12" sm="6">
              <div>{{ $t('pleaseEnterYourNewSubdomain') }} :</div>
            </v-col>
          </v-row>
          <v-row>
            <v-col cols="12" sm="6">
              <UiInputText
                v-model="subdomain.subdomain"
                field="subdomain"
                type="string"
                :rules="rules()"
                @update:model-value="onSubdomainUpdate"
              />
            </v-col>
          </v-row>
          <div class="validationMessage">
            <span v-if="validationPending">
              <v-progress-circular size="16" indeterminate />
              <i class="ml-2">{{ $t('validation_ongoing') }}</i>
            </span>
            <span v-else-if="subdomainAvailable === true" class="text-success">
              <v-icon>fa fa-check</v-icon>
              <i class="ml-2">{{ $t('this_subdomain_is_available') }}</i>
            </span>
          </div>
        </v-container>

        <template #form.button>
          <NuxtLink to="/parameters/website" class="no-decoration">
            <v-btn class="mr-4 theme-neutral">
              {{ $t('back') }}
            </v-btn>
          </NuxtLink>
        </template>
      </UiForm>
    </LayoutContainer>
  </main>
</template>

<script setup lang="ts">
import type { Ref } from 'vue'
import _ from 'lodash'
import { useEntityManager } from '~/composables/data/useEntityManager'
import Subdomain from '~/models/Organization/Subdomain'
import { SUBMIT_TYPE } from '~/types/enum/enums'
import type { AnyJson } from '~/types/data'
import SubdomainValidation from '~/services/validation/subdomainValidation'
import { useSubdomainValidation } from '~/composables/form/validation/useSubdomainValidation'
import Form from '~/components/Ui/Form.vue'

const i18n = useI18n()

const { em } = useEntityManager()
const { subdomainValidation } = useSubdomainValidation()

const organizationProfileStore = useOrganizationProfileStore()

// @ts-expect-error TODO à résoudre quand l'EM pourra gérer les types génériques
const subdomain: Ref<Subdomain> = ref(
  em.newInstance(Subdomain, { organization: organizationProfileStore.id }),
)

const submitActions = computed(() => {
  const actions: AnyJson = {}
  actions[SUBMIT_TYPE.SAVE_AND_BACK] = '/parameters/website'
  return actions
})

const form: Ref<typeof Form | null> = ref(null)
const subdomainAvailable: Ref<boolean | null> = ref(null)
const validationPending: Ref<boolean> = ref(false)

/**
 * Délai entre le dernier caractère saisi et la requête de vérification de la disponibilité du sous-domaine (en ms)
 */
const inputDelay = 600

/**
 * Procède à la vérification de disponibilité.
 * @param subdomain
 */
const checkAvailability = async (subdomain: string) => {
  subdomainAvailable.value = await subdomainValidation.isAvailable(subdomain)
  validationPending.value = false

  form.value!.validate()
}

/**
 * Version debounced de la fonction checkAvailability
 * @see https://docs-lodash.com/v4/debounce/
 */
const checkAvailabilityDebounced: _.DebouncedFunc<() => void> = _.debounce(
  async () => {
    if (subdomain.value.subdomain === null) {
      return
    }
    await checkAvailability(subdomain.value.subdomain)
  },
  inputDelay,
)

const onSubdomainUpdate = () => {
  subdomainAvailable.value = null
  validationPending.value = true
  checkAvailabilityDebounced()
}

/**
 * Règles de validation
 */
const rules = () => [
  (subdomain: string | null) =>
    (subdomain !== null && subdomain.length > 0) ||
    i18n.t('please_enter_a_value_for_the_subdomain'),
  (subdomain: string | null) =>
    (subdomain !== null && subdomain.length >= 2 && subdomain.length <= 60) ||
    i18n.t('subdomain_need_to_have_0_to_60_cars'),
  (subdomain: string | null) =>
    SubdomainValidation.isValid(subdomain) ||
    i18n.t('subdomain_can_not_contain_spaces_or_special_cars'),
  () =>
    subdomainAvailable.value !== false ||
    i18n.t('this_subdomain_is_already_in_use'),
]
</script>

<style scoped lang="scss">
.validationMessage {
  height: 20px;
  min-height: 20px;
}
</style>
