package fr.teamflash.fencerjudgeback.services

import fr.teamflash.fencerjudgeback.entities.PlayerBean
import fr.teamflash.fencerjudgeback.repositories.PlayerRepository
import fr.teamflash.fencerjudgeback.websocket.controllers.PlayerWebSocketController
import fr.teamflash.fencerjudgeback.websocket.models.PlayerUpdateMessage
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Lazy
import org.springframework.stereotype.Service

@Service
class PlayerService(
    @Autowired private val playerRepository: PlayerRepository,
    @Lazy private val playerWebSocketController: PlayerWebSocketController? = null
) {
    // Obtenir tous les joueurs (public)
    fun getAll(): List<PlayerBean> {
        println("PlayerService.getAll")
        return playerRepository.findAll()
    }

    // Obtenir un joueur par id (public)
    fun getById(id:Long?) : PlayerBean? {
        println("PlayerService.getById : $id")

        if (id == null) {
            return null
        }

        return playerRepository.findById(id).get()
    }

    // Obtenir un ou plusieurs joueur(s) par nom (public)
    fun getByName(name:String): List<PlayerBean?>? {
        println("PlayerService.getByName : $name")
        return playerRepository.findAll().filter{ it.name == name }
    }

    // Obtenir un ou plusieurs joueur(s) par prénom
    fun getByFirstName(firstName:String): List<PlayerBean?>? {
        println("PlayerService.getByFirstName : $firstName")
        return playerRepository.findAll().filter{ it.firstName == firstName }
    }

    // Obtenir un ou plusieurs joueur(s) par club
    fun getByClub(club:String): List<PlayerBean?>? {
        println("PlayerService.getByClub : $club")
        return playerRepository.findAll().filter{ it.club == club }
    }

    // Ajouter un joueur (admin)
    fun createPlayer(player: PlayerBean) : PlayerBean {
        println("PlayerService.createPlayer : $player")
        val savedPlayer = playerRepository.save(player)
        // Broadcast the new player via WebSocket
        playerWebSocketController?.broadcastPlayerUpdate(savedPlayer, PlayerUpdateMessage.UpdateType.PLAYER_CREATE)
        return savedPlayer
    }

    // Modifier un joueur (admin)
    fun updatePlayer(id:Long, newPlayer: PlayerBean) : Int {
        // Vérifier si le joueur existe à l'id renseigné
        if (getById(id) == null) {
            println("PlayerService.updatePlayer : Player not found")
            return -1
        }

        val updatedPlayer = newPlayer.copy(id = id)
        val savedPlayer = playerRepository.save(updatedPlayer)
        // Broadcast the updated player via WebSocket
        playerWebSocketController?.broadcastPlayerUpdate(savedPlayer, PlayerUpdateMessage.UpdateType.PLAYER_UPDATE)

        return 1
    }

    // Supprimer un joueur (admin)
    fun deletePlayerById(id:Long?): Int {
        println("PlayerService.deletePlayer : $id")

        val player = getById(id)
        if (player == null) {
            println("PlayerService.deletePlayer : Player not found")
            return -1
        }

        // Broadcast the player deletion via WebSocket before deleting
        playerWebSocketController?.broadcastPlayerUpdate(player, PlayerUpdateMessage.UpdateType.PLAYER_DELETE)

        playerRepository.deleteById(id!!)
        return 1
    }

    fun addPlayer(player:PlayerBean) {
        playerRepository.save(player)
    }
}
