2020using Hearthstone_Deck_Tracker . Utility . Logging ;
2121using Hearthstone_Deck_Tracker . Utility . MVVM ;
2222using Hearthstone_Deck_Tracker . Utility . RemoteData ;
23+ using Hearthstone_Deck_Tracker . Commands ;
2324using HSReplay . Requests ;
2425using HSReplay . Responses ;
2526using Newtonsoft . Json ;
2627using static Hearthstone_Deck_Tracker . Utility . Battlegrounds . BattlegroundsLastGames ;
28+ using System . Windows . Input ;
2729
2830namespace Hearthstone_Deck_Tracker . Controls . Overlay . Battlegrounds . Session ;
2931
3032public class BattlegroundsSessionViewModel : ViewModel
3133{
3234 private readonly BattlegroundsDb _db = BattlegroundsDbSingleton . Instance ;
3335
36+ public BattlegroundsSessionViewModel ( )
37+ {
38+ RetryCompStatsCommand = new Command ( async ( ) => await RetryCompStats ( ) ) ;
39+ }
40+
3441 public ObservableCollection < Race > AvailableMinionTypes { get ; } = new ( ) ;
3542 public ObservableCollection < Race > BannedMinionTypes { get ; } = new ( ) ;
3643 public ObservableCollection < BattlegroundsGameViewModel > SessionGames { get ; } = new ( ) ;
@@ -50,6 +57,8 @@ public void OnGameEnd()
5057
5158 private readonly SemaphoreSlim _updateCompStatsSemaphore = new SemaphoreSlim ( 1 , 1 ) ;
5259
60+ public ICommand RetryCompStatsCommand { get ; }
61+
5362
5463 public async void Update ( )
5564 {
@@ -187,6 +196,20 @@ private void UpdateMinionTypes()
187196
188197 var availableRaces = BattlegroundsUtils . GetAvailableRaces ( ) ;
189198
199+ // Retry logic: game state may not be ready immediately
200+ if ( availableRaces == null )
201+ {
202+ Log . Info ( "[Tier7CompStats] Available races not ready, retrying after delay..." ) ;
203+ await Task . Delay ( 2000 ) ;
204+ availableRaces = BattlegroundsUtils . GetAvailableRaces ( ) ;
205+
206+ if ( availableRaces == null )
207+ {
208+ await Task . Delay ( 3000 ) ;
209+ availableRaces = BattlegroundsUtils . GetAvailableRaces ( ) ;
210+ }
211+ }
212+
190213 if ( availableRaces == null )
191214 throw new CompositionStatsException ( "Unable to get available races" ) ;
192215
@@ -288,18 +311,28 @@ private async Task TrySetCompStats()
288311 catch ( Exception e )
289312 {
290313 HandleCompStatsError ( e ) ;
314+ return ;
291315 }
292316
293317 if ( battlegroundsCompStats is BattlegroundsCompStats compStats )
294318 {
295319 var firstPlaceComps = compStats . Data ? . FirstPlaceCompsLobbyRaces ;
296- if ( firstPlaceComps != null )
320+ if ( firstPlaceComps != null && firstPlaceComps . Count > 0 )
297321 {
322+ Log . Info ( $ "[Tier7CompStats] Success: received { firstPlaceComps . Count } compositions") ;
298323 SetBattlegroundsCompositionStatsViewModel (
299324 firstPlaceComps
300325 ) ;
301326 ShowCompositionStats ( ) ;
302327 }
328+ else
329+ {
330+ Log . Warn ( $ "[Tier7CompStats] API returned null or empty compositions. compStats.Data={ compStats . Data } , firstPlaceComps.Count={ firstPlaceComps ? . Count ?? 0 } ") ;
331+ }
332+ }
333+ else
334+ {
335+ Log . Warn ( $ "[Tier7CompStats] Received null from API") ;
303336 }
304337 }
305338
@@ -315,6 +348,7 @@ public void HideCompStatsOnError()
315348 private void HandleCompStatsError ( Exception error )
316349 {
317350 Influx . OnGetBattlegroundsCompositionStatsError ( error . GetType ( ) . Name , error . Message ) ;
351+ Log . Error ( $ "[Tier7CompStats] error: { error . GetType ( ) . Name } - { error . Message } ; debug={ CompStatsDebugInfo ?? "<none>" } ") ;
318352
319353 var beforeHeroPicked = ( Core . Game . GameEntity ? . GetTag ( GameTag . STEP ) ?? 0 ) <= ( int ) Step . BEGIN_MULLIGAN ;
320354 if ( ! beforeHeroPicked )
@@ -332,6 +366,23 @@ private void HandleCompStatsError(Exception error)
332366 CompStatsWaitingMsgVisibility = Visibility . Hidden ;
333367 }
334368
369+ private async Task RetryCompStats ( )
370+ {
371+ CompStatsErrorVisibility = Visibility . Hidden ;
372+ CompStatsBodyVisibility = Visibility . Hidden ;
373+ CompStatsWaitingMsgVisibility = Visibility . Visible ;
374+
375+ try
376+ {
377+ await _updateCompStatsSemaphore . WaitAsync ( ) ;
378+ await TrySetCompStats ( ) ;
379+ }
380+ finally
381+ {
382+ _updateCompStatsSemaphore . Release ( ) ;
383+ }
384+ }
385+
335386 private async Task < GameItem ? > UpdateLatestGames ( )
336387 {
337388 var sortedGames = ( await Instance . PlayerGames ( IsDuos ) )
@@ -529,6 +580,20 @@ public Visibility CompStatsErrorVisibility
529580 }
530581 }
531582
583+ private string ? _compStatsDebugInfo ;
584+ public string ? CompStatsDebugInfo
585+ {
586+ get => _compStatsDebugInfo ;
587+ set
588+ {
589+ _compStatsDebugInfo = value ;
590+ OnPropertyChanged ( ) ;
591+ OnPropertyChanged ( nameof ( CompStatsDebugVisibility ) ) ;
592+ }
593+ }
594+
595+ public Visibility CompStatsDebugVisibility => string . IsNullOrWhiteSpace ( _compStatsDebugInfo ) ? Visibility . Collapsed : Visibility . Visible ;
596+
532597 private Visibility _compStatsWaitingMsgVisibility ;
533598 public Visibility CompStatsWaitingMsgVisibility
534599 {
0 commit comments