package handlers import ( "net/http" "strconv" "github.com/breakpilot/consent-service/internal/middleware" "github.com/breakpilot/consent-service/internal/services" "github.com/gin-gonic/gin" "github.com/google/uuid" ) // NotificationHandler handles notification-related requests type NotificationHandler struct { notificationService *services.NotificationService } // NewNotificationHandler creates a new notification handler func NewNotificationHandler(notificationService *services.NotificationService) *NotificationHandler { return &NotificationHandler{ notificationService: notificationService, } } // GetNotifications returns notifications for the current user func (h *NotificationHandler) GetNotifications(c *gin.Context) { userID, err := middleware.GetUserID(c) if err != nil || userID == uuid.Nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"}) return } // Parse query parameters limit := 20 offset := 0 unreadOnly := false if l := c.Query("limit"); l != "" { if parsed, err := strconv.Atoi(l); err == nil && parsed > 0 { limit = parsed } } if o := c.Query("offset"); o != "" { if parsed, err := strconv.Atoi(o); err == nil && parsed >= 0 { offset = parsed } } if u := c.Query("unread_only"); u == "true" { unreadOnly = true } notifications, total, err := h.notificationService.GetUserNotifications(c.Request.Context(), userID, limit, offset, unreadOnly) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch notifications"}) return } c.JSON(http.StatusOK, gin.H{ "notifications": notifications, "total": total, "limit": limit, "offset": offset, }) } // GetUnreadCount returns the count of unread notifications func (h *NotificationHandler) GetUnreadCount(c *gin.Context) { userID, err := middleware.GetUserID(c) if err != nil || userID == uuid.Nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"}) return } count, err := h.notificationService.GetUnreadCount(c.Request.Context(), userID) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get unread count"}) return } c.JSON(http.StatusOK, gin.H{"unread_count": count}) } // MarkAsRead marks a notification as read func (h *NotificationHandler) MarkAsRead(c *gin.Context) { userID, err := middleware.GetUserID(c) if err != nil || userID == uuid.Nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"}) return } notificationID, err := uuid.Parse(c.Param("id")) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid notification ID"}) return } if err := h.notificationService.MarkAsRead(c.Request.Context(), userID, notificationID); err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Notification not found or already read"}) return } c.JSON(http.StatusOK, gin.H{"message": "Notification marked as read"}) } // MarkAllAsRead marks all notifications as read func (h *NotificationHandler) MarkAllAsRead(c *gin.Context) { userID, err := middleware.GetUserID(c) if err != nil || userID == uuid.Nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"}) return } if err := h.notificationService.MarkAllAsRead(c.Request.Context(), userID); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to mark notifications as read"}) return } c.JSON(http.StatusOK, gin.H{"message": "All notifications marked as read"}) } // DeleteNotification deletes a notification func (h *NotificationHandler) DeleteNotification(c *gin.Context) { userID, err := middleware.GetUserID(c) if err != nil || userID == uuid.Nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"}) return } notificationID, err := uuid.Parse(c.Param("id")) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid notification ID"}) return } if err := h.notificationService.DeleteNotification(c.Request.Context(), userID, notificationID); err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Notification not found"}) return } c.JSON(http.StatusOK, gin.H{"message": "Notification deleted"}) } // GetPreferences returns notification preferences for the user func (h *NotificationHandler) GetPreferences(c *gin.Context) { userID, err := middleware.GetUserID(c) if err != nil || userID == uuid.Nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"}) return } prefs, err := h.notificationService.GetPreferences(c.Request.Context(), userID) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get preferences"}) return } c.JSON(http.StatusOK, prefs) } // UpdatePreferences updates notification preferences for the user func (h *NotificationHandler) UpdatePreferences(c *gin.Context) { userID, err := middleware.GetUserID(c) if err != nil || userID == uuid.Nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid user"}) return } var req struct { EmailEnabled *bool `json:"email_enabled"` PushEnabled *bool `json:"push_enabled"` InAppEnabled *bool `json:"in_app_enabled"` ReminderFrequency *string `json:"reminder_frequency"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"}) return } // Get current preferences prefs, _ := h.notificationService.GetPreferences(c.Request.Context(), userID) // Update only provided fields if req.EmailEnabled != nil { prefs.EmailEnabled = *req.EmailEnabled } if req.PushEnabled != nil { prefs.PushEnabled = *req.PushEnabled } if req.InAppEnabled != nil { prefs.InAppEnabled = *req.InAppEnabled } if req.ReminderFrequency != nil { prefs.ReminderFrequency = *req.ReminderFrequency } if err := h.notificationService.UpdatePreferences(c.Request.Context(), userID, prefs); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update preferences"}) return } c.JSON(http.StatusOK, gin.H{"message": "Preferences updated", "preferences": prefs}) }