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()) // }