<template>
  <div class="verification-code-input">
          <input
            v-for="(code, index) in verificationCode"
            :key="index"
            type="text"
            :value="verificationCode[index]"
            ref="inputRefs"
            inputmode="numeric"
            pattern="[0-9]*"
            :disabled="loading"
            @input="(e) => onCodeInput(e, index)"
            @paste="(e) => onCodePaste(e, index)"
            @keydown="(e) => onCodeKeydown(e, index)"
            @keypress="(e) => onCodeKeypress(e)"
            @focus="onCodeFocus"
            class="code-input"
          />
  </div>
</template>

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

interface Props {
  loading?: boolean
}

interface Emits {
  (e: 'complete', code: string): void
  (e: 'change', code: string): void
}

const props = withDefaults(defineProps<Props>(), {
  loading: false
})

const emit = defineEmits<Emits>()

// 验证码输入相关
const verificationCode = ref(['', '', '', '', '', ''])
const inputRefs = ref<HTMLInputElement[]>([])

// 验证码输入相关方法
const onCodeInput = (e: Event, index: number) => {
  const input = e.target as HTMLInputElement
  const val = input.value
  const cleanVal = String(val).replace(/\D/g, '')

  // 检查是否已经输入了5位数字（不包括当前正在输入的第6位）
  const filledCount = verificationCode.value.filter(v => v !== '').length
  const isAlmostComplete = filledCount >= 5

  // 如果已经输入了5位数字，检查当前输入是否会导致超过6位
  if (isAlmostComplete && cleanVal.length === 1 && verificationCode.value[index] === '') {
    // 如果当前输入框是空的，说明这是第6位输入，允许
    // 如果当前输入框有值，说明是替换，不允许
    // 这里我们允许输入，但会在设置后检查
  }

  // 只处理单个字符输入，粘贴由 paste 事件处理
  if (cleanVal.length === 1) {
    verificationCode.value[index] = cleanVal

    // 自动跳转到下一个输入框（只有在还没到第6个时）
    if (index < 5) {
      nextTick(() => {
        inputRefs.value[index + 1]?.focus()
      })
    }

    // 发出变化事件
    const finalCode = verificationCode.value.join('')
    emit('change', finalCode)

    // 如果完成了6位，发出完成事件
    if (finalCode.length === 6) {
      emit('complete', finalCode)
    }
  } else if (cleanVal.length === 0) {
    // 处理删除
    verificationCode.value[index] = ''
    emit('change', verificationCode.value.join(''))
  }
  // 如果是多个字符，可能是粘贴，由 paste 事件处理，这里不做处理
}

const onCodePaste = (e: ClipboardEvent, index: number) => {
  e.preventDefault()

  // 检查是否已经输入了6位数字
  const currentCode = verificationCode.value.join('')
  if (currentCode.length === 6) {
    return // 如果已经完成，不允许粘贴
  }

  const pasteData = (e.clipboardData || (window as any).clipboardData).getData('text')
  const cleanData = pasteData.replace(/\D/g, '') // 只保留数字

  if (cleanData.length === 0) return

  console.log('Paste detected:', cleanData)

  // 从当前输入框开始填充
  for (let i = 0; i < Math.min(cleanData.length, 6 - index); i++) {
    verificationCode.value[index + i] = cleanData[i]
  }

  // 移动焦点到下一个空白输入框
  const nextEmptyIndex = verificationCode.value.findIndex((val, i) => i >= index && val === '')
  if (nextEmptyIndex !== -1) {
    nextTick(() => {
      inputRefs.value[nextEmptyIndex]?.focus()
    })
  } else {
    nextTick(() => {
      inputRefs.value[5]?.focus()
    })
  }

  // 发出完成事件
  emit('complete', verificationCode.value.join(''))
  emit('change', verificationCode.value.join(''))
}

const onCodeKeydown = (e: KeyboardEvent, index: number) => {
  // 处理删除键
  if (e.key === 'Backspace') {
    const input = e.target as HTMLInputElement
    const val = input.value

    if (val === '') {
      // 当前输入框为空，删除上一个输入框的值
      if (index > 0) {
        verificationCode.value[index - 1] = ''
        nextTick(() => {
          inputRefs.value[index - 1]?.focus()
        })
        emit('change', verificationCode.value.join(''))
      }
    } else {
      // 当前输入框有值，清空当前输入框
      verificationCode.value[index] = ''
      emit('change', verificationCode.value.join(''))
    }
  }

  // 阻止其他非数字字符（除了允许的控制键）
  else if (
    e.key &&
    !/[0-9]/.test(e.key) &&
    ![
      'Backspace',
      'Delete',
      'Tab',
      'Enter',
      'ArrowLeft',
      'ArrowRight',
      'ArrowUp',
      'ArrowDown'
    ].includes(e.key)
  ) {
    e.preventDefault()
  }
}

const onCodeKeypress = (e: KeyboardEvent) => {
  // 检查是否已经输入了6位数字
  const currentCode = verificationCode.value.join('')
  if (currentCode.length === 6) {
    e.preventDefault() // 如果已经完成，阻止任何按键输入
    return
  }

  // 只允许输入数字0-9
  const char = String.fromCharCode(e.which || (e as any).keyCode)
  if (!/[0-9]/.test(char)) {
    e.preventDefault()
  }
}

const onCodeFocus = () => {
  // 聚焦到第一个空白输入框
  const index = verificationCode.value.findIndex(item => item === '')
  const focusIndex = index === -1 ? 5 : index
  nextTick(() => {
    inputRefs.value[focusIndex]?.focus()
  })
}

// 暴露给父组件的方法
const reset = () => {
  verificationCode.value = ['', '', '', '', '', '']
  nextTick(() => {
    inputRefs.value[0]?.focus()
  })
}

const getCode = () => {
  return verificationCode.value.join('')
}

defineExpose({
  reset,
  getCode,
  verificationCode
})
</script>

<style scoped lang="less">
.verification-code-input {
  display: flex;
  column-gap: 1.2rem;

  .code-input {
    width: 5rem;
    height: 5rem;
    border: 0.15rem solid #d5d5d5;
    border-radius: 0.8rem;
    text-align: center;
    font-size: 2rem;
    line-height: 5rem;
    outline: none;
    transition: border-color 0.2s;

    &:focus {
      border-color: #232323;
    }

    &:disabled {
      background-color: #f5f5f5;
      color: #999;
    }
  }
}
</style>