package net.halfbinary.scavengerhuntapi.service import net.halfbinary.scavengerhuntapi.error.exception.NotFoundException import net.halfbinary.scavengerhuntapi.model.HuntId import net.halfbinary.scavengerhuntapi.model.HunterId import net.halfbinary.scavengerhuntapi.model.converter.toDomain import net.halfbinary.scavengerhuntapi.model.converter.toRecord import net.halfbinary.scavengerhuntapi.model.domain.Hunt import net.halfbinary.scavengerhuntapi.model.domain.HuntItem import net.halfbinary.scavengerhuntapi.model.domain.Item import net.halfbinary.scavengerhuntapi.model.request.HuntStatus import net.halfbinary.scavengerhuntapi.repository.HuntItemRepository import net.halfbinary.scavengerhuntapi.repository.HuntRepository import net.halfbinary.scavengerhuntapi.repository.ItemRepository import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service import java.time.LocalDateTime @Service class HuntService( private val huntRepository: HuntRepository, private val itemRepository: ItemRepository, private val huntItemRepository: HuntItemRepository ) { fun getHunt(huntId: HuntId): Hunt { return huntRepository.findByIdOrNull(huntId)?.toDomain() ?: throw NotFoundException("No hunt with id $huntId found") } fun getAllHunts(status: HuntStatus?): List { return when(status) { HuntStatus.UNSTARTED -> huntRepository.findAllUnstarted().map { it.toDomain() } HuntStatus.ONGOING -> huntRepository.findAllOngoing().map { it.toDomain() } HuntStatus.CLOSED -> huntRepository.findAllClosed().map { it.toDomain() } else -> huntRepository.findAll().map { it.toDomain() } } } fun getHuntsByHunter(hunterId: HunterId): List { return huntRepository.findAllOngoingByHunter(hunterId).map { it.toDomain() } } fun getHuntsByEmail(email: String, status: HuntStatus?): List { val allHunts = huntRepository.findHuntsByEmail(email) val filteredHunts = when (status) { HuntStatus.ONGOING -> { allHunts .filter { !it.isTerminated && it.startDateTime < LocalDateTime.now() && it.endDateTime > LocalDateTime.now() } .toList() } HuntStatus.CLOSED -> { allHunts .filter { it.isTerminated || it.endDateTime < LocalDateTime.now() } } HuntStatus.UNSTARTED -> { allHunts .filter { !it.isTerminated && it.startDateTime > LocalDateTime.now() } } else -> { allHunts } } return filteredHunts.map { it.toDomain() } } fun createHunt(hunt: Hunt): Hunt { return huntRepository.save(hunt.toRecord()).toDomain() } fun getItemsForHunt(huntId: HuntId): List { huntRepository.findByIdOrNull(huntId) ?: throw NotFoundException("No hunt with id $huntId found") return itemRepository.findAllByHuntId(huntId).map { it.toDomain() } } fun addItemToHunt(huntId: HuntId, item: Item): Item { huntRepository.findByIdOrNull(huntId) ?: throw NotFoundException("No hunt with id $huntId found") val savedItem = itemRepository.save(item.toRecord()).toDomain() huntItemRepository.save(HuntItem(huntId = huntId, itemId = savedItem.id).toRecord()) return savedItem } }