const Comment = require("../models/tokenComment.model");
const User = require("../models/user.model");

const PostComment = async (req, res) => {
  try {
    const authorId = req.user.userId;
    const { content, tokenId, parentId } = req.body;

    if (!tokenId || !authorId || !content) {
      return res
        .status(400)
        .json({ error: "tokenId, authorId, and content are required." });
    }

    const comment = new Comment({
      tokenId,
      content,
      authorId,
      parentId: parentId || null,
    });

    await comment.save();

    res.status(201).json(comment);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
};

const GetComment = async (req, res) => {
  try {
    const { tokenId } = req.params;

    const comments = await Comment.find({ tokenId })
      .populate("authorId", "username profileImage")
      .lean();

    const commentMap = {};
    comments.forEach((comment) => {
      comment.replies = [];
      commentMap[comment._id] = comment;
    });

    const rootComments = [];
    comments.forEach((comment) => {
      if (comment.parentId) {
        commentMap[comment.parentId]?.replies.push(comment);
      } else {
        rootComments.push(comment);
      }
    });

    res.json(rootComments);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
};

const ReactComment = async (req, res) => {
  const authorId = req.user.userId;

  const { type } = req.body;
  const comment = await Comment.findById(req.params.id);
  if (!comment) return res.status(404).json({ error: "Comment not found" });

  if (type === "like") comment.dislikes.pull(authorId);
  else comment.likes.pull(authorId);

  const list = type === "like" ? comment.likes : comment.dislikes;
  const hasReacted = list.some((id) => id.equals(authorId));

  if (hasReacted) {
    list.pull(authorId);
  } else {
    list.push(authorId);
  }
  await comment.save();
  res.json(comment);
};

const DeleteComment = async (req, res) => {
  const authorId = req.user.userId;
  const comment = await Comment.findById(req.params.id);
  if (!comment) return res.status(404).json({ error: "Comment not found" });
  if (String(comment.authorId) !== authorId)
    return res.status(403).json({ error: "Not allowed" });

  await Comment.deleteOne({ _id: req.params.id });
  res.json({ success: true });
};

const EditComment = async (req, res) => {
  const authorId = req.user.userId;
  const { content } = req.body;
  if (!content) return res.status(400).json({ error: "Content is required" });
  const comment = await Comment.findById(req.params.id);
  if (!comment) return res.status(404).json({ error: "Comment not found" });
  if (String(comment.authorId) !== authorId)
    return res.status(403).json({ error: "Not allowed" });

  comment.content = content;
  await comment.save();
  res.json(comment);
};

module.exports = {
  PostComment,
  GetComment,
  ReactComment,
  DeleteComment,
  EditComment,
};
