<template>
  <v-col
    :cols="xs"
    :sm="sm || xs"
    :md="md || sm || xs"
    :lg="lg || md || sm || xs"
    :xl="xl || lg || md || sm || xs"
    :xxl="xxl || xl || lg || md || sm || xs"
    :class="$attrs.class + ' px-2'"
  >
    <v-text-field
      ref="textField"
      v-model="formatedDate"
      :label="label"
      clearable
      append-inner-icon="mdi-calendar-outline"
      @click:clear="clearDate"
      @update:model-value="handleDateDigit"
      maxlength="10"
    >
      <v-menu
        transition="slide-x-transition"
        activator="parent"
        :close-on-content-click="true"
        location="bottom end"
      >
        <v-locale-provider locale="pt-br">
          <v-date-picker
            title=""
            v-model="value"
            locale="pt-br"
            elevation="24"
            hide-actions
          />
        </v-locale-provider>
      </v-menu>
    </v-text-field>
  </v-col>
</template>

<script lang="ts" setup>
import { MaybeRef, computed, ref, watch } from "vue";
import { useField } from "vee-validate";
import { toTypedSchema } from "@vee-validate/zod";
import * as zod from "zod";

import moment from "moment";

const textField = ref(null);

const emit = defineEmits(["update:modelValue"]);

const props = defineProps({
  name: {
    type: String,
    requird: true
  },
  label: {
    type: String,
    required: true
  },
  modelValue: {
    type: [Date, String],
    required: true
  },
  modelModifiers: { default: () => ({}) },
  xs: { type: String, default: "12" },
  sm: { type: String },
  md: { type: String },
  lg: { type: String },
  xl: { type: String },
  xxl: { type: String },
  clearOnEmpty: {
    type: Boolean,
    default: false
  },
  required: {
    type: Boolean,
    default: false
  },
  min: {
    type: Number,
    default: 0
  }
});

const formatedDate = ref("");
const menu = ref(false);
const fieldName = computed<MaybeRef>(() => {
  return props.name;
});

const validationRules = computed<MaybeRef>(() => {
  if (!props.required) {
    return undefined;
  }

  return toTypedSchema(
    zod
      .string()
      .nonempty("Campo não pode ser vazio!")
      .refine(
        val => {
          if (props.min > 0) {
            return val.length >= props.min;
          }

          return true;
        },
        {
          message: `Campo deve ter no mínimo ${props.min} caracteres!`
        }
      )
  );
});

//https://github.com/logaretm/vee-validate/blob/main/packages/vee-validate/src/useField.ts
const { value, handleBlur, errorMessage, setValue } = useField(
  fieldName,
  validationRules,
  {}
);

watch(value, newValue => {
  if (newValue) {
    const formated = moment(String(newValue)).format("DD/MM/yyyy");
    formatedDate.value = formated;
  } else {
    formatedDate.value = "";
  }

  if (moment(String(value.value)).isValid()) {
    emit("update:modelValue", moment(String(value.value)).toDate());
  } else {
    emit("update:modelValue", undefined);
  }
});

const clearDate = () => {
  emit("update:modelValue", undefined);

  value.value = undefined;
};

const handleDateDigit = () => {
  if (formatedDate.value.length === 10) {
    const date = new Date(formatedDate.value);

    if (moment(date).isValid()) {
      emit("update:modelValue", date);
    }
  }
};
</script>
