<template>
  <div class="secure-input" :class="{ 'has-error': error }">
    <label v-if="label" class="secure-input__label" :for="inputId">
      {{ label }}
      <span v-if="required" class="secure-input__required">*</span>
    </label>
    
    <div class="secure-input__wrapper">
      <input
        :id="inputId"
        ref="inputRef"
        v-model="inputValue"
        :type="showPassword ? 'text' : type"
        :placeholder="placeholder"
        :disabled="disabled"
        :readonly="readonly"
        :maxlength="maxLength"
        :autocomplete="autocomplete"
        :class="inputClasses"
        @input="handleInput"
        @blur="handleBlur"
        @focus="handleFocus"
        @keyup.enter="handleEnter"
      />
      
      <button
        v-if="type === 'password' && showToggle"
        type="button"
        class="secure-input__toggle"
        @click="togglePasswordVisibility"
        :aria-label="showPassword ? '隐藏密码' : '显示密码'"
      >
        <el-icon v-if="showPassword"><Hide /></el-icon>
        <el-icon v-else><View /></el-icon>
      </button>
      
      <button
        v-if="clearable && inputValue && !disabled && !readonly"
        type="button"
        class="secure-input__clear"
        @click="clearInput"
        aria-label="清除输入"
      >
        <el-icon><Close /></el-icon>
      </button>
      
      <div v-if="strengthIndicator && type === 'password'" class="secure-input__strength">
        <div class="secure-input__strength-bar">
          <div 
            class="secure-input__strength-fill" 
            :class="passwordStrengthClass"
            :style="{ width: `${passwordStrengthPercentage}%` }"
          ></div>
        </div>
        <span class="secure-input__strength-text">{{ passwordStrengthText }}</span>
      </div>
    </div>
    
    <div v-if="error" class="secure-input__error">{{ error }}</div>
    <div v-else-if="hint" class="secure-input__hint">{{ hint }}</div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, nextTick } from 'vue'
import { View, Hide, Close } from '@element-plus/icons-vue'
import { validatePassword, sanitizeInput } from '@/utils/security'
import { ElMessage } from 'element-plus'

const props = defineProps({
  modelValue: {
    type: [String, Number],
    default: ''
  },
  type: {
    type: String,
    default: 'text',
    validator: (value) => ['text', 'password', 'email', 'tel', 'url', 'number'].includes(value)
  },
  label: {
    type: String,
    default: ''
  },
  placeholder: {
    type: String,
    default: ''
  },
  required: {
    type: Boolean,
    default: false
  },
  disabled: {
    type: Boolean,
    default: false
  },
  readonly: {
    type: Boolean,
    default: false
  },
  clearable: {
    type: Boolean,
    default: false
  },
  showToggle: {
    type: Boolean,
    default: true
  },
  strengthIndicator: {
    type: Boolean,
    default: false
  },
  maxLength: {
    type: Number,
    default: 255
  },
  autocomplete: {
    type: String,
    default: 'off'
  },
  validateOnBlur: {
    type: Boolean,
    default: true
  },
  sanitize: {
    type: Boolean,
    default: true
  },
  error: {
    type: String,
    default: ''
  },
  hint: {
    type: String,
    default: ''
  },
  size: {
    type: String,
    default: 'default',
    validator: (value) => ['small', 'default', 'large'].includes(value)
  }
})

const emit = defineEmits(['update:modelValue', 'input', 'blur', 'focus', 'enter', 'clear', 'strength-change'])

const inputRef = ref(null)
const inputValue = ref(props.modelValue)
const showPassword = ref(false)
const isFocused = ref(false)
const passwordStrength = ref(0)

// 生成唯一ID
const inputId = computed(() => `secure-input-${Math.random().toString(36).substring(2, 9)}`)

// 计算输入框样式类
const inputClasses = computed(() => {
  return [
    'secure-input__field',
    `secure-input__field--${props.size}`,
    {
      'secure-input__field--focused': isFocused.value,
      'secure-input__field--disabled': props.disabled,
      'secure-input__field--readonly': props.readonly,
      'secure-input__field--has-error': props.error,
      'secure-input__field--password': props.type === 'password'
    }
  ]
})

// 计算密码强度类
const passwordStrengthClass = computed(() => {
  if (passwordStrength.value <= 2) return 'weak'
  if (passwordStrength.value <= 3) return 'medium'
  return 'strong'
})

// 计算密码强度百分比
const passwordStrengthPercentage = computed(() => {
  return Math.min(passwordStrength.value * 20, 100)
})

// 计算密码强度文本
const passwordStrengthText = computed(() => {
  if (passwordStrength.value <= 2) return '弱'
  if (passwordStrength.value <= 3) return '中等'
  return '强'
})

