const express = require("express");
const Comment = require("../models/Comment");
const Post = require("../models/Post");
const auth = require("../middleware/auth");
const { paginate, buildPaginatedResponse } = require("../middleware/pagination");
const { asyncHandler } = require("../middleware/errorHandler");

const router = express.Router();

/**
 * GET /api/posts/:postId/comments
 * Get all comments for a post (paginated)
 */
router.get(
  "/:postId/comments",
  paginate,
  asyncHandler(async (req, res) => {
    const { postId } = req.params;
    const { skip, limit, page } = req.pagination;

    // Verify post exists
    const post = await Post.findById(postId);
    if (!post) {
      return res.status(404).json({ msg: "Post not found" });
    }

    // Get comments with pagination
    const comments = await Comment.findByPostId(postId, { skip, limit });

    const totalCount = await Comment.countDocuments({ "post.postId": postId });

    res.json(buildPaginatedResponse(comments, totalCount, page, limit));
  })
);

/**
 * POST /api/posts/:postId/comments
 * Create a new comment on a post
 */
router.post(
  "/:postId/comments",
  auth,
  asyncHandler(async (req, res) => {
    const { postId } = req.params;
    const { content } = req.body;

    try {
      // Validate content
      await Comment.validateContent(content);

      // Verify post exists
      const post = await Post.findById(postId);
      if (!post) {
        return res.status(404).json({ msg: "Post not found" });
      }

      // Create comment
      const comment = await Comment.create({
        user: req.user.id,
        post: postId,
        content,
      });

      // Emit SSE event for new comment
      const sse = req.app.get("sse");
      if (sse) {
        sse.broadcastToTopic(`post_${postId}`, "newComment", {
          postId,
          comment,
        });
      }

      res.status(201).json(comment);
    } catch (error) {
      if (error.message.includes("required") || error.message.includes("characters")) {
        return res.status(400).json({ msg: error.message });
      }
      throw error;
    }
  })
);

/**
 * DELETE /api/posts/:postId/comments/:commentId
 * Delete own comment
 */
router.delete(
  "/:postId/comments/:commentId",
  auth,
  asyncHandler(async (req, res) => {
    const { postId, commentId } = req.params;

    // Find comment
    const comment = await Comment.findById(commentId);
    if (!comment) {
      return res.status(404).json({ msg: "Comment not found" });
    }

    // Verify comment belongs to the post
    const belongsToPost = await Comment.belongsToPost(commentId, postId);
    if (!belongsToPost) {
      return res.status(400).json({ msg: "Comment does not belong to this post" });
    }

    // Verify user owns the comment
    const isOwnedByUser = await Comment.isOwnedByUser(commentId, req.user.id);
    if (!isOwnedByUser) {
      return res.status(403).json({ msg: "Not authorized to delete this comment" });
    }

    // Delete comment
    await Comment.deleteComment(commentId);

    // Emit SSE event for deleted comment
    const sse = req.app.get("sse");
    if (sse) {
      sse.broadcastToTopic(`post_${postId}`, "commentDeleted", {
        postId,
        commentId,
      });
    }

    res.json({ msg: "Comment deleted successfully" });
  })
);

module.exports = router;
