package de.cannamanage.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.Map;
import java.util.UUID;

/**
 * Service for publishing real-time WebSocket events to connected clients.
 * Uses STOMP topics for broadcast (per-club) and user queues for targeted messages.
 * 
 * Topic structure:
 * - /topic/club.{clubId}.infoboard — new info board posts
 * - /topic/club.{clubId}.forum — new forum topics/replies
 * - /topic/club.{clubId}.forum.{topicId} — replies to a specific topic
 * - /topic/club.{clubId}.events — event RSVP changes
 */
@Slf4j
@Service
public class WebSocketEventPublisher {

    private final SimpMessagingTemplate messagingTemplate;

    public WebSocketEventPublisher(SimpMessagingTemplate messagingTemplate) {
        this.messagingTemplate = messagingTemplate;
    }

    /**
     * Publish a new info board post event to all connected club members.
     */
    @Async
    public void publishInfoBoardPost(UUID clubId, UUID postId, String title, String category) {
        String destination = "/topic/club." + clubId + ".infoboard";
        Object payload = Map.of(
                "type", "NEW_POST",
                "postId", postId.toString(),
                "title", title,
                "category", category,
                "timestamp", Instant.now().toString()
        );
        messagingTemplate.convertAndSend(destination, payload);
        log.debug("WebSocket event published to {}: new post '{}'", destination, title);
    }

    /**
     * Publish a new forum topic event.
     */
    @Async
    public void publishForumTopic(UUID clubId, UUID topicId, String title, String authorName) {
        String destination = "/topic/club." + clubId + ".forum";
        Object payload = Map.of(
                "type", "NEW_TOPIC",
                "topicId", topicId.toString(),
                "title", title,
                "authorName", authorName,
                "timestamp", Instant.now().toString()
        );
        messagingTemplate.convertAndSend(destination, payload);
        log.debug("WebSocket event published to {}: new topic '{}'", destination, title);
    }

    /**
     * Publish a new forum reply event to topic subscribers.
     */
    @Async
    public void publishForumReply(UUID clubId, UUID topicId, UUID replyId, String authorName) {
        // Notify the topic-specific channel
        String topicDestination = "/topic/club." + clubId + ".forum." + topicId;
        Object topicPayload = Map.of(
                "type", "NEW_REPLY",
                "topicId", topicId.toString(),
                "replyId", replyId.toString(),
                "authorName", authorName,
                "timestamp", Instant.now().toString()
        );
        messagingTemplate.convertAndSend(topicDestination, topicPayload);

        // Also notify the general forum channel (for reply counts)
        String forumDestination = "/topic/club." + clubId + ".forum";
        Object forumPayload = Map.of(
                "type", "TOPIC_UPDATED",
                "topicId", topicId.toString(),
                "timestamp", Instant.now().toString()
        );
        messagingTemplate.convertAndSend(forumDestination, forumPayload);
        log.debug("WebSocket reply event published for topic {}", topicId);
    }

    /**
     * Publish an event RSVP change to the event creator.
     */
    @Async
    public void publishEventRsvpChange(UUID clubId, UUID eventId, String eventTitle,
                                       String memberName, String rsvpStatus) {
        String destination = "/topic/club." + clubId + ".events";
        Object payload = Map.of(
                "type", "RSVP_CHANGED",
                "eventId", eventId.toString(),
                "eventTitle", eventTitle,
                "memberName", memberName,
                "rsvpStatus", rsvpStatus,
                "timestamp", Instant.now().toString()
        );
        messagingTemplate.convertAndSend(destination, payload);
        log.debug("WebSocket RSVP event published for event {}: {} → {}", eventId, memberName, rsvpStatus);
    }

    /**
     * Publish a notification to a specific user's queue.
     */
    public void publishToUser(UUID userId, String title, String message, String link) {
        String destination = "/queue/notifications";
        Map<String, Object> payload = Map.of(
                "type", "NOTIFICATION",
                "title", title,
                "message", message,
                "link", link != null ? link : "",
                "timestamp", Instant.now().toString()
        );
        messagingTemplate.convertAndSendToUser(userId.toString(), destination, payload);
        log.debug("WebSocket notification sent to user {}: '{}'", userId, title);
    }
}
