<template>
    <div class="mac-address-input" :class="{ disabled: disabled }">
        <el-input
            ref="inputRef"
            placeholder="请输入设备mac地址"
            v-model="macValue"
            type="text"
            maxlength="17"
            :disabled="disabled"
            @input="handleInput"
            @keydown="handleKeydown"
            @focus="handleFocus"
            @blur="handleBlur"
            @paste="handlePaste"
        />
    </div>
</template>

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

interface Props {
    modelValue?: string
    disabled?: boolean
}

interface Emits {
    (e: 'update:modelValue', value: string): void
}

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

const emit = defineEmits<Emits>()

// 创建单个输入框的引用
const inputRef = ref<InstanceType<typeof import('element-plus').ElInput> | null>(null)

// MAC地址值
const macValue = ref<string>('')

// 解析传入的MAC地址
const parseMacAddress = (mac: string): string => {
    if (!mac) return ''

    // 移除非十六进制字符并转为大写
    const cleanMac = mac.replace(/[^0-9a-fA-F]/g, '').toUpperCase()

    // 按每2个字符分割并用冒号连接
    let result = ''
    for (let i = 0; i < cleanMac.length; i += 2) {
        if (i > 0) result += ':'
        result += cleanMac.substr(i, 2)
    }
    return result.substring(0, 17) // 最多17个字符 (12个数字+5个冒号)
}

// 格式化MAC地址 - 改进版
const formatMac = (value: string): string => {
    // 移除所有冒号
    const cleanValue = value.replace(/:/g, '')
    // 只保留十六进制字符并转为大写
    const hexOnly = cleanValue.replace(/[^0-9a-fA-F]/g, '').toUpperCase()

    // 按每两个字符添加冒号，最多6段
    let formatted = ''
    for (let i = 0; i < Math.min(hexOnly.length, 12); i += 2) {
        if (i > 0) formatted += ':'
        formatted += hexOnly.substr(i, 2)
    }

    return formatted
}

// 当前聚焦的输入框索引
const focusedIndex = ref<number | null>(null)

// 处理输入事件
const handleInput = (value: string) => {
    const formatted = formatMac(value)
    macValue.value = formatted
    // 发出不带冒号的纯净值
    emit('update:modelValue', formatted.replace(/:/g, ''))
}

// 处理键盘事件
const handleKeydown = (event: KeyboardEvent) => {
    const target = event.target as HTMLInputElement

    // 处理退格键
    if (event.key === 'Backspace') {
        // 处理在冒号前删除的情况
        const cursorPos = target.selectionStart || 0
        if (cursorPos > 0 && macValue.value[cursorPos - 1] === ':' && target.selectionStart === target.selectionEnd) {
            event.preventDefault()
            // 删除冒号前的两个字符
            const newValue = macValue.value.substring(0, cursorPos - 3) + macValue.value.substring(cursorPos)
            macValue.value = newValue
            // 设置光标位置
            setTimeout(() => {
                if (target.setSelectionRange) {
                    target.setSelectionRange(cursorPos - 3, cursorPos - 3)
                }
            }, 0)
            emit('update:modelValue', newValue.replace(/:/g, ''))
        }
    }
}

// 处理焦点事件
const handleFocus = () => {
    focusedIndex.value = 0
}

// 处理失焦事件
const handleBlur = () => {
    focusedIndex.value = null
}

// 处理粘贴事件
const handlePaste = (event: ClipboardEvent) => {
    event.preventDefault()
    const pastedText = event.clipboardData?.getData('text') || ''

    // 清理粘贴的文本
    const cleanPastedText = pastedText.replace(/[^0-9a-fA-F]/g, '').toUpperCase()
    const formatted = formatMac(cleanPastedText)
    macValue.value = formatted
    emit('update:modelValue', formatted.replace(/:/g, ''))
}

// 监听modelValue变化
watch(
    () => props.modelValue,
    newVal => {
        const cleanNewVal = (newVal || '').replace(/[^0-9a-fA-F]/g, '').toUpperCase()
        const currentCleanValue = macValue.value.replace(/:/g, '')

        if (cleanNewVal !== currentCleanValue) {
            macValue.value = parseMacAddress(cleanNewVal)
        }
    },
    { immediate: true }
)
</script>

<style scoped lang="scss">
.mac-address-input {
    width: 100%;

    &.disabled {
        opacity: 0.7;
    }

    :deep(.el-input__wrapper) {
        input {
            text-transform: uppercase;
            font-family: inherit; // 使用继承的字体而不是等宽字体
        }
    }
}
</style>
