package handler import ( "net/http" "strconv" "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/warmbly/warmbly/internal/api/middleware" "github.com/warmbly/warmbly/internal/errx" "github.com/warmbly/warmbly/internal/models" ) func notifActor(c *gin.Context) (uuid.UUID, bool) { id, err := uuid.Parse(middleware.GetUserID(c)) if err != nil { errx.JSON(c, errx.New(errx.BadRequest, "invalid user")) return uuid.Nil, false } return id, true } // GetNotificationPreferences returns the caller's notification preferences // (merged over defaults). func (h *Handler) GetNotificationPreferences(c *gin.Context) { uid, ok := notifActor(c) if !ok { return } prefs, xerr := h.NotificationService.GetPreferences(c.Request.Context(), uid) if xerr != nil { errx.JSON(c, xerr) return } c.JSON(http.StatusOK, gin.H{"preferences": prefs}) } // UpdateNotificationPreferences replaces the caller's notification preferences. func (h *Handler) UpdateNotificationPreferences(c *gin.Context) { uid, ok := notifActor(c) if !ok { return } var req models.UpdateNotificationPreferencesRequest if err := c.ShouldBindJSON(&req); err != nil { errx.JSON(c, errx.New(errx.BadRequest, "invalid payload")) return } if xerr := h.NotificationService.UpdatePreferences(c.Request.Context(), uid, &req.Preferences); xerr != nil { errx.JSON(c, xerr) return } c.JSON(http.StatusOK, gin.H{"preferences": req.Preferences}) } // ListNotifications returns the caller's recent feed + the unread count. func (h *Handler) ListNotifications(c *gin.Context) { uid, ok := notifActor(c) if !ok { return } limit := 50 if l := c.Query("limit"); l != "" { if n, e := strconv.Atoi(l); e == nil { limit = n } } unreadOnly := c.Query("unread") == "1" || c.Query("unread") == "true" items, xerr := h.NotificationService.List(c.Request.Context(), uid, limit, unreadOnly) if xerr != nil { errx.JSON(c, xerr) return } unread, _ := h.NotificationService.UnreadCount(c.Request.Context(), uid) c.JSON(http.StatusOK, gin.H{"notifications": items, "unread": unread}) } // MarkNotificationRead marks one notification read. func (h *Handler) MarkNotificationRead(c *gin.Context) { uid, ok := notifActor(c) if !ok { return } id, err := uuid.Parse(c.Param("id")) if err != nil { errx.JSON(c, errx.ErrUuid) return } if xerr := h.NotificationService.MarkRead(c.Request.Context(), uid, id); xerr != nil { errx.JSON(c, xerr) return } c.JSON(http.StatusOK, gin.H{"ok": true}) } // MarkAllNotificationsRead marks the caller's whole feed read (PUT on the // collection — keeps the route tree clear of a static-vs-:id conflict). func (h *Handler) MarkAllNotificationsRead(c *gin.Context) { uid, ok := notifActor(c) if !ok { return } if xerr := h.NotificationService.MarkAllRead(c.Request.Context(), uid); xerr != nil { errx.JSON(c, xerr) return } c.JSON(http.StatusOK, gin.H{"ok": true}) }