const Post = require('../models/postModel');
const PostAttachment = require('../models/postAttachmentsModel');
const Reaction = require('../models/reactionModel');
const User = require('../models/userModel');
const { upload } = require('../middleware/uploadMiddleware');
const path = require('path');
const fs = require('fs');
const { bool } = require('sharp');

const postController = {
    getPosts: async (req, res, next) => {
        try {
            // Get all posts
            const posts = await Post.getAll();
            
            // For each post, get attachments, reactions, and user details
            const postsWithDetails = await Promise.all(posts.map(async (post) => {
                const attachments = await PostAttachment.getByPostId(post.id);
                const reactions = await Reaction.getByPostId(post.id);
                const user = await User.findById(post.user_id);
                const approvedByUser = post.approved_by ? await User.findById(post.approved_by) : null;
                
                // Enhance reactions with user details
                const reactionsWithUsers = await Promise.all(reactions.map(async (reaction) => {
                    const reactionUser = await User.findById(reaction.user_id);
                    return {
                        ...reaction,
                        user: reactionUser ? {
                            id: reactionUser.id,
                            first_name: reactionUser.first_name,
                            last_name: reactionUser.last_name,
                            role: reactionUser.role,
                            email: reactionUser.email,
                            profile_url: reactionUser.profile_url || null
                        } : null
                    };
                }));
                
                return {
                    ...post,
                    user: user ? {
                        id: user.id,
                        first_name: user.first_name,
                        last_name: user.last_name,
                        role: user.role,
                        email: user.email,
                        profile_url: user.profile_url || null
                    } : null,
                    approved_by: approvedByUser ? {
                        id: approvedByUser.id,
                        first_name: approvedByUser.first_name,
                        last_name: approvedByUser.last_name,
                        role: approvedByUser.role,
                        email: approvedByUser.email,
                        profile_url: approvedByUser.profile_url || null
                    } : null,
                    attachments: attachments || [],
                    reactions: reactionsWithUsers || []
                };
            }));
            
            console.log(postsWithDetails)
            res.status(200).json({success:true, statusCode:200, message:"Success", data: postsWithDetails});
        } catch (error) {
            next(error);
        }
    },

    getApprovedPosts: async (req, res, next) => {
        try {
            // Get all posts
            const posts = await Post.getApprovedPosts();
            
            // For each post, get attachments, reactions, and user details
            const postsWithDetails = await Promise.all(posts.map(async (post) => {
                const attachments = await PostAttachment.getByPostId(post.id);
                const reactions = await Reaction.getByPostId(post.id);
                const user = await User.findById(post.user_id);
                const approvedByUser = post.approved_by ? await User.findById(post.approved_by) : null;
                
                // Enhance reactions with user details
                const reactionsWithUsers = await Promise.all(reactions.map(async (reaction) => {
                    const reactionUser = await User.findById(reaction.user_id);
                    return {
                        ...reaction,
                        user: reactionUser ? {
                            id: reactionUser.id,
                            first_name: reactionUser.first_name,
                            last_name: reactionUser.last_name,
                            role: reactionUser.role,
                            email: reactionUser.email,
                            profile_url: reactionUser.profile_url || null
                        } : null
                    };
                }));
                
                return {
                    ...post,
                    user: user ? {
                        id: user.id,
                        first_name: user.first_name,
                        last_name: user.last_name,
                        role: user.role,
                        email: user.email,
                        profile_url: user.profile_url || null
                    } : null,
                    approved_by: approvedByUser ? {
                        id: approvedByUser.id,
                        first_name: approvedByUser.first_name,
                        last_name: approvedByUser.last_name,
                        role: approvedByUser.role,
                        email: approvedByUser.email,
                        profile_url: approvedByUser.profile_url || null
                    } : null,
                    attachments: attachments || [],
                    reactions: reactionsWithUsers || []
                };
            }));
            
            res.status(200).json({success:true, statusCode:200, message:"Success", data: postsWithDetails});
        } catch (error) {
            next(error);
        }
    },

    getPostsForUser: async (req, res, next) => {
        try {

            const { userId } = req.body;
            // Get all posts for a user 
            const posts = await Post.getAllForUser(userId);
            
            // For each post, get attachments, reactions, and user details
            const postsWithDetails = await Promise.all(posts.map(async (post) => {
                const attachments = await PostAttachment.getByPostId(post.id);
                const reactions = await Reaction.getByPostId(post.id);
                const user = await User.findById(post.user_id);
                const approvedByUser = post.approved_by ? await User.findById(post.approved_by) : null;
                
                // Enhance reactions with user details
                const reactionsWithUsers = await Promise.all(reactions.map(async (reaction) => {
                    const reactionUser = await User.findById(reaction.user_id);
                    return {
                        ...reaction,
                        user: reactionUser ? {
                            id: reactionUser.id,
                            first_name: reactionUser.first_name,
                            last_name: reactionUser.last_name,
                            role: reactionUser.role,
                            email: reactionUser.email,
                            profile_url: reactionUser.profile_url || null
                        } : null
                    };
                }));
                
                return {
                    ...post,
                    user: user ? {
                        id: user.id,
                        first_name: user.first_name,
                        last_name: user.last_name,
                        role: user.role,
                        email: user.email,
                        profile_url: user.profile_url || null
                    } : null,
                    approved_by: approvedByUser ? {
                        id: approvedByUser.id,
                        first_name: approvedByUser.first_name,
                        last_name: approvedByUser.last_name,
                        role: approvedByUser.role,
                        email: approvedByUser.email,
                        profile_url: approvedByUser.profile_url || null
                    } : null,
                    attachments: attachments || [],
                    reactions: reactionsWithUsers || []
                };
            }));
            
            res.status(200).json({success:true, statusCode:200, message:"Success", data: postsWithDetails});
        } catch (error) {
            next(error);
        }
    },

    getMyPosts: async (req, res, next) => {
        try {

            const  userId  = req.userId;
            // Get all posts for a user 
            console.log(userId)
            const posts = await Post.getMyPosts(userId);
            
            // For each post, get attachments, reactions, and user details
            const postsWithDetails = await Promise.all(posts.map(async (post) => {
                const attachments = await PostAttachment.getByPostId(post.id);
                const reactions = await Reaction.getByPostId(post.id);
                const user = await User.findById(post.user_id);
                const approvedByUser = post.approved_by ? await User.findById(post.approved_by) : null;
                
                // Enhance reactions with user details
                const reactionsWithUsers = await Promise.all(reactions.map(async (reaction) => {
                    const reactionUser = await User.findById(reaction.user_id);
                    return {
                        ...reaction,
                        user: reactionUser ? {
                            id: reactionUser.id,
                            first_name: reactionUser.first_name,
                            last_name: reactionUser.last_name,
                            role: reactionUser.role,
                            email: reactionUser.email,
                            profile_url: reactionUser.profile_url || null
                        } : null
                    };
                }));
                
                return {
                    ...post,
                    user: user ? {
                        id: user.id,
                        first_name: user.first_name,
                        last_name: user.last_name,
                        role: user.role,
                        email: user.email,
                        profile_url: user.profile_url || null
                    } : null,
                    approved_by: approvedByUser ? {
                        id: approvedByUser.id,
                        first_name: approvedByUser.first_name,
                        last_name: approvedByUser.last_name,
                        role: approvedByUser.role,
                        email: approvedByUser.email,
                        profile_url: approvedByUser.profile_url || null
                    } : null,
                    attachments: attachments || [],
                    reactions: reactionsWithUsers || []
                };
            }));
            
            res.status(200).json({success:true, statusCode:200, message:"Success", data: postsWithDetails});
        } catch (error) {
            next(error);
        }
    },
    
    getPostById: async (req, res, next) => {
        try {
            const postId = req.params.id;
            const post = await Post.getById(postId);
            
            if (!post) {
                return res.status(404).json({ 
                    success: false,
                    statusCode: 404,
                    message: 'Post not found' 
                });
            }
            
            const attachments = await PostAttachment.getByPostId(postId);
            const reactions = await Reaction.getByPostId(postId);
            const user = await User.findById(post.user_id);
            const approvedByUser = post.approved_by ? await User.findById(post.approved_by) : null;
            
            // Enhance reactions with user details
            const reactionsWithUsers = await Promise.all(reactions.map(async (reaction) => {
                const reactionUser = await User.findById(reaction.user_id);
                return {
                    ...reaction,
                    user: reactionUser ? {
                        id: reactionUser.id,
                        first_name: reactionUser.first_name,
                        last_name: reactionUser.last_name,
                        role: reactionUser.role,
                        email: reactionUser.email,
                        profile_url: reactionUser.profile_url || null
                    } : null
                };
            }));
            
            res.status(200).json({
                success: true,
                statusCode: 200,
                message: "Success",
                data: {
                    ...post,
                    user: user ? {
                        id: user.id,
                        first_name: user.first_name,
                        last_name: user.last_name,
                        role: user.role,
                        email: user.email,
                        profile_url: user.profile_url || null
                    } : null,
                    approved_by: approvedByUser ? {
                        id: approvedByUser.id,
                        first_name: approvedByUser.first_name,
                        last_name: approvedByUser.last_name,
                        role: approvedByUser.role,
                        email: approvedByUser.email,
                        profile_url: approvedByUser.profile_url || null
                    } : null,
                    attachments: attachments || [],
                    reactions: reactionsWithUsers || []
                }
            });
        } catch (error) {
            next(error);
        }
    },

    // Add or update a reaction to a post
    reactToPost: async (req, res, next) => {
        try {
            const { postId } = req.body;
            const { reactionType } = req.body;
            const userId = req.userId; 

            // Validate reaction type
            if (!reactionType) {
                return res.status(400).json({
                    success: false,
                    statusCode: 400,
                    message: "Reaction type is required"
                });
            }

            // Check if post exists
            const post = await Post.getById(postId);
            if (!post) {
                return res.status(404).json({
                    success: false,
                    statusCode: 404,
                    message: "Post not found"
                });
            }

            // Add/update reaction
            const result = await Reaction.react(userId, postId, reactionType);

            // Get updated reactions for the post
            const updatedReactions = await Reaction.getByPostId(postId);

            res.status(200).json({
                success: true,
                statusCode: 200,
                message: "Reaction updated successfully",
                data: {
                    reactions: updatedReactions
                }
            });
        } catch (error) {
            next(error);
        }
    },

    // Remove a reaction from a post
    removeReaction: async (req, res, next) => {
        try {
            const { postId } = req.body;
            const userId = req.userId; 

            // Check if post exists
            const post = await Post.getById(postId);
            if (!post) {
                return res.status(404).json({
                    success: false,
                    statusCode: 404,
                    message: "Post not found"
                });
            }

            // Delete reaction
            const result = await Reaction.delete(userId, postId);

            if (result.affectedRows === 0) {
                return res.status(404).json({
                    success: false,
                    statusCode: 404,
                    message: "Reaction not found"
                });
            }

            // Get updated reactions for the post
            const updatedReactions = await Reaction.getByPostId(postId);

            res.status(200).json({
                success: true,
                statusCode: 200,
                message: "Reaction removed successfully",
                data: {
                    reactions: updatedReactions
                }
            });
        } catch (error) {
            next(error);
        }
    },

    createPost: async (req, res, next) => {
        try {
            const { post: content } = req.body;
            const userId = req.userId; 

            const currentUser = await User.findById(userId)
            let approved =false; 
            console.log(currentUser['role'] )
            if(currentUser['role'] == 'SUPER_ADMIN' || currentUser['role'] == 'DESK_OFFICER'){
                approved = true
            }

            // Validate at least content or files exist
            if (!content && (!req.files || req.files.length === 0)) {
                return res.status(400).json({
                    success: false,
                    message: "Either post content or attachments are required"
                });
            }
            console.log(userId);
            // Create post in database
            const newPost = await Post.create(
                userId, content, approved
            );

            // Process attachments if they exist
            let attachments = [];
            if (req.files && req.files.length > 0) {
                attachments = await Promise.all(
                    req.files.map(async (file) => {
                        const ext = path.extname(file.originalname).toLowerCase();
                        const type = ['.mp4', '.mkv'].includes(ext) ? 'VID' : 'IMG';
                        
                        console.log(ext)
                        console.log(type)
                        return await PostAttachment.create(
                            newPost, 
                            {
                                type: type, 
                                url: `/uploads/${file.filename}`
                            }
                            );
                    })
                );
            }

            // Get user details
            const user = await User.findById(userId);

            // Return successful response
            res.status(201).json({
                success: true,
                message: "Post created successfully",
                data: {
                    ...newPost,
                    user: {
                        id: user.id,
                        first_name: user.first_name,
                        last_name: user.last_name,
                        email: user.email,
                        profile_url: user.profile_url || null
                    },
                    attachments: attachments || []
                }
            });

        } catch (error) {
            // Clean up uploaded files if error occurs
            if (req.files) {
                req.files.forEach(file => {
                    fs.unlink(file.path, () => {}); // Silent cleanup
                });
            }
            
            console.error('Post creation error:', error);
            next(error); // Pass to your error handling middleware
        }
    },

  approvePost: async (req, res, next) => {
    try {
        const { postId, isApproved } = req.body; // Expecting 0 or 1
        const userId = req.userId;  
        console.log(isApproved)
       

        // Check if post exists
        const post = await Post.getById(postId);
        if (!post) {
            return res.status(404).json({
                success: false,
                statusCode: 404,
                message: "Post not found"
            });
        }

        // Update approval status (0 or 1)
        const success = await Post.approvePost(postId, userId, isApproved);
        
        if (!success) {
            return res.status(500).json({
                success: false,
                statusCode: 500,
                message: "Failed to update approval status"
            });
        }

        // Get updated post details
        const updatedPost = await Post.getById(postId);
        const attachments = await PostAttachment.getByPostId(postId);
        const reactions = await Reaction.getByPostId(postId);
        const user = await User.findById(updatedPost.user_id);
        const approvedByUser = updatedPost.approved_by ? await User.findById(updatedPost.approved_by) : null;

        res.status(200).json({
            success: true,
            statusCode: 200,
            message: `Post ${isApproved == 1 ? 'approved' : 'unapproved'} successfully`,
            data: {
                ...updatedPost,
                user: user ? {
                    id: user.id,
                    first_name: user.first_name,
                    last_name: user.last_name,
                    role: user.role,
                    email: user.email,
                    profile_url: user.profile_url || null
                } : null,
                approved_by: approvedByUser ? {
                    id: approvedByUser.id,
                    first_name: approvedByUser.first_name,
                    last_name: approvedByUser.last_name,
                    role: approvedByUser.role,
                    email: approvedByUser.email,
                    profile_url: approvedByUser.profile_url || null
                } : null,
                attachments: attachments || [],
                reactions: reactions || []
            }
        });

    } catch (error) {
        console.error('Post approval error:', error);
        next(error);
    }
},

// Add this method to your postController object
deletePost: async (req, res, next) => {
    try {
        const postId = req.params.id;
        const userId = req.userId; // From authentication middleware

        // Check if post exists
        const post = await Post.getById(postId);
        if (!post) {
            return res.status(404).json({
                success: false,
                statusCode: 404,
                message: "Post not found"
            });
        }

        // Verify the user is the owner of the post or an admin
        // You might want to add an admin check here if needed
        if (post.user_id !== userId) {
            return res.status(403).json({
                success: false,
                statusCode: 403,
                message: "Unauthorized - You can only delete your own posts"
            });
        }

        // Finally, delete the post itself
        const result = await Post.delete(postId);

        if (result.affectedRows === 0) {
            return res.status(404).json({
                success: false,
                statusCode: 404,
                message: "Post not found or already deleted"
            });
        }

        res.status(200).json({
            success: true,
            statusCode: 200,
            message: "Post deleted successfully"
        });

    } catch (error) {
        next(error);
    }
}
};

module.exports = postController;