<template>
  <div :style="{ width: item.width ? item.width + 'px' : '100%' }">
    <v-text-field
      v-model.trim="value"
      variant="outlined"
      :density="item.dense || 'compact'"
      :type="inputType"
      :rules="item.rules"
      :disabled="item.disabled"
      :style="{width: item.width}"
      :color="item.color || 'primary'"
      :label="item.label"
      :placeholder="item.placeholder || item.label"
      :autofocus="item.autofocus"
      :required="item.required"
      :class="item.class"
      :suffix="item.suffix"
      :append-icon="item.appendIcon"
      :append-inner-icon="item.appendInnerIcon"
      :clearable="item.clearable"
      :readonly="item.readonly"
      :counter="item.counter"
      :prepend-inner-icon="item.prependInnerIcon"
      hide-spin-buttons
      :hide-details="item.hideDetails || false"
      @wheel="$event => handleWheel($event, item)"
      @update:modelValue="modelValueUpDate"
      @click:append="appendClick"
      @click:append-inner="appendInnerClick"
      @keyup.enter="handleKeyup"
      @click:clear="handleClear"
      @blur="handleBlur"
      @focus="handleFocus"
    >
      <slot name="default"></slot>
    </v-text-field>
  </div>
</template>
<script setup>
import { useI18n } from '@/hooks/web/useI18n'; const { t } = useI18n()
import { debounce } from 'lodash'
import { ref, watch } from 'vue';
defineOptions({ name:'FormUI-v-text-field'})

const props = defineProps({item: Object, modelValue: [String, Number]})
const emit = defineEmits(['update:modelValue', 'change', 'appendClick', 'appendInnerClick', 'enter', 'blur', 'focus'])
const item = props.item
const inputType = ref(item.type === 'phoneNumber' ? 'number' : item.type)

const value = ref('')
if (props.modelValue && typeof props.modelValue === 'string') value.value = props.modelValue.replace(/&amp;/g, '&')

const searchDebouncedTime = item?.searchDebouncedTime === 0 ? ref(0) : ref(500)
if (inputType.value === 'number' && item.integer) searchDebouncedTime.value = 0

const valueDeal = (val) => {
  let dealData = val
  if (inputType.value === 'number') {
    if (item.integer) { // 为true时只能输入整型
      dealData = val.replace(/\D/g,'') - 0
    }
  }
  return dealData
}

watch(() => props.modelValue, (newVal) => {
  const dealData = valueDeal(newVal)
  value.value = dealData ? typeof dealData === 'string' ? dealData.replace(/&amp;/g, '&') : dealData : ''
})

const modelValueUpDate = (val) => {
  value.value = val
  emit('update:modelValue', value.value)
  debouncedCallbackUpDate(value.value) // emit('change', value.value)
}
const debouncedCallbackUpDate = debounce(newValue => {
  emit('change', newValue)
}, searchDebouncedTime.value)

const appendClick = () => {
  if (item.appendClick) item.appendClick()
  emit('appendClick', value.value)
}
const appendInnerClick = () => {
  if (item.password) {
    inputType.value = inputType.value === 'password' ? 'text' : 'password'
    item.appendInnerIcon = inputType.value === 'password' ? 'mdi-eye-off-outline' : 'mdi-eye-outline'
  }
  if (item.appendInnerClick) item.appendInnerClick(value.value)
  else emit('appendInnerClick', value.value)
}

const handleClear = () => {
  emit('enter', value.value)
}

const handleKeyup = () => {
  emit('enter', value.value)
}

const handleBlur = () => {
  emit('blur', props.item, value.value)
}

const handleFocus = () => {
  emit('focus', props.item, value.value)
}

const handleWheel = (event, item) => {
  if (item.type !== 'number') return
  event.preventDefault()
  if (event.deltaY > 0) {
    item.value--
  } else {
    item.value++
  }
}

if (item.type === 'phoneNumber') {
  const phoneRules = [v => !v || v?.length <= 11 && /^1[3456789]\d{9}$/.test(v) || t('login.correctPhoneNumber')]
  item.rules = item.rules ? [ ...phoneRules, ...item.rules] : phoneRules
  item.counter = item.counter ? item.counter : 11
}
</script>
<style lang="scss" scoped>

</style>