import { ChangeDetectionStrategy, Component, inject, signal } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Router } from '@angular/router'; import { PlayingCardComponent } from './components/playing-card/playing-card.component'; import { DealerHandComponent } from './components/dealer-hand/dealer-hand.component'; import { PlayerHandComponent } from './components/player-hand/player-hand.component'; import { GameControlsComponent } from './components/game-controls/game-controls.component'; import { GameInfoComponent } from './components/game-info/game-info.component'; import { Card, BlackjackGame } from './models/blackjack.model'; import { BlackjackService } from './services/blackjack.service'; import { HttpErrorResponse } from '@angular/common/http'; import { GameResultComponent } from './components/game-result/game-result.component'; import { GameState } from './enum/gameState'; import { NavbarComponent } from '../../../shared/components/navbar/navbar.component'; import { UserService } from '../../../service/user.service'; @Component({ selector: 'app-blackjack', standalone: true, imports: [ CommonModule, NavbarComponent, PlayingCardComponent, DealerHandComponent, PlayerHandComponent, GameControlsComponent, GameInfoComponent, GameResultComponent, ], templateUrl: './blackjack.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export default class BlackjackComponent { private router = inject(Router); private userService = inject(UserService); private blackjackService = inject(BlackjackService); dealerCards = signal([]); playerCards = signal([]); currentBet = signal(0); balance = signal(0); currentGameId = signal(undefined); gameInProgress = signal(false); gameState = signal(GameState.IN_PROGRESS); showGameResult = signal(false); isActionInProgress = signal(false); currentAction = signal(''); constructor() { this.refreshUserBalance(); } private refreshUserBalance(): void { this.userService.getCurrentUser().subscribe((user) => { this.balance.set(user?.balance ?? 0); }); } private updateGameState(game: BlackjackGame) { console.log('Game state update:', game); this.currentGameId.set(game.id); this.currentBet.set(game.bet); this.gameInProgress.set(game.state === GameState.IN_PROGRESS); this.gameState.set(game.state as GameState); const isGameOver = game.state !== GameState.IN_PROGRESS; this.dealerCards.set( game.dealerCards.map((card, index) => ({ ...card, hidden: !isGameOver && index === 1 && game.state === GameState.IN_PROGRESS, })) ); this.playerCards.set( game.playerCards.map((card) => ({ ...card, hidden: false, })) ); if (isGameOver) { console.log('Game is over, state:', game.state); this.refreshUserBalance(); this.showGameResult.set(true); console.log('Game result dialog should be shown now'); } } onNewGame(bet: number): void { this.isActionInProgress.set(true); this.currentAction.set('Spiel wird gestartet...'); this.blackjackService.startGame(bet).subscribe({ next: (game) => { this.updateGameState(game); this.refreshUserBalance(); this.isActionInProgress.set(false); }, error: (error) => { console.error('Failed to start game:', error); this.isActionInProgress.set(false); }, }); } onHit(): void { if (!this.currentGameId() || this.isActionInProgress()) return; this.isActionInProgress.set(true); this.currentAction.set('Karte wird gezogen...'); this.blackjackService.hit(this.currentGameId()!).subscribe({ next: (game) => { this.updateGameState(game); this.isActionInProgress.set(false); }, error: (error) => { console.error('Failed to hit:', error); this.handleGameError(error); this.isActionInProgress.set(false); }, }); } onStand(): void { if (!this.currentGameId() || this.isActionInProgress()) return; if (this.gameState() !== GameState.IN_PROGRESS) { console.log('Cannot stand: game is not in progress'); return; } this.isActionInProgress.set(true); this.currentAction.set('Dealer zieht Karten...'); this.blackjackService.stand(this.currentGameId()!).subscribe({ next: (game) => { this.updateGameState(game); this.isActionInProgress.set(false); }, error: (error) => { console.error('Failed to stand:', error); this.handleGameError(error); this.isActionInProgress.set(false); }, }); } onDoubleDown(): void { if (!this.currentGameId() || this.isActionInProgress()) return; if (this.gameState() !== GameState.IN_PROGRESS || this.playerCards().length !== 2) { console.log('Cannot double down: game is not in progress or more than 2 cards'); return; } this.isActionInProgress.set(true); this.currentAction.set('Einsatz wird verdoppelt...'); this.blackjackService.doubleDown(this.currentGameId()!).subscribe({ next: (game) => { this.updateGameState(game); this.isActionInProgress.set(false); }, error: (error) => { console.error('Failed to double down:', error); this.handleGameError(error); this.isActionInProgress.set(false); }, }); } onCloseGameResult(): void { console.log('Closing game result dialog'); this.showGameResult.set(false); } private handleGameError(error: HttpErrorResponse): void { if (error instanceof HttpErrorResponse) { if (error.status === 400 && error.error?.error === 'Invalid state') { this.gameInProgress.set(false); this.refreshUserBalance(); } else if (error.status === 500) { console.log('Server error occurred. The game may have been updated in another session.'); this.gameInProgress.set(false); this.refreshUserBalance(); if (this.currentGameId()) { this.refreshGameState(this.currentGameId()!); } } } } private refreshGameState(gameId: number): void { this.blackjackService.getGame(gameId).subscribe({ next: (game) => { this.updateGameState(game); }, error: (err) => { console.error('Failed to refresh game state:', err); }, }); } leaveGame(): void { this.router.navigate(['/home']); } }