const { DefaultError } = require("../errors/errors") const banRepo = require("../repositories/banRepo") const badgeRepo = require("../repositories/badgeRepository") const userBadgeRepo = require("../repositories/userBadgeRepository") async function banUser(userId, message, expiresAt) { const existingBan = await banRepo.isBanned(userId) if (existingBan) { throw new DefaultError(409, "Already has an active ban.", "Duplicate active ban.") } return await banRepo.banUser(userId, message, expiresAt) } async function unbanUser(banId) { const existingBan = await banRepo.isBanned(userId) if (!existingBan) { throw new DefaultError(404, "No active ban.", "No active ban found.") } return await banRepo.unbanUser(banId) } async function isUserBanned(userId) { const ban = await banRepo.isBanned(userId) if (!ban) { return false } if (new Date(ban.expiresAt) <= new Date()) { await banRepo.deactivate(ban.id) return false } return true } async function createBadge({ name, description, icon, condition }) { const existing = await badgeRepo.findAllBadges() if (existing.some(b => b.name === name)) { throw new DefaultError(409, "Badge already exists", "Duplicate badge name") } return await badgeRepo.createBadge(name, description, icon, condition) } async function getAllBadges() { return await badgeRepo.findAllBadges() } async function getBadgeById({ badgeId }) { const badge = await badgeRepo.findBadgeById(badgeId) if (!badge) { throw new DefaultError(404, "Badge not found", "Badge ID does not exist") } return badge } async function updateBadge({ badgeId, updateData }) { const badge = await badgeRepo.findBadgeById(badgeId) if (!badge) { throw new DefaultError(404, "Badge not found", "Badge ID does not exist") } const allowedFields = ["name", "description", "icon", "condition"] const filteredData = Object.keys(updateData) .filter(key => allowedFields.includes(key)) .reduce((obj, key) => { obj[key] = updateData[key] return obj }, {}) if (Object.keys(filteredData).length === 0) { throw new DefaultError(400, "No valid fields to update", "Invalid update data") } return await badgeRepo.updateBadge(badgeId, filteredData) } async function deleteBadge({ badgeId }) { const badge = await badgeRepo.findBadgeById(badgeId) if (!badge) { throw new DefaultError(404, "Badge not found", "Badge ID does not exist") } return await badgeRepo.deleteBadge(badgeId) } async function assignBadgeToUser({ userId, badgeId }) { const badge = await badgeRepo.findBadgeById(badgeId) if (!badge) { throw new DefaultError(404, "Badge not found", "Badge ID does not exist") } const hasAlready = await userBadgeRepo.hasBadge(userId, badgeId) if (hasAlready) { throw new DefaultError(409, "User already has this badge", "Duplicate badge assignment") } return await userBadgeRepo.assignBadgeToUser(userId, badgeId) } async function removeBadgeFromUser({ userId, badgeId }) { const badge = await badgeRepo.findBadgeById(badgeId) if (!badge) { throw new DefaultError(404, "Badge not found", "Badge ID does not exist") } const success = await userBadgeRepo.removeBadgeFromUser(userId, badgeId) if (!success) { throw new DefaultError(404, "Badge not assigned to user", "User does not have this badge") } return success } module.exports = { banUser, unbanUser, isUserBanned, createBadge, getAllBadges, getBadgeById, updateBadge, deleteBadge, assignBadgeToUser, removeBadgeFromUser }