<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-select
      ref="selectField"
      v-model="value"
      :items="[...listStateCode, ...props.items]"
      :label="label"
      :error-messages="errorMessage"
      :name="name"
      :return-object="returnObject"
      autocomplete="section-blue one-time-code"
    >
      <template v-slot:prepend-item>
        <slot name="prepend"></slot>
      </template>
      <template v-slot:append-item>
        <slot name="append"></slot>
      </template>
    </v-select>
  </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 { PropType } from "nuxt/dist/app/compat/capi";
import { getStates } from "@brazilian-utils/brazilian-utils";

const selectField = ref(null);

const listStateCode = computed(() => {
  const statesCode = getStates();
  return statesCode.map(stateCode => stateCode.code);
});

const props = defineProps({
  name: {
    type: String,
    requird: true
  },
  label: {
    type: String,
    required: true
  },
  items: {
    type: Array,
    default: () => []
  },
  itemTitle: {
    type: String,
    default: ""
  },
  itemValue: {
    type: String || Number,
    default: ""
  },
  modelValue: {
    type: [String, Object, Number],
    required: true
  },
  xs: { type: String, default: "12" },
  sm: { type: String },
  md: { type: String },
  lg: { type: String },
  xl: { type: String },
  xxl: { type: String },
  required: {
    type: Boolean,
    default: false
  },
  min: {
    type: Number,
    default: 0
  },
  returnObject: {
    type: Boolean,
    default: false
  }
});

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

const fieldName = computed<MaybeRef>(() => {
  return props.name;
});

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

  if (props.returnObject) {
    return toTypedSchema(
      zod.object({
        [props.itemTitle]: zod.string().refine(
          val => {
            if (props.min > 0) {
              return val.length >= props.min;
            }

            return true;
          },
          {
            message: `Campo deve ter no mínimo ${props.min} caracteres!`
          }
        ),
        [props.itemValue]: zod.string().refine(
          val => {
            if (props.min > 0) {
              return val.length >= props.min;
            }

            return true;
          },
          {
            message: `Campo deve ter no mínimo ${props.min} caracteres!`
          }
        )
      })
    );
  } else {
    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!`
          }
        )
    );
  }
});

const { value, handleBlur, errorMessage, setValue, resetField } = useField<
  String | Object | Number
>(fieldName, validationRules);

watch(value, newValue => {
  switch (typeof newValue) {
    case "object":
      emit("update:modelValue", newValue);
      break;
    case "number":
      emit("update:modelValue", newValue);
      break;
    case "string":
      emit("update:modelValue", newValue);
      break;
  }
});
</script>
