<template>
  <div class="column" :class="attrs.class" :style="attrs.style">
    <div class="col">
      <q-input
        ref="inputRef"
        v-model="model"
        v-bind="inputAttrs"
        color="secondary"
        hide-bottom-space
        label-color="secondary"
        lazy-rules="ondemand"
        :bg-color
        :class="[inputClass, { 'required-field': required }]"
        :error="!!error"
        :error-message="normalizedErrorMessage"
        :input-class="nativeInputClass"
        :label
        :outlined
        :rules
        @update:model-value="error = null"
      >
        <template #append>
          <slot name="append">
            <q-icon v-if="icon" color="secondary" size="sm" :name="icon" />
          </slot>
        </template>
      </q-input>
    </div>
  </div>
</template>

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

defineOptions({
  inheritAttrs: false,
});

const {
  bgColor,
  errorMessage,
  icon,
  inputClass,
  label,
  nativeInputClass,
  outlined,
  rules,
} = defineProps({
  bgColor: {
    type: String,
    default: "white",
  },
  errorMessage: {
    type: String,
    default: undefined,
  },
  icon: {
    type: String,
    default: "",
  },
  inputClass: {
    type: String,
    default: null,
  },
  label: {
    type: String,
    default: "",
  },
  nativeInputClass: {
    type: String,
    default: null,
  },
  outlined: {
    type: Boolean,
    default: false,
  },
  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 inputAttrs = computed(() => {
  // eslint-disable-next-line
  const { class: _, style: __, ...rest } = attrs;

  return rest;
});

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

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

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

  return String(error.value);
});

const required = computed(() => rules.some((rule) => rule?.$id === "required"));

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

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

:deep(.required-field .q-field__label::after) {
  color: var(--q-negative);
  content: " *";
}
</style>
