<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-checkbox
      v-model="value"
      :label="label"
      :error-messages="errorMessage"
      :name="name"
    />
  </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";

const props = defineProps({
  name: {
    type: String,
    requird: true
  },
  label: {
    type: String,
    required: true
  },
  modelValue: {
    type: [Array, Object, String, Number, Boolean],
    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
  }
});

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

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

  switch (typeof props.modelValue) {
    case "object":
      return toTypedSchema(zod.object({}));
    case "number":
      return toTypedSchema(zod.number());
    case "string":
      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!`
            }
          )
      );
    case "boolean":
      return toTypedSchema(zod.boolean());
  }
});

const { value, handleBlur, errorMessage, setValue, resetField } = useField<
  Array<any> | Object | String | Number | Boolean
>(fieldName, validationRules, {
  syncVModel: true
});

const valueNew = ref<Array<any> | Object | String | Number | Boolean>();

watch(value, newVale => {
  valueNew.value = newVale;
});
</script>
