<template>
  <div
    :class="[
      'ivyforms-field',
      'ivyforms-quantity-field',
      'ivyforms-quantity-field--field-' + field.id,
      field.cssClasses,
      { 'is-readonly': field.readOnly },
    ]"
  >
    <IvyFormItem
      :label="field.hideLabel ? '' : field.label"
      :required="field.required"
      :error="error"
      :prop="field.type + '_' + field.fieldIndex"
      :show-info="!!field.description"
      :info-text="field.description || ''"
      :show-info-icon="false"
      :label-position="field.labelPosition"
    >
      <div
        class="ivyforms-quantity-field__control ivyforms-flex ivyforms-align-items-center ivyforms-gap-8 ivyforms-width-100"
      >
        <span
          v-if="field.inputPrefix"
          class="ivyforms-quantity-field__prefix regular-16 text-primary ivyforms-flex-shrink-0"
          >{{ field.inputPrefix }}</span
        >
        <IvyTextNumberInput
          :id="fieldID"
          v-model="localModelValue"
          class="ivyforms-quantity-field__input ivyforms-flex-grow-1"
          :aria-label="field.label"
          :placeholder="field.placeholder"
          :disabled="disabled"
          :readonly="props.field.readOnly"
          :required="field.required"
          :step="field.step && field.step > 0 ? field.step : 1"
          :min="numericMin"
          :max="numericMax"
        />
        <span
          v-if="field.inputSuffix"
          class="ivyforms-quantity-field__suffix regular-16 text-primary ivyforms-flex-shrink-0"
          >{{ field.inputSuffix }}</span
        >
      </div>
    </IvyFormItem>
  </div>
</template>

<script setup lang="ts">
import { computed, inject } from 'vue'
import IvyTextNumberInput from '@/views/_components/input/IvyTextNumberInput.vue'
import IvyFormItem from '@/views/_components/form/IvyFormItem.vue'

interface Field {
  id: number
  formId: number
  fieldIndex: number
  type: string
  label: string
  placeholder?: string
  required?: boolean
  hideLabel?: boolean
  readOnly?: boolean
  description?: string
  cssClasses?: string
  step?: number
  labelPosition?: string
  inputPrefix?: string
  inputSuffix?: string
  limitRange?: boolean
  minValue?: number | null
  maxValue?: number | null
}

interface FieldProps {
  modelValue: string | number | null | undefined
  field: Field
  disabled?: boolean
  error?: string
}

const props = withDefaults(defineProps<FieldProps>(), {
  modelValue: '',
  disabled: false,
  error: '',
})

const emit = defineEmits(['update:modelValue'])

const clearFieldError = inject<(fieldKey: string) => void>('clearFieldError', () => {})

const fieldKey = computed(() => {
  return props.field.type + '_' + props.field.fieldIndex
})

const numericMin = computed(() => {
  if (!props.field.limitRange) {
    return 0
  }
  const v = props.field.minValue
  if (v === null || v === undefined) {
    return 0
  }
  return v
})

const numericMax = computed(() => {
  if (!props.field.limitRange) {
    return Number.MAX_SAFE_INTEGER
  }
  const v = props.field.maxValue
  if (v === null || v === undefined) {
    return Number.MAX_SAFE_INTEGER
  }
  return v
})

const handleInput = (value: string | number | null | undefined) => {
  emit('update:modelValue', value === undefined || value === null ? '' : value)
  clearFieldError(fieldKey.value)
}

const localModelValue = computed({
  get() {
    const val = props.modelValue
    if (val === '' || val === null || val === undefined || isNaN(Number(val))) return undefined
    return typeof val === 'number' ? val : Number(val)
  },
  set(value) {
    handleInput(value)
  },
})

const fieldID = computed(() => {
  return `ivyforms-quantity-field__input_${props.field.formId || ''}_${props.field.fieldIndex || ''}`
})
</script>

<style scoped lang="scss">
.ivyforms-quantity-field {
  &.is-readonly {
    :deep(.el-input__wrapper),
    :deep(.el-input__wrapper:hover),
    :deep(.el-input__wrapper.is-focus),
    :deep(.el-input__inner) {
      cursor: not-allowed;
      pointer-events: none;
    }
  }
}
</style>
