package com.bonus.common.core.utils;

import java.security.SecureRandom;

/**
 * 验证码生成实用类。
 * 提供生成数字、字母和字母数字混合的验证码的功能。
 * @author bonus
 */
public class VerificationCodeUtils {
    // 安全的随机数生成器，用于生成随机验证码
    private static final SecureRandom SECURE_RANDOM = new SecureRandom();
    // 验证码的默认长度
    private static final int CODE_LENGTH = 6;
    // 数字字符集
    private static final String NUMERIC_CHARACTERS = "0123456789";
    // 字母字符集，包括大写和小写字母
    private static final String ALPHABETIC_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    // 字母和数字混合的字符集
    private static final String ALPHANUMERIC_CHARACTERS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

    /**
     * 验证码类型枚举类。
     * NUMERIC - 数字验证码
     * ALPHABETIC - 字母验证码
     * ALPHANUMERIC - 字母和数字混合验证码
     */
    public enum CodeType {
        NUMERIC, ALPHABETIC, ALPHANUMERIC
    }

    /**
     * 生成一个安全的随机验证码。
     *
     * @param codeType 验证码类型 (NUMERIC, ALPHABETIC, ALPHANUMERIC)
     * @return String 生成的验证码
     */
    public static String generateVerificationCode(CodeType codeType) {
        // 用于存储生成的验证码
        StringBuilder verificationCode = new StringBuilder(CODE_LENGTH);
        // 根据验证码类型选择的字符集
        String characters;

        // 根据传入的验证码类型选择相应的字符集
        switch (codeType) {
            case NUMERIC:
                characters = NUMERIC_CHARACTERS;
                break;
            case ALPHABETIC:
                characters = ALPHABETIC_CHARACTERS;
                break;
            case ALPHANUMERIC:
                characters = ALPHANUMERIC_CHARACTERS;
                break;
            default:
                // 如果传入的验证码类型无效，抛出非法参数异常
                throw new IllegalArgumentException("Invalid code type");
        }

        // 生成验证码，长度为CODE_LENGTH
        for (int i = 0; i < CODE_LENGTH; i++) {
            // 随机选择字符集中的一个字符并添加到验证码字符串中
            int index = SECURE_RANDOM.nextInt(characters.length());
            verificationCode.append(characters.charAt(index));
        }

        // 返回生成的验证码字符串
        return verificationCode.toString();
    }
}
