package handlers import ( "fmt" "math" "strconv" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/gofiber/fiber/v2" ) // CreateDirectDeposit godoc // @Summary Create a new direct deposit // @Description Creates a direct deposit for a customer and notifies both the customer and admins // @Tags DirectDeposit // @Accept json // @Produce json // @Param body body domain.CreateDirectDeposit true "Direct deposit details" // @Success 200 {object} domain.Response{data=domain.DirectDeposit} // @Failure 400 {object} domain.ErrorResponse // @Failure 502 {object} domain.ErrorResponse // @Router /api/v1/direct-deposits [post] func (h *Handler) CreateDirectDeposit(c *fiber.Ctx) error { var req domain.CreateDirectDeposit if err := c.BodyParser(&req); err != nil { return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ Message: "Invalid request payload", Error: err.Error(), }) } // Call service deposit, err := h.directDepositSvc.CreateDirectDeposit(c.Context(), req) if err != nil { h.logger.Error("CreateDirectDeposit error", err.Error()) return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{ Message: "Failed to create direct deposit", Error: err.Error(), }) } return c.Status(fiber.StatusOK).JSON(domain.Response{ Message: "Direct deposit created successfully", Data: deposit, StatusCode: fiber.StatusOK, Success: true, }) } // GetDirectDepositsByStatus godoc // @Summary Get direct deposits by status // @Description Fetches direct deposits filtered by status with pagination // @Tags DirectDeposit // @Accept json // @Produce json // @Param status query string true "Deposit status (e.g., PENDING, APPROVED, REJECTED)" // @Param page query int false "Page number" // @Param pageSize query int false "Page size" // @Success 200 {object} domain.Response{data=[]domain.DirectDeposit} // @Failure 400 {object} domain.ErrorResponse // @Failure 502 {object} domain.ErrorResponse // @Router /api/v1/direct-deposits [get] func (h *Handler) GetDirectDepositsByStatus(c *fiber.Ctx) error { status := c.Query("status") if status == "" { return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ Message: "status query parameter is required", }) } page, _ := strconv.Atoi(c.Query("page", "1")) pageSize, _ := strconv.Atoi(c.Query("pageSize", "50")) deposits, total, err := h.directDepositSvc.GetDirectDepositsByStatus(c.Context(), status, page, pageSize) if err != nil { h.logger.Error("GetDirectDepositsByStatus error", err) return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{ Message: "Failed to fetch direct deposits", Error: err.Error(), }) } return c.Status(fiber.StatusOK).JSON(domain.Response{ Message: fmt.Sprintf("Direct deposits with status '%s' fetched successfully", status), Data: deposits, StatusCode: fiber.StatusOK, Success: true, // Optional: include pagination info MetaData: map[string]any{ "page": page, "pageSize": pageSize, "total": total, "totalPage": int(math.Ceil(float64(total) / float64(pageSize))), }, }) } // ApproveDirectDeposit godoc // @Summary Approve a direct deposit // @Description Approves a direct deposit by admin and credits customer wallet // @Tags DirectDeposit // @Accept json // @Produce json // @Param depositID path int true "Deposit ID" // @Param adminID query int true "Admin ID performing the approval" // @Success 200 {object} domain.Response{data=string} // @Failure 400 {object} domain.ErrorResponse // @Failure 502 {object} domain.ErrorResponse // @Router /api/v1/direct-deposits/{depositID}/approve [post] func (h *Handler) ApproveDirectDeposit(c *fiber.Ctx) error { depositID, err := strconv.Atoi(c.Params("depositID")) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ Message: "Invalid deposit ID", Error: err.Error(), }) } adminID, err := strconv.Atoi(c.Query("adminID")) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ Message: "Invalid admin ID", Error: err.Error(), }) } if err := h.directDepositSvc.ApproveDirectDeposit(c.Context(), depositID, adminID); err != nil { h.logger.Error("ApproveDirectDeposit error", err) return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{ Message: "Failed to approve direct deposit", Error: err.Error(), }) } return c.Status(fiber.StatusOK).JSON(domain.Response{ Message: fmt.Sprintf("Direct deposit #%d approved successfully", depositID), Data: fmt.Sprintf("Deposit #%d approved", depositID), StatusCode: fiber.StatusOK, Success: true, }) } // RejectDirectDeposit godoc // @Summary Reject a direct deposit // @Description Rejects a direct deposit by admin and notifies the customer // @Tags DirectDeposit // @Accept json // @Produce json // @Param depositID path int true "Deposit ID" // @Param adminID query int true "Admin ID performing the rejection" // @Param reason query string true "Reason for rejection" // @Success 200 {object} domain.Response{data=string} // @Failure 400 {object} domain.ErrorResponse // @Failure 502 {object} domain.ErrorResponse // @Router /api/v1/direct-deposits/{depositID}/reject [post] func (h *Handler) RejectDirectDeposit(c *fiber.Ctx) error { depositID, err := strconv.Atoi(c.Params("depositID")) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ Message: "Invalid deposit ID", Error: err.Error(), }) } adminID, err := strconv.Atoi(c.Query("adminID")) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ Message: "Invalid admin ID", Error: err.Error(), }) } reason := c.Query("reason") if reason == "" { return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ Message: "Rejection reason is required", }) } if err := h.directDepositSvc.RejectDirectDeposit(c.Context(), depositID, adminID, reason); err != nil { h.logger.Error("RejectDirectDeposit error", err) return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{ Message: "Failed to reject direct deposit", Error: err.Error(), }) } return c.Status(fiber.StatusOK).JSON(domain.Response{ Message: fmt.Sprintf("Direct deposit #%d rejected successfully", depositID), Data: fmt.Sprintf("Deposit #%d rejected", depositID), StatusCode: fiber.StatusOK, Success: true, }) } // GetDirectDepositByID godoc // @Summary Get a direct deposit by ID // @Description Fetches a single direct deposit by its ID // @Tags DirectDeposit // @Accept json // @Produce json // @Param depositID path int true "Deposit ID" // @Success 200 {object} domain.Response{data=domain.DirectDeposit} // @Failure 400 {object} domain.ErrorResponse // @Failure 502 {object} domain.ErrorResponse // @Router /api/v1/direct-deposits/{depositID} [get] func (h *Handler) GetDirectDepositByID(c *fiber.Ctx) error { depositID, err := strconv.Atoi(c.Params("depositID")) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ Message: "Invalid deposit ID", Error: err.Error(), }) } deposit, err := h.directDepositSvc.GetDirectDepositByID(c.Context(), depositID) if err != nil { h.logger.Error("GetDirectDepositByID error", err) return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{ Message: "Failed to fetch direct deposit", Error: err.Error(), }) } return c.Status(fiber.StatusOK).JSON(domain.Response{ Message: fmt.Sprintf("Direct deposit #%d fetched successfully", depositID), Data: deposit, StatusCode: fiber.StatusOK, Success: true, }) } // DeleteDirectDeposit godoc // @Summary Delete a direct deposit // @Description Deletes a direct deposit by its ID // @Tags DirectDeposit // @Accept json // @Produce json // @Param depositID path int true "Deposit ID" // @Success 200 {object} domain.Response{data=string} // @Failure 400 {object} domain.ErrorResponse // @Failure 502 {object} domain.ErrorResponse // @Router /api/v1/direct-deposits/{depositID} [delete] func (h *Handler) DeleteDirectDeposit(c *fiber.Ctx) error { depositID, err := strconv.Atoi(c.Params("depositID")) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ Message: "Invalid deposit ID", Error: err.Error(), }) } if err := h.directDepositSvc.DeleteDirectDeposit(c.Context(), depositID); err != nil { h.logger.Error("DeleteDirectDeposit error", err) return c.Status(fiber.StatusBadGateway).JSON(domain.ErrorResponse{ Message: "Failed to delete direct deposit", Error: err.Error(), }) } return c.Status(fiber.StatusOK).JSON(domain.Response{ Message: fmt.Sprintf("Direct deposit #%d deleted successfully", depositID), Data: fmt.Sprintf("Deposit #%d deleted", depositID), StatusCode: fiber.StatusOK, Success: true, }) }