<template>
  <BmsInputText
    :modelValue="modelValue"
    :label="label"
    :required="required"
    :optional="optional"
    :disabled="disabled"
    :helperText="helperText"
    :placeholder="placeholder"
    :captions="captions"
    :errors="computedErrors"
    :inputType="InputType.NUMBER"
    :min="min"
    :max="max"
    :step="step"
    @input="onInput"
  />
</template>

<script lang="ts" setup>
import { Ref, computed, ref, watch, onMounted } from 'vue';
import { Caption } from '@/models/caption.model';
import BmsInputText from '@/components/form/BmsInputText.vue';
import { InputType } from '@/models';

export interface Props {
  modelValue: number;
  label?: string;
  required?: boolean;
  optional?: boolean;
  disabled?: boolean;
  helperText?: string;
  placeholder?: string;
  captions?: (string | Caption)[];
  errors?: (string | Caption)[];
  step?: number;
  max?: number;
  min?: number;
}

const props = withDefaults(defineProps<Props>(), {
  label: '',
  required: false,
  disabled: false,
  step: 0,
});

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

const internalErrors: Ref<(string | Caption)[]> = ref([]);
const computedErrors: Ref<(string | Caption)[]> = computed(() => {
  return props.errors
    ? internalErrors.value.concat(props.errors)
    : internalErrors.value;
});

onMounted(() => {
  checkLimit();
});

const $emits = defineEmits<{
  (e: 'update:modelValue', value: number): void;
}>();

const onInput = (e: Event) => {
  if (!props.disabled)
    $emits('update:modelValue', Number((e?.target as HTMLInputElement).value));
};

const checkLimit = () => {
  internalErrors.value = [];
  const hasValue = props.modelValue !== null && props.modelValue !== undefined;
  if (hasValue && props.min !== undefined && props.modelValue < props.min) {
    internalErrors.value = [
      'Valeur inférieure au minimum autorisé (min : ' + props.min + ')',
    ];
  }
  if (props.max !== undefined && props.modelValue > props.max) {
    internalErrors.value = [
      'Valeur supérieure au maximum autorisé (max : ' + props.max + ')',
    ];
  }
};

const setFocus = () => {
  if (input.value) {
    input.value.focus();
  }
};

defineExpose({
  setFocus,
});

watch(
  () => props.modelValue,
  () => checkLimit(),
);
</script>
