/**
 * 表单验证工具类
 */

// 验证规则类型
export const VALIDATION_TYPES = {
  REQUIRED: 'required',
  EMAIL: 'email',
  PHONE: 'phone',
  ID_CARD: 'idCard',
  PASSWORD: 'password',
  NUMBER: 'number',
  INTEGER: 'integer',
  DECIMAL: 'decimal',
  MIN_LENGTH: 'minLength',
  MAX_LENGTH: 'maxLength',
  MIN_VALUE: 'minValue',
  MAX_VALUE: 'maxValue',
  PATTERN: 'pattern',
  CUSTOM: 'custom'
}

// 内置验证规则
const BUILT_IN_RULES = {
  // 必填验证
  [VALIDATION_TYPES.REQUIRED]: {
    validator: (value) => {
      if (Array.isArray(value)) {
        return value.length > 0
      }
      return value !== null && value !== undefined && String(value).trim() !== ''
    },
    message: '此字段为必填项'
  },

  // 邮箱验证
  [VALIDATION_TYPES.EMAIL]: {
    validator: (value) => {
      if (!value) return true
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
      return emailRegex.test(value)
    },
    message: '请输入正确的邮箱地址'
  },

  // 手机号验证
  [VALIDATION_TYPES.PHONE]: {
    validator: (value) => {
      if (!value) return true
      const phoneRegex = /^1[3-9]\d{9}$/
      return phoneRegex.test(value)
    },
    message: '请输入正确的手机号码'
  },

  // 身份证验证
  [VALIDATION_TYPES.ID_CARD]: {
    validator: (value) => {
      if (!value) return true
      const idCardRegex = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
      return idCardRegex.test(value)
    },
    message: '请输入正确的身份证号码'
  },

  // 密码验证（至少8位，包含字母和数字）
  [VALIDATION_TYPES.PASSWORD]: {
    validator: (value) => {
      if (!value) return true
      const passwordRegex = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&]{8,}$/
      return passwordRegex.test(value)
    },
    message: '密码至少8位，需包含字母和数字'
  },

  // 数字验证
  [VALIDATION_TYPES.NUMBER]: {
    validator: (value) => {
      if (!value) return true
      return !isNaN(Number(value))
    },
    message: '请输入有效的数字'
  },

  // 整数验证
  [VALIDATION_TYPES.INTEGER]: {
    validator: (value) => {
      if (!value) return true
      return Number.isInteger(Number(value))
    },
    message: '请输入整数'
  },

  // 小数验证
  [VALIDATION_TYPES.DECIMAL]: {
    validator: (value) => {
      if (!value) return true
      const decimalRegex = /^\d+(\.\d+)?$/
      return decimalRegex.test(value)
    },
    message: '请输入有效的小数'
  }
}

/**
 * 验证器类
 */
export class Validator {
  constructor() {
    this.rules = {}
    this.errors = {}
  }

  /**
   * 添加验证规则
   * @param {string} field 字段名
   * @param {Array} rules 验证规则数组
   */
  addRule(field, rules) {
    this.rules[field] = Array.isArray(rules) ? rules : [rules]
    return this
  }

  /**
   * 批量添加验证规则
   * @param {Object} rulesMap 规则映射对象
   */
  addRules(rulesMap) {
    Object.keys(rulesMap).forEach(field => {
      this.addRule(field, rulesMap[field])
    })
    return this
  }

  /**
   * 验证单个字段
   * @param {string} field 字段名
   * @param {any} value 字段值
   * @param {Object} data 完整数据对象
   * @returns {Object} 验证结果
   */
  validateField(field, value, data = {}) {
    const fieldRules = this.rules[field] || []
    const errors = []

    for (const rule of fieldRules) {
      const result = this.executeRule(rule, value, data, field)
      if (!result.valid) {
        errors.push(result.message)
        if (rule.stopOnFirstError !== false) {
          break
        }
      }
    }

    return {
      valid: errors.length === 0,
      errors,
      field
    }
  }

  /**
   * 验证所有字段
   * @param {Object} data 数据对象
   * @returns {Object} 验证结果
   */
  validate(data) {
    const errors = {}
    let isValid = true

    Object.keys(this.rules).forEach(field => {
      const value = this.getFieldValue(data, field)
      const result = this.validateField(field, value, data)
      
      if (!result.valid) {
        errors[field] = result.errors
        isValid = false
      }
    })

    this.errors = errors
    return {
      valid: isValid,
      errors
    }
  }

