const couchdbService = require("../services/couchdbService"); class Comment { static async create(commentData) { const { user, post, content } = commentData; // Get user data for embedding const userDoc = await couchdbService.findUserById(user); if (!userDoc) { throw new Error("User not found"); } // Get post data for embedding const postDoc = await couchdbService.getById(post); if (!postDoc) { throw new Error("Post not found"); } const comment = { _id: `comment_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, type: "comment", user: { userId: user, name: userDoc.name, profilePicture: userDoc.profilePicture || "" }, post: { postId: post, content: postDoc.content, userId: postDoc.user.userId }, content: content.trim(), createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() }; const createdComment = await couchdbService.create(comment); // Update post's comment count await couchdbService.updatePost(post, { commentsCount: (postDoc.commentsCount || 0) + 1 }); return createdComment; } static async findById(commentId) { return await couchdbService.getById(commentId); } static async find(query = {}) { const couchQuery = { selector: { type: "comment", ...query } }; return await couchdbService.find(couchQuery); } static async findByPostId(postId, options = {}) { const { skip = 0, limit = 50, sort = { createdAt: -1 } } = options; const query = { selector: { type: "comment", "post.postId": postId }, sort: Object.keys(sort).map(key => [key, sort[key] === -1 ? "desc" : "asc"]), skip, limit }; return await couchdbService.find(query); } static async countDocuments(query = {}) { const couchQuery = { selector: { type: "comment", ...query }, fields: ["_id"] }; const docs = await couchdbService.find(couchQuery); return docs.length; } static async deleteComment(commentId) { const comment = await couchdbService.getById(commentId); if (!comment) { throw new Error("Comment not found"); } // Update post's comment count if (comment.post && comment.post.postId) { const postDoc = await couchdbService.getById(comment.post.postId); if (postDoc) { await couchdbService.updatePost(comment.post.postId, { commentsCount: Math.max(0, (postDoc.commentsCount || 0) - 1) }); } } return await couchdbService.delete(commentId); } static async findByUserId(userId, options = {}) { const { skip = 0, limit = 50 } = options; const query = { selector: { type: "comment", "user.userId": userId }, sort: [["createdAt", "desc"]], skip, limit }; return await couchdbService.find(query); } static async validateContent(content) { if (!content || content.trim().length === 0) { throw new Error("Comment content is required"); } if (content.length > 500) { throw new Error("Comment content must be 500 characters or less"); } return content.trim(); } // Legacy compatibility methods for mongoose-like interface static async populate(comments, fields) { // In CouchDB, user and post data are already embedded in comments // This method is for compatibility with existing code if (fields) { if (fields.includes("user") || fields.includes("post")) { // Data is already embedded, so just return comments as-is return comments; } } return comments; } // Helper method to check if comment belongs to a post static async belongsToPost(commentId, postId) { const comment = await couchdbService.getById(commentId); return comment && comment.post && comment.post.postId === postId; } // Helper method to check if user owns comment static async isOwnedByUser(commentId, userId) { const comment = await couchdbService.getById(commentId); return comment && comment.user && comment.user.userId === userId; } } module.exports = Comment;