/**
 * 邀请码生成纯函数（audit-P2-3 新增）
 *
 * 纯函数，不依赖任何外部状态，便于单元测试。
 * 生成格式：8 位大写字母 + 数字组合（去除易混淆字符 I/O/0/1）。
 */

import { randomBytes } from "node:crypto"

/** 安全字符集（去除 I/O/0/1 易混淆字符） */
const SAFE_ALPHABET = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"

/** 邀请码长度 */
const CODE_LENGTH = 8

/**
 * 生成单个邀请码
 *
 * 使用 node:crypto.randomBytes 作为随机源，避免 Math.random() 的伪随机性。
 */
export function generateInvitationCode(): string {
  const bytes = randomBytes(CODE_LENGTH)
  let code = ""
  for (let i = 0; i < CODE_LENGTH; i++) {
    code += SAFE_ALPHABET[bytes[i] % SAFE_ALPHABET.length]
  }
  return code
}

/**
 * 批量生成唯一邀请码
 *
 * 内部使用 Set 去重，确保返回的 codes 数组中无重复。
 * 若因随机冲突无法生成足够唯一码（极端罕见），最多重试 3 次。
 */
export function generateUniqueInvitationCodes(count: number): string[] {
  if (count < 1 || count > 1000) {
    throw new Error(`count must be between 1 and 1000, got ${count}`)
  }

  const codes = new Set<string>()
  const maxAttempts = count * 3

  for (let attempt = 0; attempt < maxAttempts && codes.size < count; attempt++) {
    codes.add(generateInvitationCode())
  }

  if (codes.size < count) {
    throw new Error(
      `Failed to generate ${count} unique invitation codes after ${maxAttempts} attempts (only ${codes.size} unique)`,
    )
  }

  return Array.from(codes)
}

/**
 * 生成批次 ID（同一批生成的邀请码共享同一 batchId，便于追踪）
 *
 * 格式：`batch_<timestamp>_<random6>`
 */
export function generateBatchId(): string {
  const timestamp = Date.now().toString(36)
  const random = randomBytes(3).toString("hex")
  return `batch_${timestamp}_${random}`
}
