package fr.teamflash.fencerjudgeback.websocket.controllers

import fr.teamflash.fencerjudgeback.config.CHANNEL_MATCH_NAME
import fr.teamflash.fencerjudgeback.entities.RefereeBean
import fr.teamflash.fencerjudgeback.services.RefereeService
import fr.teamflash.fencerjudgeback.websocket.models.RefereeUpdateMessage
import org.springframework.context.event.EventListener
import org.springframework.messaging.handler.annotation.MessageMapping
import org.springframework.messaging.handler.annotation.SendTo
import org.springframework.messaging.simp.SimpMessagingTemplate
import org.springframework.messaging.simp.stomp.StompHeaderAccessor
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.socket.messaging.SessionSubscribeEvent

@Controller
@RequestMapping("/ws")
class RefereeWebSocketController(
    private val refereeService: RefereeService,
    private val messagingTemplate: SimpMessagingTemplate
) {

    private val messageHistory = ArrayList<RefereeBean>()

    @MessageMapping("/referee.update")
    @SendTo("/topic/referee.updates")
    fun handleRefereeUpdate(refereeUpdateMessage: RefereeUpdateMessage): RefereeUpdateMessage {
        // Create a RefereeBean from the update message
        val refereeBean = RefereeBean(
            id = refereeUpdateMessage.refereeId,
            name = refereeUpdateMessage.name,
            firstName = refereeUpdateMessage.firstName,
            level = refereeUpdateMessage.level
        )
        
        // Update the referee in the database
        refereeService.updateReferee(refereeBean.id ?: 0, refereeBean)
        
        // Return the update message to be broadcast to all subscribers
        return refereeUpdateMessage
    }
    
    /**
     * Broadcast a referee update to all connected clients
     * This method can be called from other services
     */
    fun broadcastRefereeUpdate(refereeBean: RefereeBean, type: RefereeUpdateMessage.UpdateType = RefereeUpdateMessage.UpdateType.REFEREE_UPDATE) {
        val updateMessage = RefereeUpdateMessage.fromRefereeBean(refereeBean, type)
        messagingTemplate.convertAndSend("/topic/referee.updates", updateMessage)
    }

    @EventListener
    fun handleWebSocketSubscribeListener(event: SessionSubscribeEvent) {
        val headerAccessor = StompHeaderAccessor.wrap(event.message)
        if ("/topic/referee.updates" == headerAccessor.destination) {
            // When a client subscribes, send them the current referees
            val referees = refereeService.getAll()
            referees.forEach { referee ->
                messagingTemplate.convertAndSend(
                    "/topic/referee.updates", 
                    RefereeUpdateMessage.fromRefereeBean(referee, RefereeUpdateMessage.UpdateType.REFEREE_UPDATE)
                )
            }
        }
    }
}