<template>
  <field v-bind="$props" :errors="allErrors" class="field-between">
    <RawInputText
      :type="inputType"
      :modelValue="valueFrom"
      :placeholder="placeholderFrom"
      :required="required"
      :errors="errors"
      @input="onInput($event, 'from')"
    >
      <template #label>
        {{ inputType === InputType.NUMBER ? 'Entre' : 'Du' }}
      </template>
    </RawInputText>

    <ArrowRight :size="40" class="field-between__separator" />

    <RawInputText
      :type="inputType"
      :modelValue="valueTo"
      :placeholder="placeholderTo"
      :required="required"
      :errors="allErrors"
      @input="onInput($event, 'to')"
    >
      <template #label>
        {{ inputType === InputType.NUMBER ? 'Et' : 'Au' }}
      </template>
    </RawInputText>
  </field>
</template>

<script lang="ts" setup>
import { computed, Ref, ref } from 'vue';
import { Caption } from '@/models/caption.model';
import RawInputText from '@/components/form/RawInputText.vue';
import { ArrowRight } from 'lucide-vue-next';
import { InputType } from '@/models';

export interface Props {
  inputType: InputType.NUMBER | InputType.DATE | InputType.DATETIME;
  valueFrom?: any;
  valueTo?: any;
  label?: string;
  required?: boolean;
  optional?: boolean;
  disabled?: boolean;
  helperText?: string;
  placeholderFrom?: string;
  placeholderTo?: string;
  captions?: (string | Caption)[];
  errors?: (string | Caption)[];
}

const props = withDefaults(defineProps<Props>(), {
  inputType: InputType.NUMBER,
  valueFrom: 0,
  valueTo: 0,
  label: '',
  requiredFrom: false,
  requiredTo: false,
  disabled: false,
});

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

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

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

defineExpose({
  setFocus,
});

const allErrors = computed(() => {
  let msg = null;
  if (
    props.inputType === InputType.NUMBER &&
    props.valueTo &&
    props.valueFrom > props.valueTo &&
    Number(props.valueTo) > 0
  ) {
    msg = 'La seconde valeur doit être supérieure à la première';
  }
  try {
    if (
      props.inputType !== InputType.NUMBER &&
      props.valueTo !== 0 &&
      new Date(props.valueFrom) > new Date(props.valueTo)
    ) {
      msg = 'La seconde date doit être supérieure à la première';
    }
  } catch (e) {
    return props.errors;
  }
  if (msg) {
    return props.errors?.length
      ? ([...props.errors].concat([msg]) as (string | Caption)[])
      : [msg];
  }
  return props.errors;
});

const onInput = (e: Event, emitter: 'from' | 'to') => {
  if (!props.disabled) {
    const value = (e?.target as HTMLInputElement).value;
    const emittedValue =
      props.inputType === InputType.NUMBER ? Number(value) : value;
    emitter === 'from'
      ? $emits('update:valueFrom', emittedValue)
      : $emits('update:valueTo', emittedValue);
  }
};
</script>

<style scoped lang="scss">
.field-between {
  &__separator {
    margin-left: 10px;
    margin-right: 10px;
  }

  .input-wrapper {
    display: unset;
    margin-left: 0;
    position: relative;
    padding: 0.2em 1em;
  }
}
</style>