  /**
   * 执行单个验证规则
   * @param {Object} rule 验证规则
   * @param {any} value 字段值
   * @param {Object} data 完整数据
   * @param {string} field 字段名
   * @returns {Object} 执行结果
   */
  executeRule(rule, value, data, field) {
    let validator, message

    if (typeof rule === 'string') {
      // 字符串规则，使用内置规则
      const builtInRule = BUILT_IN_RULES[rule]
      if (!builtInRule) {
        throw new Error(`未知的验证规则: ${rule}`)
      }
      validator = builtInRule.validator
      message = builtInRule.message
    } else if (typeof rule === 'function') {
      // 函数规则
      validator = rule
      message = '验证失败'
    } else if (typeof rule === 'object') {
      // 对象规则
      if (rule.type && BUILT_IN_RULES[rule.type]) {
        const builtInRule = BUILT_IN_RULES[rule.type]
        validator = this.createParameterizedValidator(rule.type, rule, builtInRule.validator)
        message = rule.message || builtInRule.message
      } else if (rule.validator) {
        validator = rule.validator
        message = rule.message || '验证失败'
      } else {
        throw new Error('无效的验证规则对象')
      }
    } else {
      throw new Error('验证规则必须是字符串、函数或对象')
    }

    try {
      const isValid = validator(value, data, field)
      return {
        valid: isValid,
        message: isValid ? null : message
      }
    } catch (error) {
      return {
        valid: false,
        message: `验证过程中发生错误: ${error.message}`
      }
    }
  }

  /**
   * 创建参数化验证器
   * @param {string} type 验证类型
   * @param {Object} rule 规则对象
   * @param {Function} baseValidator 基础验证器
   * @returns {Function} 参数化验证器
   */
  createParameterizedValidator(type, rule, baseValidator) {
    switch (type) {
      case VALIDATION_TYPES.MIN_LENGTH:
        return (value) => {
          if (!value) return true
          return String(value).length >= rule.min
        }
      
      case VALIDATION_TYPES.MAX_LENGTH:
        return (value) => {
          if (!value) return true
          return String(value).length <= rule.max
        }
      
      case VALIDATION_TYPES.MIN_VALUE:
        return (value) => {
          if (!value) return true
          return Number(value) >= rule.min
        }
      
      case VALIDATION_TYPES.MAX_VALUE:
        return (value) => {
          if (!value) return true
          return Number(value) <= rule.max
        }
      
      case VALIDATION_TYPES.PATTERN:
        return (value) => {
          if (!value) return true
          const regex = rule.pattern instanceof RegExp ? rule.pattern : new RegExp(rule.pattern)
          return regex.test(value)
        }
      
      default:
        return baseValidator
    }
  }

  /**
   * 获取字段值（支持嵌套字段）
   * @param {Object} data 数据对象
   * @param {string} field 字段路径
   * @returns {any} 字段值
   */
  getFieldValue(data, field) {
    if (field.includes('.')) {
      return field.split('.').reduce((obj, key) => obj && obj[key], data)
    }
    return data[field]
  }

  /**
   * 获取字段错误信息
   * @param {string} field 字段名
   * @returns {Array} 错误信息数组
   */
  getFieldErrors(field) {
    return this.errors[field] || []
  }

  /**
   * 获取第一个字段错误信息
   * @param {string} field 字段名
   * @returns {string|null} 错误信息
   */
  getFirstFieldError(field) {
    const errors = this.getFieldErrors(field)
    return errors.length > 0 ? errors[0] : null
  }

  /**
   * 清除验证错误
   * @param {string} field 字段名，不传则清除所有
   */
  clearErrors(field) {
    if (field) {
      delete this.errors[field]
    } else {
      this.errors = {}
    }
  }

  /**
   * 检查是否有错误
   * @param {string} field 字段名，不传则检查所有
   * @returns {boolean} 是否有错误
   */
  hasErrors(field) {
    if (field) {
      return this.getFieldErrors(field).length > 0
    }
    return Object.keys(this.errors).length > 0
  }
}

/**
 * 创建验证器实例
 * @param {Object} rules 验证规则
 * @returns {Validator} 验证器实例
 */
export function createValidator(rules = {}) {
  const validator = new Validator()
  validator.addRules(rules)
  return validator
}

