package de.cannamanage.service;

import de.cannamanage.domain.entity.Notification;
import de.cannamanage.domain.enums.NotificationType;
import de.cannamanage.service.repository.NotificationRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * Notification service — persists notifications and delivers in real-time via WebSocket.
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class NotificationService {

    private final NotificationRepository notificationRepository;
    private final SimpMessagingTemplate messagingTemplate;

    /**
     * Send a notification: persist to DB + push via WebSocket.
     */
    @Transactional
    public Notification sendNotification(UUID userId, NotificationType type, String title, String message, String link) {
        var notification = new Notification(userId, type, title, message, link);
        notification = notificationRepository.save(notification);

        // Push to user's WebSocket queue
        messagingTemplate.convertAndSendToUser(
                userId.toString(),
                "/queue/notifications",
                Map.of(
                        "id", notification.getId(),
                        "type", notification.getType().name(),
                        "title", notification.getTitle(),
                        "message", notification.getMessage(),
                        "link", notification.getLink() != null ? notification.getLink() : "",
                        "read", notification.isRead(),
                        "createdAt", notification.getCreatedAt().toString()
                )
        );

        log.debug("Notification sent to user {}: {} - {}", userId, type, title);
        return notification;
    }

    /**
     * Get the last 10 notifications for a user (unread first).
     */
    @Transactional(readOnly = true)
    public List<Notification> getRecentNotifications(UUID userId) {
        return notificationRepository.findTop10ByUserIdOrderByReadAscCreatedAtDesc(userId);
    }

    /**
     * Get unread count for badge display.
     */
    @Transactional(readOnly = true)
    public long getUnreadCount(UUID userId) {
        return notificationRepository.countByUserIdAndReadFalse(userId);
    }

    /**
     * Mark a single notification as read.
     */
    @Transactional
    public void markAsRead(UUID notificationId) {
        notificationRepository.findById(notificationId).ifPresent(n -> {
            n.setRead(true);
            notificationRepository.save(n);
        });
    }

    /**
     * Mark all notifications as read for a user.
     */
    @Transactional
    public int markAllAsRead(UUID userId) {
        return notificationRepository.markAllAsRead(userId);
    }
}
