package service import ( "context" "fmt" "apskel-pos-be/internal/models" "apskel-pos-be/internal/processor" "github.com/google/uuid" ) type SpinGameService interface { PlaySpinGame(ctx context.Context, customerID string, req *models.SpinGameRequest) (*models.SpinGameResponse, error) } type spinGameService struct { gamePlayProcessor *processor.GamePlayProcessor } func NewSpinGameService(gamePlayProcessor *processor.GamePlayProcessor) SpinGameService { return &spinGameService{ gamePlayProcessor: gamePlayProcessor, } } func (s *spinGameService) PlaySpinGame(ctx context.Context, customerID string, req *models.SpinGameRequest) (*models.SpinGameResponse, error) { // Validate customer ID if customerID == "" { return nil, fmt.Errorf("customer ID is required") } // Parse spin ID to UUID spinID, err := uuid.Parse(req.SpinID) if err != nil { return nil, fmt.Errorf("invalid spin ID format: %w", err) } // Parse customer ID to UUID customerUUID, err := uuid.Parse(customerID) if err != nil { return nil, fmt.Errorf("invalid customer ID format: %w", err) } // PlayGame runs its own transaction and charges the game's coin_cost in EnakCoin. playResponse, err := s.gamePlayProcessor.PlayGame(ctx, &models.PlayGameRequest{ GameID: spinID, CustomerID: customerUUID, }) if err != nil { return nil, fmt.Errorf("failed to play spin game: %w", err) } // Convert prize to customer-facing format var customerPrize *models.CustomerGamePrizeResponse if playResponse.PrizeWon != nil { customerPrize = &models.CustomerGamePrizeResponse{ ID: playResponse.PrizeWon.ID, GameID: playResponse.PrizeWon.GameID, Name: playResponse.PrizeWon.Name, Image: playResponse.PrizeWon.Image, Metadata: &playResponse.PrizeWon.Metadata, CreatedAt: playResponse.PrizeWon.CreatedAt, UpdatedAt: playResponse.PrizeWon.UpdatedAt, } } // Convert to spin game response response := &models.SpinGameResponse{ Status: "SUCCESS", Message: "Spin game completed successfully.", Data: &models.SpinGameResponseData{ GamePlay: playResponse.GamePlay, PrizeWon: customerPrize, CoinsRemaining: playResponse.CoinsRemaining, }, } return response, nil }