using Common.Library; using CommunityToolkit.Maui; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using GreadyPoang.DataLayer; using GreadyPoang.EntityLayer; using GreadyPoang.Services; using System.Collections.ObjectModel; using System.Diagnostics; using System.Windows.Input; namespace GreadyPoang.ViewModelLayer; public partial class RoundRunningViewModel : ObservableObject { public event EventHandler RebuildRequested; public ICommand OnLoadedCommand { get; } public RoundRunningViewModel() : base() { } public RoundRunningViewModel( IRepository roundsRepo, IRepository pointsRepo, IMethodSharingService sharingService, ICombinedRepository combined, IObjectMessageService objectMessage, IPopupService popupService, IPopupEventHub popupEvent ) : base() { _roundsRepo = roundsRepo; _pointsRepo = pointsRepo; _sharingService = sharingService; _combined = combined; _objectMessage = objectMessage; _popupService = popupService; _popupEvent = popupEvent; RoundElements = new ObservableCollection(); BuilderObject = new(); _popupEvent.InfoPopupCloseRequested += infoPopupViewModel_ClosePopupRequested; //PopupVisad = false; OnLoadedCommand = new AsyncRelayCommand(OnLoadedAsync, () => true); } private readonly IRepository? _roundsRepo; private readonly IRepository _pointsRepo; private readonly IMethodSharingService _sharingService; private readonly ICombinedRepository _combined; private readonly IObjectMessageService _objectMessage; private readonly IPopupService _popupService; private readonly IPopupEventHub _popupEvent; [ObservableProperty] private ObservableCollection roundElements; [ObservableProperty] private Collection playerColumns; [ObservableProperty] private RoundBuilderElement builderObject; public ObservableCollection ScoreColumns { get; } = new ObservableCollection(); private string _activePopupId; //public bool PopupVisad { get; set; } private async Task OnLoadedAsync() { await Get(); } public async Task Get() { if (_objectMessage.CurrentGroup != null) { //CurrentGroup är satt från RoundStarting ViewModel Debug.WriteLine($"Chosen round: {_objectMessage.CurrentGroup.GameRoundId}"); if (RoundElements.Count > 0) { RoundElements.Clear(); } foreach (var item in _objectMessage.CurrentGroup.Elements) { RoundElements.Add(item); } BuilderObject.Status = _objectMessage.CurrentGroup.Status; UpdateAndShow(); } } [RelayCommand] private void StoreAndHandlePointsAsync() { var game = _roundsRepo.Get(BuilderObject.GameRoundId).GetAwaiter().GetResult(); var regNr = RoundElements.Count > 0 ? RoundElements.Max(e => e.GameRoundRegNr) + 1 : 1; if (game.GameStatus == GamePointStatus.New) { game.GameStatus = GamePointStatus.InProgress; regNr = regNr == 0 ? 1 : regNr; _roundsRepo.Save(game); } BuilderObject.Status = game.GameStatus; var points = BuilderObject.GameRegPoints; var newPoint = new GamePoint { ParticipantId = BuilderObject.ParticipantId, GameRoundId = BuilderObject.GameRoundId, GameDate = DateTime.Now, GameRoundRegNr = regNr, GameRegPoints = points }; var pointId = _pointsRepo?.Save(newPoint).GetAwaiter().GetResult(); // Uppdatera listan med element var tmpElements = _combined.roundBuilderElementsDbById(BuilderObject.GameRoundId); RoundElements.Clear(); foreach (var item in tmpElements) { item.Status = GamePointStatus.InProgress; RoundElements.Add(item); } BuilderObject.GameRegPoints = 0; UpdateAndShow(); Shell.Current.GoToAsync("..").GetAwaiter().GetResult(); } private int nextPlayerElement() { for (int i = 0; i < RoundElements.Count; i++) { if (RoundElements[i].GameRoundRegNr == -1 || (i > 0 && (RoundElements[i - 1].GameRoundRegNr > RoundElements[i].GameRoundRegNr)) || (i == 0 && RoundElements[i].GameRoundRegNr < RoundElements[RoundElements.Count - 1].GameRoundRegNr)) return i; } return -1; } private void UpdateAndShow() { // Räkna ut vem som är nästa spelare var nxt = nextPlayerElement(); // Aktuell spelare sätts som BuilderObject BuilderObject.ParticipantName = _objectMessage.CurrentGroup.Elements[nxt].ParticipantName; BuilderObject.ParticipantId = _objectMessage.CurrentGroup.Elements[nxt].ParticipantId; BuilderObject.GameRoundId = _objectMessage.CurrentGroup.GameRoundId; // Alla poängposter från samtliga spelare i rundan samlas ihop och fördelas per deltagare var localElements = _combined.roundBuilderElementsTotalById(_objectMessage.CurrentGroup.GameRoundId); FillupResultTable(localElements); // Fix for CS8602: Add null check before dereferencing FirstOrDefault result foreach (var col in PlayerColumns) { var roundElement = RoundElements.FirstOrDefault(e => e.ParticipantId == col.PlayerId); if (roundElement != null) { roundElement.GameRegPoints = col.PlayerPoints; } } // Fix for MVVMTK0034: Use the generated property 'PlayerColumns' instead of the backing field 'playerColumns' BuildScore(PlayerColumns); } private void Show_a_Popup(string ppName, string ppTitle, string ppMessage) { //if (!PopupVisad) //{ var queryAttributes = new Dictionary { [nameof(InfoPopupViewModel.Title)] = ppTitle, [nameof(InfoPopupViewModel.Message)] = ppMessage, [nameof(InfoPopupViewModel.Name)] = ppName, }; _popupService.ShowPopup( Shell.Current, options: PopupOptions.Empty, shellParameters: queryAttributes); _activePopupId = LatestPopup.valueGuid; //} } private async void infoPopupViewModel_ClosePopupRequested(object? sender, PopupCloseEventArgs e) { if (e.PopupId != _activePopupId) { return; } //PopupVisad = true; await _popupService.ClosePopupAsync(Shell.Current); } private void FillupResultTable(IEnumerable elements) { if (PlayerColumns != null) { PlayerColumns.Clear(); } else { PlayerColumns = new Collection(); } // if (elements.Any(g => g.GameRegPoints > 0)) if (BuilderObject.Status == GamePointStatus.InProgress) { PlayerColumn player = new PlayerColumn(); var regMax = elements.Max(e => e.GameRoundRegNr); var existingWinning = elements.FirstOrDefault(e => e.Status == GamePointStatus.Winning); foreach (var element in elements) { player = PlayerColumns.FirstOrDefault(p => p.PlayerId == element.ParticipantId)!; if (player == null) { player = new PlayerColumn { PlayerName = element.ParticipantName, PlayerId = element.ParticipantId, PlayerPoints = 0 }; } if (element.GameRegPoints > 0) { player.Values.Add(element.GameRegPoints.ToString()); var playerPointsOld = player.PlayerPoints; player.PlayerPoints += element.GameRegPoints; if (player.PlayerPoints > 10000) { HandlePlayerReachedWinningThreshold(player, regMax, element, playerPointsOld, existingWinning); } } if (!PlayerColumns.Contains(player)) { PlayerColumns.Add(player); } } } else { Random slumper = new Random(); foreach (var element in elements) { var player = new PlayerColumn { PlayerName = element.ParticipantName, PlayerId = element.ParticipantId, PlayerPoints = 0 }; for (int i = 0; i < slumper.Next(6); i++) { player.Values.Add(slumper.Next(1, 10).ToString()); } PlayerColumns.Add(player); } } } private void HandlePlayerReachedWinningThreshold( PlayerColumn player, int regMax, RoundBuilderElement element, int playerPointsOld, RoundBuilderElement existingWinning ) { var nextPlayer = RoundElements[AfterNext()].ParticipantName; Debug.WriteLine($"Spelare {nextPlayer} samma som {player.PlayerName} ???."); if (existingWinning != null && existingWinning.ParticipantId != player.PlayerId) { // Det finns redan en vinnare, sätt dennes status tillbaka till InProgress existingWinning.Status = GamePointStatus.InProgress; } // Om det redan finns en vinnare, sätt dennes status tillbaka till InProgress, kanske var winner = RoundElements.FirstOrDefault(e => e.ParticipantId == player.PlayerId); var oldStatus = winner.Status; winner.Status = GamePointStatus.Winning; if (playerPointsOld < 10000 && oldStatus != winner.Status && regMax == element.GameRoundRegNr) { //PopupVisad = false; Show_a_Popup( player.PlayerName, "Se upp för denne spelare !", $"Du har nått en poängnivå över 10000 ({player.PlayerPoints})\r" + $"Alla övriga får nu en chans att överträffa\r" + $"om någon kommer till samma poäng som\r" + $"{player.PlayerName}\r" + $"får hen försvara sig med nytt kast\r" + $"Om kastet inte blir godkänt (ger poäng)\r" + $"Vinner den upphinnande spelaren" ); } } private int AfterNext() { var comingUp = nextPlayerElement(); if (RoundElements.Count - 1 == comingUp) { return 0; } return comingUp; } public void BuildScore(IEnumerable columns) { ScoreColumns.Clear(); foreach (var column in columns) { var scoreColumn = new ScoreColumn { PlayerName = column.PlayerName }; scoreColumn.Cells.Add(new ScoreCell { Text = column.PlayerName, IsHeader = true }); foreach (var value in System.Linq.Enumerable.Reverse(column.Values)) { scoreColumn.Cells.Add(new ScoreCell { Text = value, IsHeader = false }); } ScoreColumns.Add(scoreColumn); } } }