package fr.teamflash.fencerjudgeback.services

import fr.teamflash.fencerjudgeback.entities.MatchState
import fr.teamflash.fencerjudgeback.entities.RefereeBean
import fr.teamflash.fencerjudgeback.entities.RefereeLevel
import fr.teamflash.fencerjudgeback.repositories.RefereeRepository
import fr.teamflash.fencerjudgeback.websocket.controllers.RefereeWebSocketController
import fr.teamflash.fencerjudgeback.websocket.models.RefereeUpdateMessage
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Lazy
import org.springframework.stereotype.Service

@Service
class RefereeService(
    @Autowired private val refereeRepository: RefereeRepository,
    @Lazy private val refereeWebSocketController: RefereeWebSocketController? = null
) {
    // Obtenir tous les arbitres (public)
    fun getAll(): List<RefereeBean> {
        println("RefereeService.getReferees")
        return refereeRepository.findAll()
    }

    // Obtenir un arbitre par id (public)
    fun getById(id:Long?) : RefereeBean? {
        println("RefereeService.getRefereeById : $id")

        if (id == null) {
            return null
        }

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

    // Obtenir un ou plusieurs arbitre(s) par nom (public)
    fun getByName(name:String): List<RefereeBean?>? {
        println("RefereeService.getRefereeByName : $name")
        return refereeRepository.findAll().filter{ it.name == name }
    }

    // Obtenir un ou plusieurs arbitre(s) par prénom
    fun getByFirstName(firstName:String): List<RefereeBean?>? {
        println("RefereeService.getRefereeByFirstName : $firstName")
        return refereeRepository.findAll().filter{ it.firstName == firstName }
    }

    // Obtenir un ou plusieurs arbitre(s) par niveau
    fun getByLevel(level: RefereeLevel): List<RefereeBean>? {
        println("RefereeService.getByLevel : $level")
        return refereeRepository.findAll().filter{ it.level == level }
    }

    // Ajouter un arbitre (admin)
    fun createReferee(referee: RefereeBean) : RefereeBean {
        println("RefereeService.createReferee : $referee")
        val savedReferee = refereeRepository.save(referee)
        // Broadcast the new referee via WebSocket
        refereeWebSocketController?.broadcastRefereeUpdate(savedReferee, RefereeUpdateMessage.UpdateType.REFEREE_CREATE)
        return savedReferee
    }

    // Modifier un arbitre (admin)
    fun updateReferee(id:Long, newReferee: RefereeBean) : Int? {
        // Vérifier si l'arbitre existe à l'id renseigné
        if (getById(id) == null) {
            return -1
        }

        val updatedReferee = newReferee.copy(id = id)
        val savedReferee = refereeRepository.save(updatedReferee)
        // Broadcast the updated referee via WebSocket
        refereeWebSocketController?.broadcastRefereeUpdate(savedReferee, RefereeUpdateMessage.UpdateType.REFEREE_UPDATE)
        return 1
    }

    // Supprimer un arbitre (admin)
    fun deleteRefereeById(id:Long): Int {
        println("RefereeService.deleteReferee : $id")

        val referee = getById(id)
        if (referee == null) {
            println("RefereeService.deleteReferee : Referee not found")
            return -1
        }

        // Broadcast the referee deletion via WebSocket before deleting
        refereeWebSocketController?.broadcastRefereeUpdate(referee, RefereeUpdateMessage.UpdateType.REFEREE_DELETE)

        refereeRepository.deleteById(id)
        return 1
    }
}
