package net.halfbinary.scavengerhuntapi.service import net.halfbinary.scavengerhuntapi.model.HuntId import net.halfbinary.scavengerhuntapi.model.PhotoStatus import net.halfbinary.scavengerhuntapi.model.domain.HunterLeaderboardEntry import net.halfbinary.scavengerhuntapi.model.domain.TeamLeaderboardEntry import net.halfbinary.scavengerhuntapi.repository.ItemRepository import net.halfbinary.scavengerhuntapi.repository.PhotoRepository import org.springframework.stereotype.Service @Service class StatsService( private val photoRepository: PhotoRepository, private val itemRepository: ItemRepository, private val teamService: TeamService, private val hunterService: HunterService ) { fun getTeamLeaderboard(huntId: HuntId): List { val approvedPhotos = photoRepository.findByHuntIdAndStatus(huntId, PhotoStatus.APPROVED) val itemPoints = itemRepository.findAllByHuntId(huntId).associate { it.id to it.points } val teams = teamService.getListOfTeamsForHunt(huntId) val sortedScores = teams.map { team -> val teamHunterIds = teamService.getHunterIdsForTeam(team.id) val score = approvedPhotos .filter { it.hunterId in teamHunterIds } .distinctBy { it.itemId } .sumOf { itemPoints[it.itemId] ?: 0 } team to score }.sortedByDescending { (_, score) -> score } var rank = 1 return sortedScores.mapIndexed { index, (team, score) -> if (index > 0 && sortedScores[index - 1].second != score) rank = index + 1 TeamLeaderboardEntry(rank = rank, teamName = team.name, score = score) } } fun getHunterLeaderboard(huntId: HuntId): List { val approvedPhotos = photoRepository.findByHuntIdAndStatus(huntId, PhotoStatus.APPROVED) val itemPoints = itemRepository.findAllByHuntId(huntId).associate { it.id to it.points } val sortedScores = approvedPhotos .groupBy { it.hunterId } .map { (hunterId, photos) -> val score = photos.distinctBy { it.itemId }.sumOf { itemPoints[it.itemId] ?: 0 } hunterId to score } .sortedByDescending { (_, score) -> score } var rank = 1 return sortedScores.mapIndexed { index, (hunterId, score) -> if (index > 0 && sortedScores[index - 1].second != score) rank = index + 1 val hunter = hunterService.getHunterById(hunterId) HunterLeaderboardEntry(rank = rank, hunterName = hunter.name, score = score) } } }