<template>
  <div class="column" :class="attrs.class" :style="attrs.style">
    <div class="col">
      <q-input
        ref="inputRef"
        v-model="model"
        v-bind="inputAttrs"
        hide-bottom-space
        :bg-color="bgColor"
        :class="inputClass"
        :color
        :error="!!error || !!errorMessageProp"
        :error-message="errorMessage"
        :input-class="nativeInputClass"
        :label
        :label-color
        :rules
        :outlined
        @update:model-value="error = null"
      >
        <template v-for="(_, slotName) in $slots" #[slotName]>
          <slot :name="slotName" />
        </template>

        <template #append>
          <slot name="append">
            <q-icon v-if="icon" :name="icon" size="sm" color="secondary" />
          </slot>
        </template>
      </q-input>
    </div>
  </div>
</template>

<script setup>
import {
  computed,
  onBeforeMount,
  ref,
  useAttrs,
  useTemplateRef,
  watch,
} from "vue";

defineOptions({
  inheritAttrs: false,
});

const { bgColor, errorMessage: errorMessageProp, icon, inputClass, label, labelColor, nativeInputClass, rules, outlined } =
  defineProps({
    bgColor: {
      type: String,
      default: "white",
    },
    color: {
      type: String,
      default: "secondary",
    },
    errorMessage: {
      type: String,
      default: null,
    },
    icon: {
      type: String,
      default: "",
    },
    inputClass: {
      type: String,
      default: null,
    },
    label: {
      type: String,
      default: "",
    },
    labelColor: {
      type: String,
      default: "secondary",
    },
    nativeInputClass: {
      type: String,
      default: null,
    },
    outlined: {
      type: Boolean,
      default: true,
    },
    rules: {
      type: Array,
      default: () => [],
    },
  });

const attrs = useAttrs();

const inputRef = useTemplateRef("inputRef");

const model = defineModel({ type: [String, Object, Array, Boolean, null] });

const error = defineModel("error", {
  type: [String, Object, Array, Boolean, null],
});

const required = ref(false);

const inputAttrs = computed(() => {
  // eslint-disable-next-line
  const { class: _, style: __, ...rest } = attrs;
  return rest;
});

const errorMessage = computed(() => {
  if (errorMessageProp != null) {
    return errorMessageProp;
  }

  if (error.value == null) {
    return void 0;
  }

  if (typeof error.value === "boolean") {
    return void 0;
  }

  return String(error.value);
});

watch(
  () => rules,
  (values) => {
    values.forEach((r) => {
      if (r?.$id === "required") return (required.value = true);
    });
  },
);

onBeforeMount(() => {
  rules.forEach((r) => {
    if (r?.$id === "required") return (required.value = true);
  });
});

defineExpose({
  inputRef,
});
</script>

<style scoped lang="scss">
:deep(.q-field--outlined.q-field--rounded .q-field__control) {
  border-radius: 8px;
}
</style>
