private void ProcessNewPlayer(Game game)
        {
            var filteredPlayers = game.SortedPlayersByRating
                                  .Where(x => game.RequestedPlayers.All(y => x.Player.Id != y.Player.Id))
                                  .Where(x => game.AcceptedPlayers.All(y => x.Player.Id != y.Id))
                                  .Where(x => game.RejectedPlayers.All(y => x.Player.Id != y.Id));

            if (game.AcceptedPlayers.Concat(game.RequestedPlayers.Select(y => y.Player)).Count(y => y.IsGoalkeeper) >= 2)
            {
                filteredPlayers = filteredPlayers.Where(x => x.Player.IsGoalkeeper == false);
            }

            var nextPlayer = filteredPlayers.OrderBy(x => x.OrderNumber).FirstOrDefault();

            if (nextPlayer != null)
            {
                var timeoutTime = DateTime.Now.Add(_serviceConfiguration.InviteTime, _serviceConfiguration.StartDayTime,
                                                   _serviceConfiguration.EndDayTime);
                var playerGameAcceptanceTimeoutEventMetadata = new PlayerGameAcceptanceTimeoutEventMetadata()
                {
                    GameId   = game.Id,
                    PlayerId = nextPlayer.Player.Id
                };
                _scheduler.AddEvent(playerGameAcceptanceTimeoutEventMetadata, timeoutTime);
                game.RequestedPlayers.Add(new PlayerEvent()
                {
                    Id = Guid.NewGuid(), EventTime = timeoutTime, Player = nextPlayer.Player
                });

                _userInteractionService.StartGameConfirmationDialog(nextPlayer.Player,
                                                                    nextPlayer.Player.User.UserAccounts.Select(x => _communicatorFactory.GetCommunicator(x)).ToList(),
                                                                    game.Id);
            }
        }
        public Task <Unit> Handle(ScheduleGameRequest request, CancellationToken cancellationToken)
        {
            using (_threadContextSessionProvider.CreateSessionScope())
            {
                _logger.Trace($"Schedule game at {request.DateTime}");
                var game = new Game()
                {
                    DateTime = request.DateTime,
                    IsActive = true
                };
                game.MarkAsNew();
                _gameRepository.Save(game);
                _scheduler.AddEvent(new PrimaryCollectingEventMetadata()
                {
                    GameId = game.Id
                },
                                    request.DateTime.Subtract(_configuration.StartGameProcess, _configuration.StartDayTime,
                                                              _configuration.EndDayTime));

                _scheduler.AddEvent(new DistributionByTeamsEventMetadata()
                {
                    GameId = game.Id
                },
                                    request.DateTime.Subtract(_configuration.GameScheduleThreshold, _configuration.StartDayTime,
                                                              _configuration.EndDayTime));
                _scheduler.AddEvent(new PlayersCollectingDeadlineEventMetadata()
                {
                    GameId = game.Id
                },
                                    request.DateTime.Subtract(_configuration.GameDeadline, _configuration.StartDayTime,
                                                              _configuration.EndDayTime));


                _logger.Trace($"Game date - {request.DateTime}");
                return(Unit.Task);
            }
        }
        private PlayerEvent RequestPlayer(SortedPlayer requestedPlayer, Guid gameId)
        {
            var timeoutTime = DateTime.Now.Add(_serviceConfiguration.FirstInviteTime, _serviceConfiguration.StartDayTime,
                                               _serviceConfiguration.EndDayTime);
            var playerGameAcceptanceTimeoutEventMetadata = new PlayerGameAcceptanceTimeoutEventMetadata()
            {
                GameId   = gameId,
                PlayerId = requestedPlayer.Player.Id
            };

            _scheduler.AddEvent(playerGameAcceptanceTimeoutEventMetadata, timeoutTime);

            _userInteractionService.StartGameConfirmationDialog(requestedPlayer.Player, requestedPlayer.Player.User.UserAccounts.Select(x => _communicatorFactory.GetCommunicator(x)).ToList(), gameId);

            return(new PlayerEvent()
            {
                Id = Guid.NewGuid(), EventTime = timeoutTime, Player = requestedPlayer.Player
            });
        }