/**
 * 快速验证函数
 * @param {Object} data 数据对象
 * @param {Object} rules 验证规则
 * @returns {Object} 验证结果
 */
export function validate(data, rules) {
  const validator = createValidator(rules)
  return validator.validate(data)
}

/**
 * 常用验证规则预设
 */
export const COMMON_RULES = {
  // 用户名规则
  username: [
    VALIDATION_TYPES.REQUIRED,
    { type: VALIDATION_TYPES.MIN_LENGTH, min: 3, message: '用户名至少3个字符' },
    { type: VALIDATION_TYPES.MAX_LENGTH, max: 20, message: '用户名最多20个字符' },
    { type: VALIDATION_TYPES.PATTERN, pattern: /^[a-zA-Z0-9_]+$/, message: '用户名只能包含字母、数字和下划线' }
  ],

  // 邮箱规则
  email: [
    VALIDATION_TYPES.REQUIRED,
    VALIDATION_TYPES.EMAIL
  ],

  // 手机号规则
  phone: [
    VALIDATION_TYPES.REQUIRED,
    VALIDATION_TYPES.PHONE
  ],

  // 密码规则
  password: [
    VALIDATION_TYPES.REQUIRED,
    VALIDATION_TYPES.PASSWORD
  ],

  // 确认密码规则
  confirmPassword: [
    VALIDATION_TYPES.REQUIRED,
    {
      validator: (value, data) => value === data.password,
      message: '两次输入的密码不一致'
    }
  ],

  // 身份证规则
  idCard: [
    VALIDATION_TYPES.REQUIRED,
    VALIDATION_TYPES.ID_CARD
  ],

  // 姓名规则
  name: [
    VALIDATION_TYPES.REQUIRED,
    { type: VALIDATION_TYPES.MIN_LENGTH, min: 2, message: '姓名至少2个字符' },
    { type: VALIDATION_TYPES.MAX_LENGTH, max: 20, message: '姓名最多20个字符' },
    { type: VALIDATION_TYPES.PATTERN, pattern: /^[\u4e00-\u9fa5a-zA-Z\s]+$/, message: '姓名只能包含中文、英文和空格' }
  ],

  // 年龄规则
  age: [
    VALIDATION_TYPES.REQUIRED,
    VALIDATION_TYPES.INTEGER,
    { type: VALIDATION_TYPES.MIN_VALUE, min: 1, message: '年龄必须大于0' },
    { type: VALIDATION_TYPES.MAX_VALUE, max: 150, message: '年龄不能超过150' }
  ],

  // 金额规则
  amount: [
    VALIDATION_TYPES.REQUIRED,
    VALIDATION_TYPES.DECIMAL,
    { type: VALIDATION_TYPES.MIN_VALUE, min: 0, message: '金额不能为负数' }
  ],

  // 验证码规则
  verifyCode: [
    VALIDATION_TYPES.REQUIRED,
    { type: VALIDATION_TYPES.PATTERN, pattern: /^\d{4,6}$/, message: '验证码为4-6位数字' }
  ]
}

/**
 * 自定义验证器示例
 */
export const CUSTOM_VALIDATORS = {
  // 银行卡号验证
  bankCard: {
    validator: (value) => {
      if (!value) return true
      // Luhn算法验证银行卡号
      const digits = value.replace(/\D/g, '')
      if (digits.length < 13 || digits.length > 19) return false
      
      let sum = 0
      let isEven = false
      
      for (let i = digits.length - 1; i >= 0; i--) {
        let digit = parseInt(digits[i])
        
        if (isEven) {
          digit *= 2
          if (digit > 9) {
            digit -= 9
          }
        }
        
        sum += digit
        isEven = !isEven
      }
      
      return sum % 10 === 0
    },
    message: '请输入正确的银行卡号'
  },

  // 统一社会信用代码验证
  socialCreditCode: {
    validator: (value) => {
      if (!value) return true
      const regex = /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/
      return regex.test(value)
    },
    message: '请输入正确的统一社会信用代码'
  },

  // 车牌号验证
  licensePlate: {
    validator: (value) => {
      if (!value) return true
      const regex = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-Z0-9]{4}[A-Z0-9挂学警港澳]$/
      return regex.test(value)
    },
    message: '请输入正确的车牌号'
  }
}

// 导出默认验证器实例
export default new Validator()