<script setup lang="ts">
import { ref, watch, nextTick } from 'vue'

defineOptions({ name: 'ElInputThousandth' })

const props = withDefaults(
  defineProps<{
    modelValue?: number | string
    placeholder?: string
    disabled?: boolean
  }>(),
  {
    modelValue: undefined,
    placeholder: '',
    disabled: false,
  },
)

const emit = defineEmits<{
  'update:modelValue': [value: number | string | undefined]
}>()

const isFocused = ref(false)
const displayValue = ref('')
const inputRef = ref<InstanceType<typeof import('element-plus')['ElInput']>>()

function formatThousandth(val: string | number | undefined): string {
  if (val === undefined || val === null || val === '') return ''
  const str = String(val)
  const num = Number(str)
  if (isNaN(num)) return ''
  const parts = str.split('.')
  const intPart = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',')
  if (parts.length > 1) {
    return intPart + '.' + parts[1]
  }
  return intPart
}

function stripNonNumeric(val: string): string {
  let result = val.replace(/[^\d.]/g, '')
  const dotIndex = result.indexOf('.')
  if (dotIndex !== -1) {
    result = result.slice(0, dotIndex + 1) + result.slice(dotIndex + 1).replace(/\./g, '')
  }
  if (dotIndex !== -1) {
    const parts = result.split('.')
    if (parts[1].length > 2) {
      result = parts[0] + '.' + parts[1].slice(0, 2)
    }
  }
  return result
}

function handleInput(val: string) {
  const cleaned = stripNonNumeric(val)
  displayValue.value = cleaned
  if (cleaned === '' || cleaned === '.') {
    emit('update:modelValue', undefined)
  } else {
    emit('update:modelValue', Number(cleaned))
  }
}

function handleFocus() {
  isFocused.value = true
  const raw = props.modelValue !== undefined && props.modelValue !== null && props.modelValue !== ''
    ? String(props.modelValue)
    : ''
  displayValue.value = raw
}

function handleBlur() {
  isFocused.value = false
  if (props.modelValue !== undefined && props.modelValue !== null && props.modelValue !== '') {
    displayValue.value = formatThousandth(props.modelValue)
  } else {
    displayValue.value = ''
  }
}

watch(
  () => props.modelValue,
  (val) => {
    if (!isFocused.value) {
      displayValue.value = formatThousandth(val)
    }
  },
  { immediate: true },
)
</script>

<template>
  <el-input
    ref="inputRef"
    :model-value="displayValue"
    :placeholder="placeholder"
    :disabled="disabled"
    @input="handleInput"
    @focus="handleFocus"
    @blur="handleBlur"
  />
</template>
