package handlers import ( "strconv" "time" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response" "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, } } type BranchWalletRes struct { ID int64 `json:"id" example:"1"` Balance float32 `json:"balance" example:"100.0"` IsActive bool `json:"is_active" example:"true"` Name string `json:"name" example:"true"` Location string `json:"location" example:"somewhere"` BranchManagerID int64 `json:"branch_manager_id" example:"1"` CompanyID int64 `json:"company_id" example:"1"` IsSelfOwned bool `json:"is_self_owned" example:"false"` UpdatedAt time.Time `json:"updated_at"` CreatedAt time.Time `json:"created_at"` } // 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 (h *Handler) GetWalletByID(c *fiber.Ctx) error { walletID := c.Params("id") id, err := strconv.ParseInt(walletID, 10, 64) if err != nil { h.logger.Error("Invalid wallet ID", "walletID", walletID, "error", err) return fiber.NewError(fiber.StatusBadRequest, "Invalid wallet ID") } wallet, err := h.walletSvc.GetWalletByID(c.Context(), id) if err != nil { h.logger.Error("Failed to get wallet by ID", "walletID", id, "error", err) return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve wallet") } 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 (h *Handler) GetAllWallets(c *fiber.Ctx) error { wallets, err := h.walletSvc.GetAllWallets(c.Context()) if err != nil { h.logger.Error("Failed to get wallets", "error", err) return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve wallets", err, nil) } var res []WalletRes = make([]WalletRes, 0, len(wallets)) for _, wallet := range wallets { res = append(res, convertWallet(wallet)) } return response.WriteJSON(c, fiber.StatusOK, "All wallets retrieved successfully", res, nil) } // GetAllBranchWallets godoc // @Summary Get all branch wallets // @Description Retrieve all branch wallets // @Tags wallet // @Accept json // @Produce json // @Success 200 {array} WalletRes // @Failure 400 {object} response.APIResponse // @Failure 500 {object} response.APIResponse // @Router /branchWallet [get] func (h *Handler) GetAllBranchWallets(c *fiber.Ctx) error { wallets, err := h.walletSvc.GetAllBranchWallets(c.Context()) if err != nil { h.logger.Error("Failed to get wallets", "error", err) return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve wallets", err, nil) } var res []BranchWalletRes = make([]BranchWalletRes, 0, len(wallets)) for _, wallet := range wallets { res = append(res, BranchWalletRes{ ID: wallet.ID, Balance: wallet.Balance.Float64(), IsActive: wallet.IsActive, Name: wallet.Name, Location: wallet.Location, BranchManagerID: wallet.BranchManagerID, CompanyID: wallet.CompanyID, IsSelfOwned: wallet.IsSelfOwned, UpdatedAt: wallet.UpdatedAt, CreatedAt: wallet.CreatedAt, }) } return response.WriteJSON(c, fiber.StatusOK, "All Wallets retrieved", res, nil) } type UpdateWalletActiveReq struct { IsActive bool `json:"is_active" validate:"required" example:"true"` } // 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 (h *Handler) UpdateWalletActive(c *fiber.Ctx) error { walletID := c.Params("id") id, err := strconv.ParseInt(walletID, 10, 64) if err != nil { h.logger.Error("Invalid wallet ID", "walletID", walletID, "error", err) return fiber.NewError(fiber.StatusBadRequest, "Invalid wallet ID") } var req UpdateWalletActiveReq if err := c.BodyParser(&req); err != nil { h.logger.Error("Failed to parse UpdateWalletActive request", "error", err) return fiber.NewError(fiber.StatusBadRequest, "Invalid request body") } if valErrs, ok := h.validator.Validate(c, req); !ok { return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil) } err = h.walletSvc.UpdateWalletActive(c.Context(), id, req.IsActive) if err != nil { h.logger.Error("Failed to update wallet active status", "walletID", id, "error", err) return fiber.NewError(fiber.StatusInternalServerError, "Failed to update wallet") } 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 (h *Handler) GetCustomerWallet(c *fiber.Ctx) error { userID, ok := c.Locals("user_id").(int64) if !ok || userID == 0 { h.logger.Error("Invalid user ID in context") return fiber.NewError(fiber.StatusUnauthorized, "Invalid user identification") } role, ok := c.Locals("role").(domain.Role) if !ok { h.logger.Error("Invalid role in context", "userID", userID) return fiber.NewError(fiber.StatusUnauthorized, "Invalid role") } if role != domain.RoleCustomer { h.logger.Error("Unauthorized access", "userID", userID, "role", role) return fiber.NewError(fiber.StatusUnauthorized, "Unauthorized access") } companyID, err := strconv.ParseInt(c.Get("company_id"), 10, 64) if err != nil { h.logger.Error("Invalid company_id header", "value", c.Get("company_id"), "error", err) return fiber.NewError(fiber.StatusBadRequest, "Invalid company_id") } h.logger.Info("Fetching customer wallet", "userID", userID, "companyID", companyID) wallet, err := h.walletSvc.GetCustomerWallet(c.Context(), userID, companyID) if err != nil { h.logger.Error("Failed to get customer wallet", "userID", userID, "companyID", companyID, "error", err) return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve wallet") } res := convertCustomerWallet(wallet) return response.WriteJSON(c, fiber.StatusOK, "Wallet retrieved successfully", res, nil) }