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

const hasLabel = computed(() => !!useSlots().label);

const props = defineProps({
  modelValue: [Number, String, Boolean, Array],
  error: {
    type: String,
    default: "",
  },
  required: {
    type: Boolean,
    default: false,
  },
  id: {
    type: String,
    default: () => Math.random().toString(20).substr(2, 10),
  },
  name: {
    type: String,
    default: "",
  },
  label: {
    type: String,
    default: "",
  },
  valueKey: {
    type: String,
    default: "value",
  },
  textKey: {
    type: [String, Function],
    default: "text",
  },
  options: {
    type: [Array, Object],
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  dense: {
    type: Boolean,
    default: false,
  },
  help: {
    type: String,
    default: "",
  },
  background: {
    type: String,
    default: "",
  },
});
const emit = defineEmits(["update:modelValue"]);
const componentValue = computed({
  get() {
    return props.modelValue;
  },
  set(value) {
    emit("update:modelValue", value);
  },
});
</script>

<template>
  <div class="flex flex-col gap-2">
    <template v-if="label || hasLabel">
      <label
        :for="id"
        :class="`${
          disabled ? 'text-gray-200' : 'text-gray-900'
        } block text-sm font-medium dark:text-white`"
        ><slot v-if="!label" name="label" />
        <template v-else
          >{{ label }}
          <span v-if="required" class="text-red-600"> *</span></template
        >
      </label>
    </template>
    <select
      :id="id"
      v-model="componentValue"
      :class="`${
        dense ? '!p-1' : '!p-2.5'
      } ${background ? background : '!bg-gray-50'} !border !border-gray-300 !text-gray-900 !text-sm !rounded-lg focus:ring-primary-500 focus:border-primary-500 block min-w-full dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500`"
      :required="required"
      :disabled="disabled"
      :name="name"
      :value="modelValue"
    >
      <option
        v-for="option in options"
        :key="option[valueKey]"
        :value="option[valueKey]"
        v-text="typeof textKey === 'string' ? option[textKey] : textKey(option)"
      />
    </select>
    <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">
      {{ error }}
    </div>
  </div>
</template>
