public async Task <Unit> Handle(UnfollowGameCommand request, CancellationToken cancellationToken)
        {
            string currentProfileId = _userAccessor.GetCurrentProfileId();

            if (currentProfileId == null)
            {
                throw new RestException(HttpStatusCode.Forbidden, new { message = "Not authorized." });
            }

            Domain.Entities.Game game = await _dbContext.Games.FirstOrDefaultAsync(x => x.IgdbId == request.Game.Id,
                                                                                   cancellationToken : cancellationToken);

            if (game == null)
            {
                throw new RestException(HttpStatusCode.NotFound);
            }

            GameFollowing followedGame = await _dbContext.Followings.FirstOrDefaultAsync(x =>
                                                                                         x.GameId == game.Id && x.ProfileId == new Guid(currentProfileId), cancellationToken);

            if (followedGame == null)
            {
                throw new RestException(HttpStatusCode.Conflict, new { message = $"You're not following {game.Title}." });
            }

            _dbContext.Followings.Remove(followedGame);

            bool success = await _dbContext.SaveChangesAsync(cancellationToken) > 0;

            if (success)
            {
                return(Unit.Value);
            }
            throw new RestException(HttpStatusCode.InternalServerError, new { message = "An error occurred." });
        }
        public async Task <Unit> Handle(VoteGameCommand request, CancellationToken cancellationToken)
        {
            string currentProfileId = _userAccessor.GetCurrentProfileId();

            if (request.Vote <= 0 || request.Vote > 5)
            {
                throw new RestException(HttpStatusCode.Forbidden, new { message = "Rank must be between 1 and 5." });
            }

            if (currentProfileId == null)
            {
                throw new RestException(HttpStatusCode.Forbidden, new { message = "Not authorized." });
            }

            Domain.Entities.Game game = await _dbContext.Games.FirstOrDefaultAsync(x => x.IgdbId == request.Game.Id,
                                                                                   cancellationToken);

            if (game == null)
            {
                game = new Domain.Entities.Game
                {
                    Id          = Guid.NewGuid(), IgdbId = request.Game.Id, Title = request.Game.Name,
                    Description = request.Game.Summary, CoverPath = request.Game.Cover.Url
                };
                _dbContext.Games.Add(game);
            }

            GameRank gameRank = await _dbContext.Ranks.FirstOrDefaultAsync(x =>
                                                                           x.Game.IgdbId == game.IgdbId && x.ProfileId.ToString() == currentProfileId, cancellationToken);

            if (gameRank == null)
            {
                gameRank = new GameRank {
                    Game = game, ProfileId = new Guid(currentProfileId), Rank = request.Vote
                }
            }
            ;
            else if (gameRank.Rank == request.Vote)
            {
                gameRank.Rank = 0;
            }
            else
            {
                gameRank.Rank = request.Vote;
            }

            _dbContext.Ranks.Update(gameRank);

            bool success = await _dbContext.SaveChangesAsync(cancellationToken) > 0;

            if (success)
            {
                return(Unit.Value);
            }
            throw new RestException(HttpStatusCode.InternalServerError, new { message = "An error occurred." });
        }
        public async Task <Unit> Handle(FollowGameCommand request, CancellationToken cancellationToken)
        {
            string currentProfileId = _userAccessor.GetCurrentProfileId();

            if (currentProfileId == null)
            {
                throw new RestException(HttpStatusCode.Forbidden, new { message = "Not authorized." });
            }

            Domain.Entities.Game game = await _dbContext.Games.FirstOrDefaultAsync(x => x.IgdbId == request.Game.Id,
                                                                                   cancellationToken);

            if (game == null)
            {
                game = new Domain.Entities.Game
                {
                    Id          = Guid.NewGuid(), IgdbId = request.Game.Id, Title = request.Game.Name,
                    Description = request.Game.Summary, CoverPath = request.Game.Cover.Url
                };
                _dbContext.Games.Add(game);
            }

            bool alreadyFollowing = await _dbContext.Followings.FirstOrDefaultAsync(x =>
                                                                                    x.GameId == game.Id && x.ProfileId == new Guid(currentProfileId), cancellationToken) != null;

            if (alreadyFollowing)
            {
                throw new RestException(HttpStatusCode.Conflict, new { message = $"Already following {game.Title}." });
            }

            _dbContext.Followings.Add(new GameFollowing
            {
                GameId = game.Id, ProfileId = new Guid(currentProfileId)
            });

            bool success = await _dbContext.SaveChangesAsync(cancellationToken) > 0;

            if (success)
            {
                return(Unit.Value);
            }
            throw new RestException(HttpStatusCode.InternalServerError, new { message = "An error occurred." });
        }