package handlers import ( "errors" "fmt" "strconv" "time" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/SamuelTariku/FortuneBet-Backend/internal/pkgs/helpers" "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response" "github.com/gofiber/fiber/v2" "go.uber.org/zap" ) func (h *Handler) CreateRaffle(c *fiber.Ctx) error { var req domain.CreateRaffle if err := c.BodyParser(&req); err != nil { h.mongoLoggerSvc.Info("Failed to parse raffle request", zap.Int("status_code", fiber.StatusBadRequest), zap.Error(err), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusBadRequest, "Invalid request body") } if valErrs, ok := h.validator.Validate(c, req); !ok { var errMsg string for field, msg := range valErrs { errMsg += fmt.Sprintf("%s: %s; ", field, msg) } h.mongoLoggerSvc.Info("Failed to validate settings", zap.String("errMsg", errMsg), zap.Int("status_code", fiber.StatusBadRequest), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusBadRequest, errMsg) } raffle, err := h.raffleSvc.CreateRaffle(c.Context(), req) if err != nil { h.mongoLoggerSvc.Error("Failed to create raffle", zap.Int("status_code", fiber.StatusInternalServerError), zap.Error(err), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusInternalServerError, "Failed to create raffle") } return response.WriteJSON(c, fiber.StatusOK, "Raffle created successfully", raffle, nil) } func (h *Handler) DeleteRaffle(c *fiber.Ctx) error { stringRaffleID := c.Params("id") raffleID, err := strconv.Atoi(stringRaffleID) if err != nil { h.mongoLoggerSvc.Info("failed to parse raffle id", zap.String("stringRaffleID", stringRaffleID), zap.Int("status_code", fiber.StatusBadRequest), zap.Error(err), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusBadRequest, "Invalid raffle id") } raffle, err := h.raffleSvc.DeleteRaffle(c.Context(), int32(raffleID)) if err != nil { fmt.Println("raffle delete error: ", err) h.mongoLoggerSvc.Error("Failed to delete raffle", zap.Int("status_code", fiber.StatusInternalServerError), zap.Error(err), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusInternalServerError, "Failed to delete raffle") } return response.WriteJSON(c, fiber.StatusOK, "Raffle deleted successfully", raffle, nil) } func (h *Handler) GetRafflesOfCompany(c *fiber.Ctx) error { stringCompanyID := c.Params("id") companyID, err := strconv.Atoi(stringCompanyID) if err != nil || companyID == 0 { h.mongoLoggerSvc.Info("failed to parse company id", zap.String("stringCompanyID", stringCompanyID), zap.Int("status_code", fiber.StatusBadRequest), zap.Error(err), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusBadRequest, "Invalid company ID") } companyRaffles, err := h.raffleSvc.GetRafflesOfCompany(c.Context(), int32(companyID)) if err != nil { h.mongoLoggerSvc.Error("Failed to fetch company raffle", zap.Int("status_code", fiber.StatusInternalServerError), zap.Error(err), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch company raffle") } return response.WriteJSON(c, fiber.StatusOK, "Company Raffles fetched successfully", companyRaffles, nil) } func (h *Handler) GetRaffleStanding(c *fiber.Ctx) error { raffleIDStr := c.Params("id") limitStr := c.Params("limit") // if error happens while parsing, it just uses zero values // resulting in empty standing raffleID, _ := strconv.Atoi(raffleIDStr) limit, _ := strconv.Atoi(limitStr) raffleStanding, err := h.raffleSvc.GetRaffleStanding(c.Context(), int32(raffleID), int32(limit)) if err != nil { h.mongoLoggerSvc.Error("Failed to fetch raffle standing", zap.Int("status_code", fiber.StatusInternalServerError), zap.Error(err), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch raffle standing") } maskedRaffleStanding := []domain.RaffleStanding{} for _, standing := range raffleStanding { maskedStanding := domain.RaffleStanding{ UserID: standing.UserID, RaffleID: standing.RaffleID, FirstName: standing.FirstName, LastName: standing.LastName, PhoneNumber: helpers.MaskPhone(standing.PhoneNumber), Email: helpers.MaskEmail(standing.Email), TicketCount: standing.TicketCount, } maskedRaffleStanding = append(maskedRaffleStanding, maskedStanding) } return response.WriteJSON(c, fiber.StatusOK, "Raffles standing fetched successfully", maskedRaffleStanding, nil) } func (h *Handler) GetRaffleWinners(c *fiber.Ctx) error { raffleIDStr := c.Params("id") limitStr := c.Params("limit") // if error happens while parsing, it just uses zero values // resulting in empty standing raffleID, _ := strconv.Atoi(raffleIDStr) limit, _ := strconv.Atoi(limitStr) raffleStanding, err := h.raffleSvc.GetRaffleStanding(c.Context(), int32(raffleID), int32(limit)) if err != nil { h.mongoLoggerSvc.Error("Failed to fetch raffle standing", zap.Int("status_code", fiber.StatusInternalServerError), zap.Error(err), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch raffle standing") } // set raffle as complete if err := h.raffleSvc.SetRaffleComplete(c.Context(), int32(raffleID)); err != nil { h.mongoLoggerSvc.Error("Failed to set raffle complete", zap.Int("status_code", fiber.StatusInternalServerError), zap.Error(err), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusInternalServerError, "Failed to set raffle complete") } // add winners to table var errs []error for i, standing := range raffleStanding { err = h.raffleSvc.CreateRaffleWinner(c.Context(), domain.RaffleWinnerParams{ RaffleID: standing.RaffleID, UserID: int32(standing.UserID), Rank: int32(i + 1), }) if err != nil { errs = append(errs, err) } } if len(errs) != 0 { h.mongoLoggerSvc.Error("Failed to create raffle winners", zap.Int("status_code", fiber.StatusInternalServerError), zap.Error(errors.Join(errs...)), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusInternalServerError, "Failed to create raffle winners") } return nil } func (h *Handler) CreateRaffleTicket(c *fiber.Ctx) error { var req domain.CreateRaffleTicket if err := c.BodyParser(&req); err != nil { fmt.Println("parser error: ", err) h.mongoLoggerSvc.Info("Failed to parse raffle ticket request", zap.Int("status_code", fiber.StatusBadRequest), zap.Error(err), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusBadRequest, "Invalid request body") } if valErrs, ok := h.validator.Validate(c, req); !ok { var errMsg string for field, msg := range valErrs { errMsg += fmt.Sprintf("%s: %s; ", field, msg) } h.mongoLoggerSvc.Info("Failed to validate settings", zap.String("errMsg", errMsg), zap.Int("status_code", fiber.StatusBadRequest), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusBadRequest, errMsg) } raffleTicket, err := h.raffleSvc.CreateRaffleTicket(c.Context(), req) if err != nil { fmt.Println("raffle ticket create error: ", err) h.mongoLoggerSvc.Error("Failed to create raffle ticket", zap.Int("status_code", fiber.StatusInternalServerError), zap.Error(err), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusInternalServerError, "Failed to create raffle ticket") } return response.WriteJSON(c, fiber.StatusOK, "Raffle created successfully", raffleTicket, nil) } func (h *Handler) GetUserRaffleTickets(c *fiber.Ctx) error { stringUserID := c.Params("id") userID, err := strconv.Atoi(stringUserID) if err != nil { h.mongoLoggerSvc.Info("failed to parse company id", zap.String("stringUserID", stringUserID), zap.Int("status_code", fiber.StatusBadRequest), zap.Error(err), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusBadRequest, "Invalid user ID") } raffleTickets, err := h.raffleSvc.GetUserRaffleTickets(c.Context(), int32(userID)) if err != nil { h.mongoLoggerSvc.Error("Failed to fetch user raffle tickets", zap.Int("status_code", fiber.StatusInternalServerError), zap.Error(err), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch user raffle tickets") } return response.WriteJSON(c, fiber.StatusOK, "User raffle tickets fetched successfully", raffleTickets, nil) } func (h *Handler) SuspendRaffleTicket(c *fiber.Ctx) error { stringRaffleTicketID := c.Params("id") raffleTicketID, err := strconv.Atoi(stringRaffleTicketID) if err != nil { h.mongoLoggerSvc.Info("failed to parse raffle ticket id", zap.String("stringUserID", stringRaffleTicketID), zap.Int("status_code", fiber.StatusBadRequest), zap.Error(err), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusBadRequest, "Invalid raffel ticket id") } if err := h.raffleSvc.SuspendRaffleTicket(c.Context(), int32(raffleTicketID)); err != nil { h.mongoLoggerSvc.Error("Failed to suspend raffle ticket", zap.Int("status_code", fiber.StatusInternalServerError), zap.Error(err), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusInternalServerError, "Failed to suspend raffle ticket") } return response.WriteJSON(c, fiber.StatusOK, "User raffle tickets suspended successfully", nil, nil) } func (h *Handler) UnSuspendRaffleTicket(c *fiber.Ctx) error { stringRaffleTicketID := c.Params("id") raffleTicketID, err := strconv.Atoi(stringRaffleTicketID) if err != nil { h.mongoLoggerSvc.Info("failed to parse raffle ticket id", zap.String("stringUserID", stringRaffleTicketID), zap.Int("status_code", fiber.StatusBadRequest), zap.Error(err), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusBadRequest, "Invalid raffel ticket id") } if err := h.raffleSvc.UnSuspendRaffleTicket(c.Context(), int32(raffleTicketID)); err != nil { h.mongoLoggerSvc.Error("Failed to unsuspend raffle ticket", zap.Int("status_code", fiber.StatusInternalServerError), zap.Error(err), zap.Time("timestamp", time.Now()), ) return fiber.NewError(fiber.StatusInternalServerError, "Failed to unsuspend raffle ticket") } return response.WriteJSON(c, fiber.StatusOK, "User raffle tickets unsuspended successfully", nil, nil) }