<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"
      readonly
      clearable
      append-inner-icon="mdi-calendar-outline"
      @click:clear="clearDate"
      @click:append-inner="showDialog = true"
    />
  </v-col>
  <v-dialog v-model="showDialog" persistent width="830">
    <v-card flat rounded="xl">
      <v-card-text class="d-flex align-center pa-6" style="gap: 2rem;">
        <v-date-picker title="Data inicial" v-model="model.initialDate" />
        <v-date-picker title="Data final" v-model="model.finalDate" />
      </v-card-text>
      <v-card-actions class="pa-4">
        <span v-if="isError" class="error-dates">
          {{ invalidDateMessage }}
        </span>
        <v-spacer></v-spacer>

        <v-btn variant="text" color="primary" @click="cancelar">
          Cancelar
        </v-btn>
        <v-btn variant="text" color="primary" @click="confirmDates"> OK </v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>

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

import moment from "moment";

interface ValueProps {
  initialDate: String;
  finalDate: String;
}

const textField = ref(null);
const showDialog = ref(false);

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

const props = defineProps({
  name: {
    type: String,
    requird: true
  },
  label: {
    type: String,
    required: true
  },
  modelValue: {
    type: [Date, Object],
    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 isError = ref(false);
const invalidDateMessage = ref("");

const model = ref({
  initialDate: "" as any,
  finalDate: "" as any
});

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<ValueProps>(
  fieldName,
  validationRules,
  {}
);

onMounted(() => {
  value.value = {
    initialDate: "",
    finalDate: ""
  };
});

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

  value.value = {
    initialDate: "",
    finalDate: ""
  };
};

const cancelar = () => {
  model.value = {
    initialDate: "",
    finalDate: ""
  };

  value.value = model.value;

  showDialog.value = false;
};

const confirmDates = () => {
  if (moment(model.value.finalDate).isBefore(model.value.initialDate)) {
    invalidDateMessage.value =
      "Data inicial não pode ser superior a data final!";
    isError.value = true;
    return;
  } else if (!model.value.initialDate || !model.value.finalDate) {
    invalidDateMessage.value = "Deve ser selecionando um intervalo de datas!";
    isError.value = true;
    return;
  } else if (
    !moment(String(value.value.initialDate)).isValid() &&
    !moment(String(value.value.finalDate)).isValid()
  ) {
    invalidDateMessage.value = "Intervalo de dados invádlido";
    isError.value = true;
  }

  value.value = model.value;
  emit("update:modelValue", value.value);
  showDialog.value = false;

  const formated = `${moment(String(model.value.initialDate)).format(
    "DD/MM/yyyy"
  )} ate ${moment(String(model.value.finalDate)).format("DD/MM/yyyy")}`;

  formatedDate.value = formated;

  invalidDateMessage.value = "";
  isError.value = false;
};
</script>

<style scoped>
.error-dates {
  font-size: 1.2rem;
  font-weight: 500;
  color: #f44336;
}
</style>
