const { validateUsername, USERNAME_MAX_LENGTH } = require('./usernameValidation') const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') const isUsernameTaken = async (UserModel, userName, excludeUserId) => { const existing = await UserModel.findOne({ user_name: { $regex: new RegExp(`^${escapeRegex(userName)}$`, 'i') } }) if (!existing) return false if (excludeUserId && existing._id.toString() === excludeUserId) return false return true } const buildCandidates = (base, attempt) => { const random2 = () => String(Math.floor(Math.random() * 90 + 10)) const random3 = () => String(Math.floor(Math.random() * 900 + 100)) const random4 = () => String(Math.floor(Math.random() * 9000 + 1000)) const builders = [ (b) => `${b}${random2()}`, (b) => `${b}_${random3()}`, (b) => `${b}.${random2()}`, (b) => `${b}-${random2()}`, (b) => `${b}${random4()}`, (b) => `${b}_m${random2()}`, (b) => `${b}${attempt}`, ] return builders.map((fn) => { let candidate = fn(base) if (candidate.length > USERNAME_MAX_LENGTH) { candidate = candidate.slice(0, USERNAME_MAX_LENGTH) } return candidate }) } const generateUsernameSuggestions = async ( UserModel, baseUsername, excludeUserId, count = 3 ) => { const base = baseUsername.trim().toLowerCase() const suggestions = [] const tried = new Set([base]) for (let attempt = 1; attempt <= 60 && suggestions.length < count; attempt++) { const candidates = buildCandidates(base, attempt) for (const candidate of candidates) { if (suggestions.length >= count) break if (tried.has(candidate)) continue tried.add(candidate) if (validateUsername(candidate)) continue const taken = await isUsernameTaken(UserModel, candidate, excludeUserId) if (!taken) suggestions.push(candidate) } } return suggestions } module.exports = { generateUsernameSuggestions, isUsernameTaken }