package controllers import ( "lost-and-found/internal/models" "lost-and-found/internal/services" "lost-and-found/internal/utils" "net/http" "strconv" "github.com/gin-gonic/gin" "gorm.io/gorm" ) type LostItemController struct { lostItemService *services.LostItemService } func NewLostItemController(db *gorm.DB) *LostItemController { return &LostItemController{ lostItemService: services.NewLostItemService(db), } } // GetAllLostItems gets all lost items // GET /api/lost-items func (c *LostItemController) GetAllLostItems(ctx *gin.Context) { page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1")) limit, _ := strconv.Atoi(ctx.DefaultQuery("limit", "10")) status := ctx.Query("status") category := ctx.Query("category") search := ctx.Query("search") var userID *uint // If manager/admin, can see all. If user, only see their own if userObj, exists := ctx.Get("user"); exists { user := userObj.(*models.User) if user.IsUser() { userID = &user.ID } } lostItems, total, err := c.lostItemService.GetAllLostItems(page, limit, status, category, search, userID) if err != nil { utils.ErrorResponse(ctx, http.StatusInternalServerError, "Failed to get lost items", err.Error()) return } utils.SendPaginatedResponse(ctx, http.StatusOK, "Lost items retrieved", lostItems, total, page, limit) } // GetLostItemByID gets lost item by ID // GET /api/lost-items/:id func (c *LostItemController) GetLostItemByID(ctx *gin.Context) { id, err := strconv.ParseUint(ctx.Param("id"), 10, 32) if err != nil { utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid lost item ID", err.Error()) return } lostItem, err := c.lostItemService.GetLostItemByID(uint(id)) if err != nil { utils.ErrorResponse(ctx, http.StatusNotFound, "Lost item not found", err.Error()) return } utils.SuccessResponse(ctx, http.StatusOK, "Lost item retrieved", lostItem.ToResponse()) } // CreateLostItem creates a new lost item report // POST /api/lost-items func (c *LostItemController) CreateLostItem(ctx *gin.Context) { userObj, _ := ctx.Get("user") user := userObj.(*models.User) var req services.CreateLostItemRequest if err := ctx.ShouldBindJSON(&req); err != nil { utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid request data", err.Error()) return } ipAddress := ctx.ClientIP() userAgent := ctx.Request.UserAgent() lostItem, err := c.lostItemService.CreateLostItem(user.ID, req, ipAddress, userAgent) if err != nil { utils.ErrorResponse(ctx, http.StatusBadRequest, "Failed to create lost item report", err.Error()) return } utils.SuccessResponse(ctx, http.StatusCreated, "Lost item report created", lostItem.ToResponse()) } // UpdateLostItem updates a lost item report // PUT /api/lost-items/:id func (c *LostItemController) UpdateLostItem(ctx *gin.Context) { userObj, _ := ctx.Get("user") user := userObj.(*models.User) lostItemID, err := strconv.ParseUint(ctx.Param("id"), 10, 32) if err != nil { utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid lost item ID", err.Error()) return } var req services.UpdateLostItemRequest if err := ctx.ShouldBindJSON(&req); err != nil { utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid request data", err.Error()) return } ipAddress := ctx.ClientIP() userAgent := ctx.Request.UserAgent() lostItem, err := c.lostItemService.UpdateLostItem(user.ID, uint(lostItemID), req, ipAddress, userAgent) if err != nil { utils.ErrorResponse(ctx, http.StatusBadRequest, "Failed to update lost item report", err.Error()) return } utils.SuccessResponse(ctx, http.StatusOK, "Lost item report updated", lostItem.ToResponse()) } // UpdateLostItemStatus updates lost item status // PATCH /api/lost-items/:id/status func (c *LostItemController) UpdateLostItemStatus(ctx *gin.Context) { userObj, _ := ctx.Get("user") user := userObj.(*models.User) lostItemID, err := strconv.ParseUint(ctx.Param("id"), 10, 32) if err != nil { utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid lost item ID", err.Error()) return } var req struct { Status string `json:"status" binding:"required"` } if err := ctx.ShouldBindJSON(&req); err != nil { utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid request data", err.Error()) return } ipAddress := ctx.ClientIP() userAgent := ctx.Request.UserAgent() if err := c.lostItemService.UpdateLostItemStatus(user.ID, uint(lostItemID), req.Status, ipAddress, userAgent); err != nil { utils.ErrorResponse(ctx, http.StatusBadRequest, "Failed to update status", err.Error()) return } utils.SuccessResponse(ctx, http.StatusOK, "Lost item status updated", nil) } // DeleteLostItem deletes a lost item report // DELETE /api/lost-items/:id func (c *LostItemController) DeleteLostItem(ctx *gin.Context) { userObj, _ := ctx.Get("user") user := userObj.(*models.User) lostItemID, err := strconv.ParseUint(ctx.Param("id"), 10, 32) if err != nil { utils.ErrorResponse(ctx, http.StatusBadRequest, "Invalid lost item ID", err.Error()) return } ipAddress := ctx.ClientIP() userAgent := ctx.Request.UserAgent() if err := c.lostItemService.DeleteLostItem(user.ID, uint(lostItemID), ipAddress, userAgent); err != nil { utils.ErrorResponse(ctx, http.StatusBadRequest, "Failed to delete lost item report", err.Error()) return } utils.SuccessResponse(ctx, http.StatusOK, "Lost item report deleted", nil) } // GetLostItemsByUser gets lost items by user // GET /api/user/lost-items func (c *LostItemController) GetLostItemsByUser(ctx *gin.Context) { userObj, _ := ctx.Get("user") user := userObj.(*models.User) page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1")) limit, _ := strconv.Atoi(ctx.DefaultQuery("limit", "10")) lostItems, total, err := c.lostItemService.GetLostItemsByUser(user.ID, page, limit) if err != nil { utils.ErrorResponse(ctx, http.StatusInternalServerError, "Failed to get lost items", err.Error()) return } utils.SendPaginatedResponse(ctx, http.StatusOK, "Lost items retrieved", lostItems, total, page, limit) }