{"size": 4298, "ext": "js", "max_stars_repo_path": "server/controllers/commentController.js", "max_stars_repo_name": "Hacktogen/Instagram-Clone", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "server/controllers/commentController.js", "max_issues_repo_name": "Hacktogen/Instagram-Clone", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "server/controllers/commentController.js", "max_forks_repo_name": "Hacktogen/Instagram-Clone", "max_forks_repo_forks_event_min_datetime": "2021-01-23T17:57:16.000Z", "max_forks_repo_forks_event_max_datetime": "2021-01-23T17:57:16.000Z"}
{"max_stars_count": null, "max_issues_count": null, "max_forks_count": 1, "avg_line_length": 29.2380952381, "max_line_length": 79, "alphanum_fraction": 0.6500697999}
const Comment = require('../models/CommentModel');
const Post = require('../models/PostModel');
const asyncHandler = require('../middlewares/async');
const ErrorResponse = require('../utils/ErrorResponse');

// sort of middleware
exports.checkPostId = asyncHandler(async (req, res, next) => {
  const post = await Post.findById(req.params.postId);
  if (!post) {
    return next(
      new ErrorResponse(`No post found with that id ${req.params.postId}`, 404)
    );
  }
  next();
});

// @route    POST api/v1/posts/:postId/:id
// @desc     create a comment
// @access   Private
exports.newComment = asyncHandler(async (req, res, next) => {
  if (!req.body.post) req.body.post = req.params.postId;
  if (!req.body.user) req.body.user = req.user._id;

  const newComment = await Comment.create(req.body);
  const post = await Post.findById(newComment.post)

  res.status(201).json({
    success: true,
    data: post,
  });
});

// @route    GET api/v1/posts/:postId/comments
// @desc     get all comments for a post
// @access   Private
exports.getAll = asyncHandler(async (req, res, next) => {
  const comments = await Comment.find();

  res.status(200).json({ success: true, data: comments });
});

// @route    GET api/v1/posts/:postId/:id
// @desc     get a comment
// @access   Private
exports.getComment = asyncHandler(async (req, res, next) => {
  const comment = await Comment.findById(req.params.id);
  if (!comment) {
    return next(
      new ErrorResponse(`No comment found with that id ${req.params.id}`, 404)
    );
  }
  res.status(200).json({ success: true, data: comment });
});

// @route    PUT api/v1/posts/like/:postId/:id
// @desc     like a comment
// @access   Private
exports.likeComment = asyncHandler(async (req, res, next) => {
  const comment = await Comment.findById(req.params.id);
  if (!comment) {
    return next(new ErrorResponse('No comment found with that id', 404));
  }
  // Check if the comment has already been liked
  if (comment.likes.includes(req.user._id)) {
    return next(new ErrorResponse('Comment already liked', 400));
  }

  const likedComment = await Comment.findByIdAndUpdate(
    req.params.id,
    { $push: { likes: req.user._id } },
    { new: true }
  );

  res.json({ success: true, data: likedComment });
});

// @route    PUT api/v1/posts/unLike/:postId/:id
// @desc     unLike a comment
// @access   Private
exports.unLikeComment = asyncHandler(async (req, res, next) => {
  const comment = await Comment.findById(req.params.id);
  if (!comment) {
    return next(new ErrorResponse('No comment found with that id', 404));
  }
  // Check if the comment has already been liked
  if (!comment.likes.includes(req.user._id)) {
    return next(new ErrorResponse('You have not liked this comment ', 400));
  }

  const likedComment = await Comment.findByIdAndUpdate(
    req.params.id,
    { $pull: { likes: req.user._id } },
    { new: true }
  );

  res.json({ success: true, data: likedComment });
});

// @route    PUT api/v1/posts/:postId/:id
// @desc     update a comment
// @access   Private
exports.updateComment = asyncHandler(async (req, res, next) => {
  const comment = await Comment.findByIdAndUpdate(req.params.id, req.body, {
    new: true,
    runValidators: true,
  });

  if (!comment) {
    return next(
      new ErrorResponse(`No comment found with id ${req.params.id}`, 404)
    );
  }
  res.status(200).json({ success: true, data: comment });
});

// @route    DELETE api/v1/posts/:postId/:id
// @desc     delete a comment
// @access   Private
exports.deleteComment = asyncHandler(async (req, res, next) => {
  const comment = await Comment.findById(req.params.id);
  if (!comment) {
    return next(
      new ErrorResponse(`No comment found with id ${req.params.id}`, 404)
    );
  }

  await comment.remove();

  res.status(204).json({
    success: true,
    data: null,
  });
});

// very important check
exports.checkCommentOwner = async (req, res, next) => {
  const comment = await Comment.findById(req.params.id);
  const post = await Post.findById(req.body.postId);
  if (req.user.id.toString() !== post.user.id.toString()) {
    if (comment.user.id.toString() !== req.user.id.toString())
      return next(
        new ErrorResponse(`You cannot touch someone else's comment.`, 403)
      );
  }
  next();
};
