<script>
import theme from "#build/b24ui/input-number";
</script>

<script setup>
import { onMounted, computed, useTemplateRef, toRef } from "vue";
import { NumberFieldRoot, NumberFieldInput, NumberFieldDecrement, NumberFieldIncrement, useForwardPropsEmits } from "reka-ui";
import { reactivePick, useVModel } from "@vueuse/core";
import { useAppConfig } from "#imports";
import { useFieldGroup } from "../composables/useFieldGroup";
import { useFormField } from "../composables/useFormField";
import { useLocale } from "../composables/useLocale";
import { tv } from "../utils/tv";
import icons from "../dictionary/icons";
import B24Badge from "./Badge.vue";
import B24Button from "./Button.vue";
defineOptions({ inheritAttrs: false });
const props = defineProps({
  as: { type: null, required: false },
  placeholder: { type: String, required: false },
  color: { type: null, required: false, default: "air-primary" },
  size: { type: null, required: false },
  noBorder: { type: Boolean, required: false },
  underline: { type: Boolean, required: false },
  rounded: { type: Boolean, required: false },
  tag: { type: String, required: false },
  tagColor: { type: null, required: false },
  highlight: { type: Boolean, required: false },
  orientation: { type: String, required: false, default: "horizontal" },
  increment: { type: [Boolean, Object], required: false, default: true },
  incrementIcon: { type: [Function, Object], required: false },
  incrementDisabled: { type: Boolean, required: false },
  decrement: { type: [Boolean, Object], required: false, default: true },
  decrementIcon: { type: [Function, Object], required: false },
  decrementDisabled: { type: Boolean, required: false },
  autofocus: { type: Boolean, required: false },
  autofocusDelay: { type: Number, required: false },
  modelModifiers: { type: Object, required: false },
  class: { type: null, required: false },
  b24ui: { type: null, required: false },
  modelValue: { type: [Number, null], required: false },
  defaultValue: { type: Number, required: false },
  min: { type: Number, required: false },
  max: { type: Number, required: false },
  step: { type: Number, required: false },
  stepSnapping: { type: Boolean, required: false },
  disabled: { type: Boolean, required: false },
  required: { type: Boolean, required: false },
  id: { type: String, required: false },
  name: { type: String, required: false },
  formatOptions: { type: null, required: false },
  disableWheelChange: { type: Boolean, required: false },
  invertWheelChange: { type: Boolean, required: false },
  readonly: { type: Boolean, required: false }
});
const emits = defineEmits(["update:modelValue", "blur", "change"]);
defineSlots();
const modelValue = useVModel(props, "modelValue", emits, { defaultValue: props.defaultValue });
const { t } = useLocale();
const appConfig = useAppConfig();
const rootProps = useForwardPropsEmits(reactivePick(props, "as", "defaultValue", "min", "max", "step", "stepSnapping", "formatOptions", "disableWheelChange", "invertWheelChange", "readonly"), emits);
const { emitFormBlur, emitFormFocus, emitFormChange, emitFormInput, id, color, size: formGroupSize, name, highlight, disabled, ariaAttrs } = useFormField(props);
const { orientation, size: fieldGroupSize } = useFieldGroup(props);
const inputSize = computed(() => fieldGroupSize.value || formGroupSize.value);
const isTag = computed(() => {
  return props.tag;
});
const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.inputNumber || {} })({
  color: color.value,
  size: inputSize?.value,
  highlight: highlight.value,
  rounded: Boolean(props.rounded),
  noBorder: Boolean(props.noBorder),
  underline: Boolean(props.underline),
  orientation: props.orientation,
  fieldGroup: orientation.value,
  increment: props.orientation === "vertical" ? !!props.increment || !!props.decrement : !!props.increment,
  decrement: props.orientation === "vertical" ? false : !!props.decrement
}));
const incrementIcon = computed(() => props.incrementIcon || (props.orientation === "horizontal" ? icons.plus : icons.chevronUp));
const decrementIcon = computed(() => props.decrementIcon || (props.orientation === "horizontal" ? icons.minus : icons.chevronDown));
const inputRef = useTemplateRef("inputRef");
function onUpdate(value) {
  if (props.modelModifiers?.optional) {
    value = value ?? void 0;
  }
  const event = new Event("change", { target: { value } });
  emits("change", event);
  emitFormChange();
  emitFormInput();
}
function onBlur(event) {
  emitFormBlur();
  emits("blur", event);
}
function autoFocus() {
  if (props.autofocus) {
    inputRef.value?.$el?.focus();
  }
}
onMounted(() => {
  setTimeout(() => {
    autoFocus();
  }, props.autofocusDelay);
});
defineExpose({
  inputRef: toRef(() => inputRef.value?.$el)
});
</script>

<template>
  <NumberFieldRoot
    v-bind="rootProps"
    :id="id"
    :model-value="modelValue"
    data-slot="root"
    :class="b24ui.root({ class: [props.b24ui?.root, props.class] })"
    :name="name"
    :disabled="disabled"
    @update:model-value="onUpdate"
  >
    <B24Badge
      v-if="isTag"
      data-slot="tag"
      :class="b24ui.tag({ class: props.b24ui?.tag })"
      :color="props.tagColor"
      :label="props.tag"
      size="xs"
    />

    <NumberFieldInput
      v-bind="{ ...$attrs, ...ariaAttrs }"
      ref="inputRef"
      :placeholder="placeholder"
      :required="required"
      data-slot="base"
      :class="b24ui.base({ class: props.b24ui?.base })"
      @blur="onBlur"
      @focus="emitFormFocus"
    />

    <div v-if="!!increment" data-slot="increment" :class="b24ui.increment({ class: props.b24ui?.increment })">
      <NumberFieldIncrement as-child :disabled="disabled || incrementDisabled">
        <slot name="increment">
          <B24Button
            :icon="incrementIcon"
            color="air-tertiary-no-accent"
            :size="size"
            :aria-label="t('inputNumber.increment')"
            v-bind="typeof increment === 'object' ? increment : void 0"
          />
        </slot>
      </NumberFieldIncrement>
    </div>

    <div v-if="!!decrement" data-slot="decrement" :class="b24ui.decrement({ class: props.b24ui?.decrement })">
      <NumberFieldDecrement as-child :disabled="disabled || decrementDisabled">
        <slot name="decrement">
          <B24Button
            :icon="decrementIcon"
            color="air-tertiary-no-accent"
            :size="size"
            :aria-label="t('inputNumber.decrement')"
            v-bind="typeof decrement === 'object' ? decrement : void 0"
          />
        </slot>
      </NumberFieldDecrement>
    </div>
  </NumberFieldRoot>
</template>