// 监听modelValue变化
watch(() => props.modelValue, (newVal) => {
  inputValue.value = newVal
})

// 监听输入值变化
watch(inputValue, (newVal) => {
  // 如果启用了输入清理，则清理输入
  const processedValue = props.sanitize ? sanitizeInput(newVal) : newVal
  
  // 更新密码强度（仅当类型为password时）
  if (props.type === 'password' && props.strengthIndicator) {
    updatePasswordStrength(processedValue)
  }
  
  // 触发更新事件
  emit('update:modelValue', processedValue)
  emit('input', processedValue)
})

// 更新密码强度
const updatePasswordStrength = (password) => {
  if (!password) {
    passwordStrength.value = 0
    return
  }
  
  try {
    const result = validatePassword(password)
    passwordStrength.value = result.score
    emit('strength-change', result)
  } catch (error) {
    console.error('密码强度验证失败:', error)
    passwordStrength.value = 0
  }
}

// 处理输入事件
const handleInput = (event) => {
  // 输入事件已在watch中处理
}

// 处理焦点事件
const handleFocus = (event) => {
  isFocused.value = true
  emit('focus', event)
}

// 处理失焦事件
const handleBlur = (event) => {
  isFocused.value = false
  emit('blur', event)
}

// 处理回车事件
const handleEnter = (event) => {
  emit('enter', event)
}

// 切换密码可见性
const togglePasswordVisibility = () => {
  showPassword.value = !showPassword.value
}

// 清除输入
const clearInput = () => {
  inputValue.value = ''
  emit('clear')
  nextTick(() => {
    inputRef.value?.focus()
  })
}

// 聚焦输入框
const focus = () => {
  inputRef.value?.focus()
}

// 失焦输入框
const blur = () => {
  inputRef.value?.blur()
}

// 选择文本
const select = () => {
  inputRef.value?.select()
}

// 暴露方法
defineExpose({
  focus,
  blur,
  select,
  inputRef
})

onMounted(() => {
  // 初始化密码强度
  if (props.type === 'password' && props.strengthIndicator && inputValue.value) {
    updatePasswordStrength(inputValue.value)
  }
})
</script>

<style scoped>
.secure-input {
  width: 100%;
  margin-bottom: 16px;
}

.secure-input__label {
  display: block;
  margin-bottom: 8px;
  font-weight: 500;
  color: #333;
}

.secure-input__required {
  color: #f56c6c;
  margin-left: 4px;
}

.secure-input__wrapper {
  position: relative;
  width: 100%;
}

.secure-input__field {
  width: 100%;
  padding: 12px 16px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  font-size: 14px;
  color: #606266;
  background-color: #fff;
  transition: border-color 0.2s;
  outline: none;
  box-sizing: border-box;
}

.secure-input__field:focus {
  border-color: #409eff;
}

.secure-input__field--small {
  padding: 8px 12px;
  font-size: 12px;
}

.secure-input__field--large {
  padding: 16px 20px;
  font-size: 16px;
}

.secure-input__field--disabled {
  background-color: #f5f7fa;
  color: #c0c4cc;
  cursor: not-allowed;
}

.secure-input__field--readonly {
  background-color: #f5f7fa;
  color: #606266;
  cursor: default;
}

.secure-input__field--has-error {
  border-color: #f56c6c;
}

.secure-input__field--password {
  padding-right: 80px;
}

.secure-input__toggle,
.secure-input__clear {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  cursor: pointer;
  color: #909399;
  font-size: 16px;
  padding: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.2s;
}

.secure-input__toggle:hover,
.secure-input__clear:hover {
  color: #409eff;
}

.secure-input__toggle {
  right: 12px;
}

.secure-input__clear {
  right: 40px;
}

.secure-input__strength {
  margin-top: 8px;
}

.secure-input__strength-bar {
  height: 4px;
  background-color: #e4e7ed;
  border-radius: 2px;
  overflow: hidden;
}

.secure-input__strength-fill {
  height: 100%;
  transition: width 0.3s, background-color 0.3s;
}

.secure-input__strength-fill.weak {
  background-color: #f56c6c;
}

.secure-input__strength-fill.medium {
  background-color: #e6a23c;
}

.secure-input__strength-fill.strong {
  background-color: #67c23a;
}

.secure-input__strength-text {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
  display: block;
}

.secure-input__error {
  color: #f56c6c;
  font-size: 12px;
  margin-top: 4px;
}

.secure-input__hint {
  color: #909399;
  font-size: 12px;
  margin-top: 4px;
}

.secure-input.has-error .secure-input__field {
  border-color: #f56c6c;
}
</style>