public async Task <IActionResult> CreateCommentForPost([FromRoute(Name = "id")] int postId, [FromBody] Comment comment)
        {
            if (postId != comment.PostId)
            {
                return(BadRequest(new { Err = "You are creating a comment for the wrong post!" }));
            }

            // verify the current user
            int _userId = int.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier));

            comment.UserId    = _userId;
            comment.Timestamp = DateTimeOffset.UtcNow;
            DbContext.Add(comment);
            await DbContext.SaveChangesAsync();

            await DbContext.Entry(comment)
            .Reference(c => c.User)
            .Query()
            .Include(u => u.AvatarPhoto)
            .LoadAsync();

            var url = Url.Action("GetCommentById", "Comment", new { id = comment.Id });

            return(Created(url, ResponseModelFactory.Create(comment)));
        }
        public async Task <IActionResult> MakeFollowRelationship([FromRoute] string username,
                                                                 [FromQuery(Name = "f")] string followedUser)
        {
            if (username == followedUser)
            {
                return(BadRequest(new { Err = "Cannot follow yourself!" }));
            }

            string jwtUsername = User.FindFirstValue(ClaimTypes.Name);

            if (jwtUsername != username)
            {
                return(BadRequest(new { Err = "You cannot make follows on others' accounts!" }));
            }
            var user = await DbContext.Users.SingleOrDefaultAsync(u => u.Username == username);

            var userToBeFollowed = await DbContext.Users.SingleOrDefaultAsync(u => u.Username == followedUser);

            if (userToBeFollowed is null)
            {
                return(BadRequest(new { Err = "Followed user does not exists!" }));
            }

            // make follows
            Follow retrievedFollow = await DbContext.Follows
                                     .Where(f => f.FollowerId == user.Id &&
                                            f.UserId == userToBeFollowed.Id)
                                     .FirstOrDefaultAsync();

            if (retrievedFollow is null)
            {
                retrievedFollow = new Follow()
                {
                    FollowerId = user.Id,
                    UserId     = userToBeFollowed.Id,
                    IsActive   = true
                };
                DbContext.Add(retrievedFollow);
            }
            else
            {
                if (retrievedFollow.IsActive.Value)
                {
                    return(BadRequest(new { Err = "Already followed!" }));
                }
                DbContext.Entry(retrievedFollow).CurrentValues.SetValues(new { IsActive = true });
            }

            await DbContext.SaveChangesAsync();

            return(Ok(new
            {
                retrievedFollow.Follower.Id,
                retrievedFollow.Follower.Username,
                Type = "following",
                Link = $"/users/{retrievedFollow.Follower.Username}"
            }));
        }
        public async Task <IActionResult> CreatePost([FromForm] string caption,
                                                     [FromForm] IList <IFormFile> uploads,
                                                     [FromRoute] string username)
        {
            if (uploads.Count <= 0)
            {
                return(BadRequest(new { Err = "Cannot create a post without any photo!" }));
            }

            // validate user
            var user = await DbContext.Users.SingleOrDefaultAsync(u => u.Username == username);

            if (user is null)
            {
                return(BadRequest(new { Err = "Unauthorized user!" }));
            }

            var transaction = DbContext.Database.BeginTransaction();

            // create post content
            var post = new Post()
            {
                Caption = caption,
                UserId  = user.Id,
                Created = DateTimeOffset.UtcNow
            };

            DbContext.Add(post);
            await DbContext.SaveChangesAsync();

            post = await DbContext.Posts
                   .Include(p => p.User).ThenInclude(u => u.AvatarPhoto)
                   .Where(p => p.Id == post.Id)
                   .FirstOrDefaultAsync();

            // create file uploads
            var uploadedFiles = uploads.Select(async upload => await PhotoUtils.UploadPhotoAsync(upload, PhotoServingPath))
                                .Select(task => task.Result)
                                .Select(fileName => new Photo()
            {
                PostId   = post.Id,
                FileName = fileName
            });

            DbContext.AddRange(uploadedFiles);
            await DbContext.SaveChangesAsync();

            await transaction.CommitAsync();

            return(Created(Url.Action("GetPostById", "Post", new { id = post.Id }), ResponseModelFactory.Create(post)));
        }
        public async Task <IActionResult> CreateLikeReactionForPost([FromRoute(Name = "id")] int postId)
        {
            int userId = int.Parse(HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value);

            // check if any exists
            var retrievedLike = await DbContext.Likes.Include(l => l.User).ThenInclude(u => u.AvatarPhoto)
                                .Include(l => l.LikedPostNavigation)
                                .FirstOrDefaultAsync(l =>
                                                     l.UserId == userId && l.LikedPost == postId);

            if (retrievedLike is null)
            {
                retrievedLike = new Like()
                {
                    LikedPost = postId,
                    UserId    = userId,
                    IsActive  = true
                };
                DbContext.Add(retrievedLike);
            }
            else
            {
                if (retrievedLike.IsActive.Value)
                {
                    return(Ok(ResponseModelFactory.Create(retrievedLike)));
                }
            }
            DbContext.Entry(retrievedLike).CurrentValues.SetValues(new { IsActive = true });
            await DbContext.SaveChangesAsync();

            await DbContext.Entry(retrievedLike).GetDatabaseValuesAsync();

            await DbContext.Entry(retrievedLike)
            .Reference(l => l.User)
            .Query()
            .Include(u => u.AvatarPhoto)
            .LoadAsync();

            return(Ok(ResponseModelFactory.Create(retrievedLike)));
        }