/**
 * 动态字段验证器
 * 根据字段配置进行表单验证
 */

import type { FieldConfig, ValidationResult, FormData } from '@/types/form'

/**
 * 验证单个字段
 * @param value 字段值
 * @param field 字段配置
 * @param allFormData 所有表单数据（用于自定义验证）
 * @returns 验证结果
 */
export function validateField(
  value: any,
  field: FieldConfig,
  allFormData: FormData = {}
): ValidationResult {
  const errors: string[] = []

  // 1. 必填验证
  if (field.required) {
    if (value === undefined || value === null || value === '') {
      errors.push(`${field.label}不能为空`)
      return { isValid: false, errors }
    }
  }

  // 如果值为空且非必填，则跳过后续验证
  if (!field.required && (value === undefined || value === null || value === '')) {
    return { isValid: true, errors: [] }
  }

  // 2. 根据字段类型进行验证
  switch (field.fieldType) {
    case 'text':
    case 'textarea':
      validateText(value, field, errors)
      break
    case 'number':
      validateNumber(value, field, errors)
      break
    case 'email':
      validateEmail(value, field, errors)
      break
    case 'phone':
      validatePhone(value, field, errors)
      break
    case 'url':
      validateUrl(value, field, errors)
      break
    case 'select':
    case 'multiselect':
    case 'boolean':
    case 'date':
    case 'tree':
      // 这些类型一般不需要额外验证
      break
  }

  // 3. 自定义正则验证
  if (field.validationRules?.pattern && value) {
    try {
      const regex = new RegExp(field.validationRules.pattern)
      if (!regex.test(value)) {
        errors.push(field.validationRules.customMessage || `${field.label}格式不正确`)
      }
    } catch (error) {
      console.error('正则表达式验证失败:', error)
    }
  }

  // 4. 自定义验证函数
  if (field.validationRules?.custom) {
    try {
      const result = field.validationRules.custom(value, allFormData)
      if (result !== true) {
        errors.push(typeof result === 'string' ? result : `${field.label}验证失败`)
      }
    } catch (error) {
      console.error('自定义验证失败:', error)
      errors.push(`${field.label}验证出错`)
    }
  }

  return {
    isValid: errors.length === 0,
    errors
  }
}

/**
 * 验证所有字段
 * @param data 表单数据
 * @param fields 字段配置列表
 * @returns 字段级错误信息
 */
export function validateFields(
  data: FormData,
  fields: FieldConfig[]
): Record<string, string[]> {
  const errors: Record<string, string[]> = {}

  fields.forEach((field) => {
    const value = data[field.name]
    const result = validateField(value, field, data)

    if (!result.isValid) {
      errors[field.name] = result.errors
    }
  })

  return errors
}

/**
 * 文本类型验证
 */
function validateText(value: any, field: FieldConfig, errors: string[]): void {
  if (typeof value !== 'string') {
    errors.push(`${field.label}必须是文本`)
    return
  }

  const { min, max } = field.validationRules || {}

  if (min && value.length < min) {
    errors.push(`${field.label}长度不能少于${min}个字符`)
  }

  if (max && value.length > max) {
    errors.push(`${field.label}长度不能超过${max}个字符`)
  }
}

/**
 * 数字类型验证
 */
function validateNumber(value: any, field: FieldConfig, errors: string[]): void {
  const num = Number(value)

  if (isNaN(num)) {
    errors.push(`${field.label}必须是数字`)
    return
  }

  const { min, max } = field.validationRules || {}

  if (min !== undefined && num < min) {
    errors.push(`${field.label}不能小于${min}`)
  }

  if (max !== undefined && num > max) {
    errors.push(`${field.label}不能大于${max}`)
  }
}

/**
 * 邮箱验证
 */
function validateEmail(value: any, field: FieldConfig, errors: string[]): void {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
  if (!emailRegex.test(value)) {
    errors.push(`${field.label}邮箱格式不正确`)
  }
}

/**
 * 手机号验证
 */
function validatePhone(value: any, field: FieldConfig, errors: string[]): void {
  // 中国大陆手机号验证
  const phoneRegex = /^1[3-9]\d{9}$/
  if (!phoneRegex.test(value)) {
    errors.push(`${field.label}手机号格式不正确`)
  }
}

/**
 * URL验证
 */
function validateUrl(value: any, field: FieldConfig, errors: string[]): void {
  try {
    new URL(value)
  } catch {
    errors.push(`${field.label}URL格式不正确`)
  }
}

/**
 * 创建VeeValidate验证规则
 * @param field 字段配置
 * @returns VeeValidate规则对象
 */
export function createValidationRule(field: FieldConfig): any {
  const rules: any = {}

  // 必填规则
  if (field.required) {
    rules.required = true
  }

  // 根据字段类型添加规则
  switch (field.fieldType) {
    case 'text':
    case 'textarea':
      if (field.validationRules?.min) {
        rules.min = field.validationRules.min
      }
      if (field.validationRules?.max) {
        rules.max = field.validationRules.max
      }
      if (field.validationRules?.pattern) {
        rules.regex = new RegExp(field.validationRules.pattern)
      }
      break

    case 'number':
      if (field.validationRules?.min !== undefined) {
        rules.min_value = field.validationRules.min
      }
      if (field.validationRules?.max !== undefined) {
        rules.max_value = field.validationRules.max
      }
      break

    case 'email':
      rules.email = true
      break

    case 'phone':
      rules.regex = /^1[3-9]\d{9}$/
      break

    case 'url':
      rules.url = true
      break
  }

  return rules
}

/**
 * 获取字段错误消息
 * @param field 字段配置
 * @param errorType 错误类型
 * @returns 错误消息
 */
export function getFieldErrorMessage(field: FieldConfig, errorType: string): string {
  const messages: Record<string, string> = {
    required: `${field.label}不能为空`,
    min: `${field.label}长度/值不能小于${field.validationRules?.min}`,
    max: `${field.label}长度/值不能大于${field.validationRules?.max}`,
    email: `${field.label}邮箱格式不正确`,
    url: `${field.label}URL格式不正确`,
    regex: `${field.label}格式不正确`
  }

  return messages[errorType] || `${field.label}验证失败`
}
