package promocode import ( "codeword/internal/models" "codeword/internal/repository" "codeword/internal/services" "errors" "github.com/gofiber/fiber/v2" "go.uber.org/zap" ) type PromoCodeController struct { logger *zap.Logger promoCodeService *services.PromoCodeService } func NewPromoCodeController(logger *zap.Logger, promoCodeService *services.PromoCodeService) *PromoCodeController { return &PromoCodeController{ logger: logger, promoCodeService: promoCodeService, } } func (p *PromoCodeController) CreatePromoCode(c *fiber.Ctx) error { var req models.PromoCode if err := c.BodyParser(&req); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) } if req.Codeword == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "codeword is required"}) } createdPromoCode, err := p.promoCodeService.CreatePromoCode(c.Context(), &req) if err != nil { p.logger.Error("Failed to create promocode", zap.Error(err)) if errors.Is(err, repository.ErrDuplicateCodeword) { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Duplicate Codeword"}) } return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) } return c.Status(fiber.StatusCreated).JSON(createdPromoCode) } func (p *PromoCodeController) EditPromoCode(c *fiber.Ctx) error { var req models.ReqEditPromoCode if err := c.BodyParser(&req); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) } if req.ID == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "promocode ID is required"}) } editedPromoCode, err := p.promoCodeService.EditPromoCode(c.Context(), &req) if err != nil { p.logger.Error("Failed to edit promocode", zap.Error(err)) if errors.Is(err, repository.ErrPromoCodeNotFound) { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "PromoCode not found"}) } return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) } return c.Status(fiber.StatusOK).JSON(editedPromoCode) } func (p *PromoCodeController) GetList(c *fiber.Ctx) error { var req models.GetPromoCodesListReq if err := c.BodyParser(&req); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) } promoCodes, count, err := p.promoCodeService.GetPromoCodesList(c.Context(), &req) if err != nil { p.logger.Error("Failed to retrieve promocode list", zap.Error(err)) return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) } resp := models.GetPromoCodesListResp{ Count: count, Items: promoCodes, } return c.Status(fiber.StatusOK).JSON(resp) } func (p *PromoCodeController) Activate(c *fiber.Ctx) error { var req models.ActivateReq if err := c.BodyParser(&req); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) } if req.UserID == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "userid is required"}) } if req.Codeword == "" && req.FastLink == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "codeword or fastlink is required"}) } greetings, err := p.promoCodeService.ActivatePromo(c.Context(), &req) if err != nil { p.logger.Error("Failed to activate promocode", zap.Error(err)) if errors.Is(err, repository.ErrPromoCodeNotFound) { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "PromoCode not found"}) } return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) } resp := models.ActivateResp{ Greetings: greetings, } return c.Status(fiber.StatusOK).JSON(resp) } func (p *PromoCodeController) Delete(c *fiber.Ctx) error { promoCodeID := c.Params("promocodeID") if promoCodeID == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "PromoCode ID is required"}) } err := p.promoCodeService.DeletePromoCode(c.Context(), promoCodeID) if err != nil { p.logger.Error("Failed to delete promocode", zap.Error(err)) if errors.Is(err, repository.ErrPromoCodeNotFound) { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "PromoCode not found"}) } return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) } return c.SendStatus(fiber.StatusOK) } func (p *PromoCodeController) CreateFastLink(c *fiber.Ctx) error { var req struct { PromoCodeID string `json:"id"` } if err := c.BodyParser(&req); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request payload"}) } if req.PromoCodeID == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "PromoCode ID is required"}) } fastLink, err := p.promoCodeService.CreateFastLink(c.Context(), req.PromoCodeID) if err != nil { p.logger.Error("Failed to create fastlink", zap.Error(err)) if errors.Is(err, repository.ErrPromoCodeNotFound) { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "PromoCode not found"}) } return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) } return c.Status(fiber.StatusCreated).JSON(fiber.Map{"fastlink": fastLink}) } func (p *PromoCodeController) GetAllStats(c *fiber.Ctx) error { promoStats, err := p.promoCodeService.GetAllStats(c.Context()) if err != nil { p.logger.Error("Failed getting promo stats", zap.Error(err)) return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Internal Server Error"}) } return c.Status(fiber.StatusOK).JSON(promoStats) }