<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="formattedValue"
      :label="label"
      :error-messages="errorMessage"
      :name="name"
      @keypress="onKeyPress"
      @blur="onBlur"
      :rules="rules"
      autocomplete="section-blue one-time-code"
      maxLength="18"
    />
  </v-col>
</template>

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

const textField = ref(null);

const props = defineProps({
  name: {
    type: String,
    requird: true
  },
  label: {
    type: String,
    required: true
  },
  modelValue: {
    type: String || Number || null,
    required: true
  },
  modelNumber: {
    type: Number,
    default: 0
  },
  xs: { type: String, default: "14" },
  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
  },
  clearOnEmpty: {
    type: Boolean,
    default: false
  }
});

const onKeyPress = (event: any) => {
  if (event.key < "0" || event.key > "9") {
    event.preventDefault();
  }
};

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

const rules = computed(() => {
  return [
    (value: string) => value.length > 17 || "O CNPJ deve conter 14 dígitos"
  ];
});

const formattedValue = computed({
  get: () => {
    return formatCNPJ(props.modelValue);
  },
  set: newValue => {
    const cleanedValue = newValue.replace(/\D/g, "");
    emit("update:modelValue", cleanedValue);
  }
});

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;
          }

          if (!isValidCNPJ(val)) {
            return "CNPJ inválido";
          }

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

const { value, handleBlur, errorMessage, setValue } = useField(
  fieldName,
  validationRules,
  {
    // initialValue?: MaybeRef<TValue>;
    // validateOnValueUpdate: boolean;
    // validateOnMount?: boolean;
    // bails?: boolean;
    // type?: InputType;
    // /**
    //  * @deprecated Use `checkedValue` instead.
    //  */
    // valueProp?: MaybeRef<TValue>;
    // checkedValue?: MaybeRef<TValue>;
    // uncheckedValue?: MaybeRef<TValue>;
    // label?: MaybeRef<string | undefined>;
    // controlled?: boolean;
    // /**
    //  * @deprecated Use `controlled` instead, controlled is opposite of standalone.
    //  */
    // standalone?: boolean;
    // keepValueOnUnmount?: MaybeRef<boolean | undefined>;
    // /**
    //  * @deprecated Pass the model prop name to `syncVModel` instead.
    //  */
    // modelPropName?: string;
    syncVModel: true
    // form?: FormContext;
  }
);

const onBlur = function(evt?: Event, shouldValidate = false) {
  if (
    props.clearOnEmpty &&
    props.modelValue != null &&
    props.modelValue != undefined &&
    props.modelValue.trim() == ""
  ) {
    setValue(undefined);
  }

  handleBlur(evt);
};
</script>
