<script setup>
import { computed, ref } from "vue";
const props = defineProps({
  modelValue: {
    type: [Number, String, Boolean, Array],
    required: false,
  },
  error: {
    type: String,
    default: "",
  },
  required: {
    type: Boolean,
    default: false,
  },
  id: {
    type: String,
    default: () => Math.random().toString(20).substr(2, 10),
  },
  name: {
    type: String,
    default: "",
  },
  ariaDescribedby: {
    type: String,
    default: "",
  },
  type: {
    type: String,
    default: "text",
  },
  placeholder: {
    type: String,
    default: "",
  },
  autofocus: {
    type: Boolean,
    default: false,
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  autocomplete: {
    type: [String, Boolean],
    default: false,
  },
  value: {
    type: [Number, String, Boolean, Array],
    default: "",
  },
  label: {
    type: String,
    default: "",
  },
  icon: {
    type: String,
    required: false,
  },
  pattern: {
    type: String,
    required: false,
  },
  help: {
    type: String,
    default: "",
  },
  readonly: {
    type: Boolean,
    default: false,
  },
  dense: {
    type: Boolean,
    default: false,
  },
  min: {
    type: [Number, String],
    required: false,
  },
  max: {
    type: [Number, String],
    required: false,
  },
});
const emit = defineEmits(["update:modelValue", "keyup"]);
const componentValue = computed({
  get() {
    return props.modelValue;
  },
  set(value) {
    emit("update:modelValue", value);
  },
});
const focus = ref(false);
</script>

<template>
  <div class="flex flex-col gap-2">
    <label
      :for="id"
      :class="`${
        disabled ? 'text-gray-400' : 'text-gray-900'
      } text-sm font-medium dark:text-white ${label ? 'block' : 'hidden'}`"
      ><slot v-if="!label" name="label" />
      <template v-else
        >{{ label }}
        <span v-if="required" class="text-red-600"> *</span></template
      >
    </label>
    <div
      :class="`flex border rounded-lg transition-colors duration-200 ${
        focus
          ? 'border-primary-500 bg-white dark:border-primary-400 dark:bg-gray-700'
          : 'border-gray-300 bg-gray-100 dark:border-gray-600 dark:bg-gray-800'
      }`"
    >
      <div v-if="icon" :class="`flex items-center border-0 rounded-l-lg`">
        <component
          :is="`${icon}-icon`"
          v-if="icon"
          class="size-5 transition duration-75 ml-3 text-gray-500 dark:text-gray-400"
        />
      </div>
      <slot v-if="!icon" name="icon" />
      <input
        :id="id"
        v-model="componentValue"
        :class="`${dense ? 'text-sm' : 'text-base'} block w-full !min-h-0 !ring-0 !leading-1 !border-0 !rounded-lg transition-colors duration-200 text-gray-900 bg-gray-50 placeholder-gray-500 dark:bg-transparent dark:text-white dark:placeholder-gray-400 ${type === 'file' ? '!p-0 cursor-pointer' : dense ? '!py-1 !px-2' : '!p-2.5'}`"
        :required="required"
        :type="type"
        :placeholder="placeholder"
        :autofocus="autofocus"
        :autocomplete="autocomplete"
        :aria-describedby="ariaDescribedby"
        :name="name ? name : id"
        :disabled="disabled"
        :value="modelValue"
        :pattern="pattern"
        :readonly="readonly"
        :min="min"
        :max="max"
        @keyup="emit('keyup', $event)"
        @focusin="focus = true"
        @focusout="focus = false"
      />
    </div>
    <div v-if="help" class="text-xs text-gray-500 dark:text-gray-400">
      {{ help }}
    </div>
    <div v-show="error" class="text-sm text-red-600 flex flex-col gap-1">
      <template v-if="error instanceof Array">
        <span v-for="e in error" :key="e"> {{ e }}</span>
      </template>
      <template v-else>
        {{ error }}
      </template>
    </div>
  </div>
</template>
