<script setup>
// Wraps PrimeVue InputNumber; optional label/required/error like BaseInputText.
import { computed, ref } from "vue";
import InputNumber from "primevue/inputnumber";

const props = defineProps({
  label: { type: String, default: "" },
  modelValue: { type: Number, default: null },
  min: { type: Number, default: null },
  max: { type: Number, default: null },
  step: { type: Number, default: 1 },
  placeholder: { type: String, default: "" },
  disabled: { type: Boolean, default: false },
  readonly: { type: Boolean, default: false },
  invalid: { type: Boolean, default: false },
  error: { type: String, default: "" },
  required: { type: Boolean, default: false },
  showButtons: { type: Boolean, default: false },
  useGrouping: { type: Boolean, default: true },
  id: { type: String, default: undefined },
  class: { type: [String, Object, Array], default: "w-full" },
});

const emit = defineEmits(["update:modelValue", "blur", "focus", "change"]);

const fallbackId = ref(
  `base-inputnumber-${Math.random().toString(36).slice(2, 11)}`,
);
const inputId = computed(() => props.id ?? fallbackId.value);
const invalidState = computed(() => props.invalid || !!props.error);
const errorId = computed(() => `${inputId.value}-error`);
</script>

<template>
  <div class="flex flex-col" :class="props['class']">
    <div v-if="label" class="flex flex-col mb-2">
      <label
        :for="inputId"
        class="block text-surface-950 dark:text-surface-0 text-md font-medium leading-7"
      >
        {{ label
        }}<span v-if="required" class="text-red-500" aria-hidden="true">
          *</span
        >
      </label>
    </div>
    <InputNumber
      :input-id="inputId"
      :model-value="modelValue"
      :min="min"
      :max="max"
      :step="step"
      :placeholder="placeholder"
      :disabled="disabled"
      :readonly="readonly"
      :invalid="invalidState"
      :aria-invalid="invalidState"
      :aria-describedby="error ? errorId : undefined"
      :show-buttons="showButtons"
      :use-grouping="useGrouping"
      v-bind="$attrs"
      @update:model-value="emit('update:modelValue', $event)"
      @blur="emit('blur', $event)"
      @focus="emit('focus', $event)"
      @change="emit('change', $event)"
    />
    <small v-if="error" :id="errorId" class="text-red-500 mt-1" role="alert">{{
      error
    }}</small>
  </div>
</template>
