package handlers import ( "log/slog" "strconv" "time" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet" "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response" customvalidator "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/validator" "github.com/gofiber/fiber/v2" ) type WalletRes struct { ID int64 `json:"id" example:"1"` Balance float32 `json:"amount" example:"100.0"` IsWithdraw bool `json:"is_withdraw" example:"true"` IsBettable bool `json:"is_bettable" example:"true"` IsTransferable bool `json:"is_transferable" example:"true"` IsActive bool `json:"is_active" example:"true"` UserID int64 `json:"user_id" example:"1"` UpdatedAt time.Time `json:"updated_at"` CreatedAt time.Time `json:"created_at"` } func convertWallet(wallet domain.Wallet) WalletRes { return WalletRes{ ID: wallet.ID, Balance: wallet.Balance.Float64(), IsWithdraw: wallet.IsWithdraw, IsBettable: wallet.IsBettable, IsTransferable: wallet.IsTransferable, IsActive: wallet.IsActive, UserID: wallet.UserID, UpdatedAt: wallet.UpdatedAt, CreatedAt: wallet.CreatedAt, } } type CustomerWalletRes struct { ID int64 `json:"id" example:"1"` RegularID int64 `json:"regular_id" example:"1"` RegularBalance float32 `json:"regular_balance" example:"100.0"` StaticID int64 `json:"static_id" example:"1"` StaticBalance float32 `json:"static_balance" example:"100.0"` CustomerID int64 `json:"customer_id" example:"1"` CompanyID int64 `json:"company_id" example:"1"` RegularUpdatedAt time.Time `json:"regular_updated_at"` StaticUpdatedAt time.Time `json:"static_updated_at"` CreatedAt time.Time `json:"created_at"` } func convertCustomerWallet(wallet domain.GetCustomerWallet) CustomerWalletRes { return CustomerWalletRes{ ID: wallet.ID, RegularID: wallet.RegularID, RegularBalance: wallet.RegularBalance.Float64(), StaticID: wallet.StaticID, StaticBalance: wallet.StaticBalance.Float64(), CustomerID: wallet.CustomerID, CompanyID: wallet.CompanyID, RegularUpdatedAt: wallet.RegularUpdatedAt, StaticUpdatedAt: wallet.StaticUpdatedAt, CreatedAt: wallet.CreatedAt, } } // GetWalletByID godoc // @Summary Get wallet by ID // @Description Retrieve wallet details by wallet ID // @Tags wallet // @Accept json // @Produce json // @Param id path int true "Wallet ID" // @Success 200 {object} WalletRes // @Failure 400 {object} response.APIResponse // @Failure 500 {object} response.APIResponse // @Router /wallet/{id} [get] func GetWalletByID(logger *slog.Logger, walletSvc *wallet.Service, validator *customvalidator.CustomValidator) fiber.Handler { return func(c *fiber.Ctx) error { walletID := c.Params("id") id, err := strconv.ParseInt(walletID, 10, 64) if err != nil { logger.Error("Invalid wallet ID", "walletID", walletID, "error", err) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid wallet ID", err, nil) } wallet, err := walletSvc.GetWalletByID(c.Context(), id) if err != nil { logger.Error("Failed to get wallet by ID", "walletID", id, "error", err) return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve wallet", err, nil) } res := convertWallet(wallet) return response.WriteJSON(c, fiber.StatusOK, "Wallet retrieved successfully", res, nil) } } // GetAllWallets godoc // @Summary Get all wallets // @Description Retrieve all wallets // @Tags wallet // @Accept json // @Produce json // @Success 200 {array} WalletRes // @Failure 400 {object} response.APIResponse // @Failure 500 {object} response.APIResponse // @Router /wallet [get] func GetAllWallets(logger *slog.Logger, walletSvc *wallet.Service, validator *customvalidator.CustomValidator) fiber.Handler { return func(c *fiber.Ctx) error { wallets, err := walletSvc.GetAllWallets(c.Context()) if err != nil { logger.Error("Failed to get wallets", "error", err) } var res []WalletRes = make([]WalletRes, len(wallets)) for _, wallet := range wallets { res = append(res, convertWallet(wallet)) } return response.WriteJSON(c, fiber.StatusOK, "All Wallets retrieved", res, nil) } } type UpdateWalletActiveReq struct { IsActive bool } // UpdateWalletActive godoc // @Summary Activate and Deactivate Wallet // @Description Can activate and deactivate wallet // @Tags wallet // @Accept json // @Produce json // @Param id path int true "Wallet ID" // @Param updateCashOut body UpdateWalletActiveReq true "Update Wallet Active" // @Success 200 {object} response.APIResponse // @Failure 400 {object} response.APIResponse // @Failure 500 {object} response.APIResponse // @Router /wallet/{id} [patch] func UpdateWalletActive(logger *slog.Logger, walletSvc *wallet.Service, validator *customvalidator.CustomValidator) fiber.Handler { return func(c *fiber.Ctx) error { walletID := c.Params("id") id, err := strconv.ParseInt(walletID, 10, 64) if err != nil { logger.Error("Invalid bet ID", "walletID", walletID, "error", err) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid wallet ID", err, nil) } var req UpdateWalletActiveReq if err := c.BodyParser(&req); err != nil { logger.Error("UpdateWalletActiveReq failed", "error", err) return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "Invalid request", }) } err = walletSvc.UpdateWalletActive(c.Context(), id, req.IsActive) if err != nil { logger.Error("Failed to update", "walletID", id, "error", err) return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update wallet", err, nil) } return response.WriteJSON(c, fiber.StatusOK, "Wallet successfully updated", nil, nil) } } // GetCustomerWallet godoc // @Summary Get customer wallet // @Description Retrieve customer wallet details // @Tags wallet // @Accept json // @Produce json // @Param company_id header int true "Company ID" // @Security Bearer // @Success 200 {object} CustomerWalletRes // @Failure 400 {object} response.APIResponse // @Failure 500 {object} response.APIResponse // @Router /user/wallet [get] func GetCustomerWallet(logger *slog.Logger, walletSvc *wallet.Service, validator *customvalidator.CustomValidator) fiber.Handler { return func(c *fiber.Ctx) error { userId := c.Locals("user_id").(int64) // role := string(c.Locals("role").(domain.Role)) vendorID, err := strconv.ParseInt(c.Get("vendor_id"), 10, 64) if err != nil { return c.Status(fiber.StatusBadRequest).SendString("Invalid company_id") } logger.Info("Company ID: " + strconv.FormatInt(vendorID, 10)) // if role != string(domain.RoleCustomer) { // logger.Error("Unauthorized access", "userId", userId, "role", role) // return response.WriteJSON(c, fiber.StatusUnauthorized, "Unauthorized access", nil, nil) // } wallet, err := walletSvc.GetCustomerWallet(c.Context(), userId, vendorID) if err != nil { logger.Error("Failed to get customer wallet", "userId", userId, "error", err) return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve wallet", err, nil) } res := convertCustomerWallet(wallet) return response.WriteJSON(c, fiber.StatusOK, "Wallet retrieved successfully", res, nil) } }