163 lines
4.7 KiB
Go
163 lines
4.7 KiB
Go
package veli
|
|
|
|
// import (
|
|
// "context"
|
|
// "fmt"
|
|
// "log/slog"
|
|
// "time"
|
|
|
|
// "github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
|
// "github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
|
|
// "github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
|
|
// )
|
|
|
|
// type Service struct {
|
|
// client *VeliClient
|
|
// gameRepo repository.VeliGameRepository
|
|
// playerRepo repository.VeliPlayerRepository
|
|
// txRepo repository.VeliTransactionRepository
|
|
// walletSvc wallet.Service
|
|
// logger domain.Logger
|
|
// }
|
|
|
|
// func NewService(
|
|
// client *VeliClient,
|
|
// gameRepo repository.VeliGameRepository,
|
|
// playerRepo repository.VeliPlayerRepository,
|
|
// txRepo repository.VeliTransactionRepository,
|
|
// walletSvc wallet.Service,
|
|
// logger *slog.Logger,
|
|
// ) *Service {
|
|
// return &Service{
|
|
// client: client,
|
|
// gameRepo: gameRepo,
|
|
// playerRepo: playerRepo,
|
|
// txRepo: txRepo,
|
|
// walletSvc: walletSvc,
|
|
// logger: logger,
|
|
// }
|
|
// }
|
|
|
|
// func (s *Service) SyncGames(ctx context.Context) error {
|
|
// games, err := s.client.GetGameList(ctx)
|
|
// if err != nil {
|
|
// return fmt.Errorf("failed to get game list: %w", err)
|
|
// }
|
|
|
|
// for _, game := range games {
|
|
// existing, err := s.gameRepo.GetGameByID(ctx, game.ID)
|
|
// if err != nil && err != domain.ErrGameNotFound {
|
|
// return fmt.Errorf("failed to check existing game: %w", err)
|
|
// }
|
|
|
|
// if existing == nil {
|
|
// // New game - create
|
|
// if err := s.gameRepo.CreateGame(ctx, game); err != nil {
|
|
// s.logger.Error("failed to create game", "game_id", game.ID, "error", err)
|
|
// continue
|
|
// }
|
|
// } else {
|
|
// // Existing game - update
|
|
// if err := s.gameRepo.UpdateGame(ctx, game); err != nil {
|
|
// s.logger.Error("failed to update game", "game_id", game.ID, "error", err)
|
|
// continue
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// return nil
|
|
// }
|
|
|
|
// func (s *Service) LaunchGame(ctx context.Context, playerID, gameID string) (string, error) {
|
|
// // Verify player exists
|
|
// player, err := s.playerRepo.GetPlayer(ctx, playerID)
|
|
// if err != nil {
|
|
// return "", fmt.Errorf("failed to get player: %w", err)
|
|
// }
|
|
|
|
// // Verify game exists
|
|
// game, err := s.gameRepo.GetGameByID(ctx, gameID)
|
|
// if err != nil {
|
|
// return "", fmt.Errorf("failed to get game: %w", err)
|
|
// }
|
|
|
|
// // Call Veli API
|
|
// gameURL, err := s.client.LaunchGame(ctx, playerID, gameID)
|
|
// if err != nil {
|
|
// return "", fmt.Errorf("failed to launch game: %w", err)
|
|
// }
|
|
|
|
// // Create game session record
|
|
// session := domain.GameSession{
|
|
// SessionID: fmt.Sprintf("%s-%s-%d", playerID, gameID, time.Now().Unix()),
|
|
// PlayerID: playerID,
|
|
// GameID: gameID,
|
|
// LaunchTime: time.Now(),
|
|
// Status: "active",
|
|
// }
|
|
|
|
// if err := s.gameRepo.CreateGameSession(ctx, session); err != nil {
|
|
// s.logger.Error("failed to create game session", "error", err)
|
|
// }
|
|
|
|
// return gameURL, nil
|
|
// }
|
|
|
|
// func (s *Service) PlaceBet(ctx context.Context, playerID, gameID string, amount float64) (*domain.VeliTransaction, error) {
|
|
// // 1. Verify player balance
|
|
// balance, err := s.walletRepo.GetBalance(ctx, playerID)
|
|
// if err != nil {
|
|
// return nil, fmt.Errorf("failed to get balance: %w", err)
|
|
// }
|
|
|
|
// if balance < amount {
|
|
// return nil, domain.ErrInsufficientBalance
|
|
// }
|
|
|
|
// // 2. Create transaction record
|
|
// tx := domain.VeliTransaction{
|
|
// TransactionID: generateTransactionID(),
|
|
// PlayerID: playerID,
|
|
// GameID: gameID,
|
|
// Amount: amount,
|
|
// Type: "bet",
|
|
// Status: "pending",
|
|
// CreatedAt: time.Now(),
|
|
// }
|
|
|
|
// if err := s.txRepo.CreateTransaction(ctx, tx); err != nil {
|
|
// return nil, fmt.Errorf("failed to create transaction: %w", err)
|
|
// }
|
|
|
|
// // 3. Call Veli API
|
|
// if err := s.client.PlaceBet(ctx, tx.TransactionID, playerID, gameID, amount); err != nil {
|
|
// // Update transaction status
|
|
// tx.Status = "failed"
|
|
// _ = s.txRepo.UpdateTransaction(ctx, tx)
|
|
// return nil, fmt.Errorf("failed to place bet: %w", err)
|
|
// }
|
|
|
|
// // 4. Deduct from wallet
|
|
// if err := s.walletRepo.DeductBalance(ctx, playerID, amount); err != nil {
|
|
// // Attempt to rollback
|
|
// _ = s.client.RollbackBet(ctx, tx.TransactionID)
|
|
// tx.Status = "failed"
|
|
// _ = s.txRepo.UpdateTransaction(ctx, tx)
|
|
// return nil, fmt.Errorf("failed to deduct balance: %w", err)
|
|
// }
|
|
|
|
// // 5. Update transaction status
|
|
// tx.Status = "completed"
|
|
// if err := s.txRepo.UpdateTransaction(ctx, tx); err != nil {
|
|
// s.logger.Error("failed to update transaction status", "error", err)
|
|
// }
|
|
|
|
// return &tx, nil
|
|
// }
|
|
|
|
// // Implement SettleBet, RollbackBet, GetBalance, etc. following similar patterns
|
|
|
|
// func generateTransactionID() string {
|
|
// return fmt.Sprintf("tx-%d", time.Now().UnixNano())
|
|
// }
|