// utils/validators.ts
// 轻量类型声明，避免对特定 UI 库的硬依赖
export interface FormItemRule {
    required?: boolean
    message?: string
    trigger?: 'blur' | 'change'
    pattern?: RegExp
    validator?: (
        rule: FormItemRule,
        value: any,
        callback: (error?: Error) => void,
    ) => void
}
type I18nT = (key: string, ...args: any[]) => string

export const Patterns = {
    // 至少 8-20 位，包含大小写字母、数字、特殊字符中的至少三类
    password: /^(?:(?=.*[a-z])(?=.*[A-Z])(?=.*\d)|(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()_+=-])|(?=.*[a-z])(?=.*\d)(?=.*[!@#$%^&*()_+=-])|(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+=-]))[\w!@#$%^&*()+=-]{8,20}$/,
    email: /^[\w.+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
    idNumber: /^[A-Z0-9]{6,18}$/i,
    mobile: /^\d{6,15}$/,
    postcode: /^[a-z0-9]{1,15}$/i,
    // 允许英文地址常见符号：空格- , . / # '
    address: /^[A-Z0-9\s\-.,/#']+$/i,
    // 允许中文、字母、数字、空格、连字符、常见中文分隔符与中点
    addressCn: /^[\u4E00-\u9FA5A-Z0-9\s\-·，。、《》（）()#]+$/i,
}

// ✅ 通用规则封装
export const Validators = {
    required: (msg: string, trigger: 'blur' | 'change' = 'blur'): FormItemRule => ({
        required: true,
        message: msg,
        trigger,
    }),
    pattern: (regex: RegExp, msg: string, trigger: 'blur' | 'change' = 'blur'): FormItemRule => ({
        pattern: regex,
        message: msg,
        trigger,
    }),
    custom: (
        validator: (rule: FormItemRule, value: any, callback: (error?: Error) => void) => void,
        trigger: 'blur' | 'change' = 'blur',
    ): FormItemRule => ({
        validator,
        trigger,
    }),
}

// ✅ 自定义校验
export function validateAge18(
    rule: FormItemRule,
    value: string,
    callback: (error?: Error) => void,
    t: I18nT,
) {
    if (!value)
        return callback(new Error(t('card.vaildate.v5')))
    const today = new Date()
    const birthDate = new Date(value)
    let age = today.getFullYear() - birthDate.getFullYear()
    const month = today.getMonth() - birthDate.getMonth()
    if (month < 0 || (month === 0 && today.getDate() < birthDate.getDate()))
        age--
    age < 18 ? callback(new Error(t('card.New.n3'))) : callback()
}

export function validateAddress(
    rule: FormItemRule,
    value: string,
    callback: (error?: Error) => void,
    t: I18nT,
) {
    const val = String(value ?? '').trim()
    if (val.length < 2 || val.length > 40 || !Patterns.address.test(val)) {
        callback(new Error(t('card.New.n1')))
    }
    else {
        callback()
    }
}

export function validateName(
    rule: FormItemRule,
    value: string,
    callback: (error?: Error) => void,
) {
    const val = String(value ?? '').trim()
    const regex = /^[A-Z\s'-]+$/i
    if (!val) {
        callback(new Error('Name is required'))
        return
    }
    if (!regex.test(val)) {
        callback(new Error('Invalid name format'))
        return
    }
    if (val.length < 2 || val.length > 23) {
        callback(new Error('Name length must be 2-23 characters'))
        return
    }
    // 连续空格或标点的简单规避
    if (/\s{2,}/.test(val)) {
        callback(new Error('Name contains consecutive spaces'))
        return
    }
    callback()
}

// 复杂密码校验（独立导出，便于在表单中直接复用）
export function validatePassword(
    rule: FormItemRule,
    value: string,
    callback: (error?: Error) => void,
    t?: I18nT,
) {
    const val = String(value ?? '')
    if (!val)
        return callback(new Error(t ? t('vaildate.password.empty') : 'Password is required'))
    if (!Patterns.password.test(val)) {
        return callback(
            new Error(
                t ? t('vaildate.password.format') : 'Password must be 8-20 chars and include 3 of: upper, lower, digit, symbol',
            ),
        )
    }
    callback()
}

export function validatePostcode(
    rule: FormItemRule,
    value: string,
    callback: (error?: Error) => void,
    t?: I18nT,
) {
    const val = String(value ?? '').trim()
    if (!val)
        return callback(new Error(t ? t('card.vaildate.v8') : 'Postcode is required'))
    if (!Patterns.postcode.test(val)) {
        return callback(new Error(t ? t('card.New.n2') : 'Invalid postcode'))
    }
    callback()
}

export function validateAddressCn(
    rule: FormItemRule,
    value: string,
    callback: (error?: Error) => void,
    t?: I18nT,
) {
    const val = String(value ?? '').trim()
    if (!val)
        return callback(new Error(t ? t('card.vaildate.v27') : 'Address is required'))
    if (!Patterns.addressCn.test(val)) {
        return callback(new Error(t ? t('card.vaildate.v27') : 'Invalid address characters'))
    }
    callback()
}
