<!--
Champs de saisie de texte, à placer dans un composant `UiForm`

@see https://vuetifyjs.com/en/components/text-fields/
-->

<template>
  <v-text-field
    ref="input"
    :model-value="modelValue"
    :label="(label || field) ? $t(label ?? field) : undefined"
    :rules="rules"
    :disabled="readonly"
    :type="(type === 'password' && show) ? 'text' : type"
    :error="error || !!fieldViolations"
    :error-messages="errorMessage || (fieldViolations ? $t(fieldViolations) : '')"
    :append-icon="type === 'password' ? (show ? 'mdi-eye' : 'mdi-eye-off') : ''"
    @click:append="show = !show"
    @update:model-value="onUpdate($event)"
    @change="onChange($event)"
  />


<!--  v-cleave="mask"-->
</template>

<script setup lang="ts">
import {ref} from "@vue/reactivity";
import {useFieldViolation} from "~/composables/form/useFieldViolation";
import {PropType} from "@vue/runtime-core";

const props = defineProps({
  /**
   * v-model
   */
  modelValue: {
    type: [String, Number],
    required: false,
    default: null
  },
  /**
   * Nom de la propriété d'une entité lorsque l'input concerne cette propriété
   * - Utilisé par la validation
   * - Laisser null si le champ ne s'applique pas à une entité
   */
  field: {
    type: String,
    required: false,
    default: null
  },
  /**
   * Label du champ
   * Si non défini, c'est le nom de propriété qui est utilisé
   */
  label: {
    type: String,
    required: false,
    default: null
  },
  /**
   * Type d'input HTML
   * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/button
   */
  type: {
    type: String,
    required: false,
    default: null
  },
  /**
   * Définit si le champ est en lecture seule
   */
  readonly: {
    type: Boolean,
    required: false,
    default: false
  },
  /**
   * Règles de validation
   * @see https://vuetify.cn/en/components/forms/#validation-with-submit-clear
   */
  rules: {
    type: Array as PropType<any[]>,
    required: false,
    default: () => []
  },
  /**
   * Le champ est-il actuellement en état d'erreur
   */
  error: {
    type: Boolean,
    required: false,
    default: false
  },
  /**
   * Si le champ est en état d'erreur, quel est le message d'erreur?
   */
  errorMessage: {
    type: String,
    required: false,
    default: null
  },
  /**
   * Masque de saisie
   * @see https://github.com/nosir/cleave.js/
   */
  mask: {
    type: [Array, Boolean],
    required: false,
    default: false
  }
})

const input = ref(null)

const { fieldViolations, updateViolationState } = useFieldViolation(props.field)

const show = ref(false)

const emit = defineEmits(['update:model-value', 'change'])

const onUpdate = (event: string) => {
  emit('update:model-value', event)
}

const onChange = (event: Event | undefined) => {
  updateViolationState(event)
  emit('change', event)
}
</script>

<style scoped lang="scss">
  input:read-only{
    color: rgb(var(--v-theme-neutral));
  }
</style>
