const StudyGroup = require('../models/StudyGroup');
const StudyGroupPost = require('../models/StudyGroupPost');
const User = require('../models/User');

// Create study group
const createStudyGroup = async (req, res) => {
    try {
        const { name, description, exam, stage, isPublic = true, maxMembers = 50 } = req.body;
        const userId = req.user.id;

        const studyGroup = new StudyGroup({
            name,
            description,
            exam,
            stage,
            createdBy: userId,
            isPublic,
            maxMembers,
            members: [{
                user: userId,
                role: 'admin'
            }]
        });

        await studyGroup.save();

        res.status(201).json({
            success: true,
            message: 'Study group created successfully',
            data: studyGroup
        });
    } catch (error) {
        console.error('Create study group error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to create study group',
            error: error.message
        });
    }
};

// Get study groups
const getStudyGroups = async (req, res) => {
    try {
        const { exam, stage, page = 1, limit = 10 } = req.query;

        const filter = { isActive: true, isPublic: true };
        
        if (exam) filter.exam = exam;
        if (stage) filter.stage = stage;

        const studyGroups = await StudyGroup.find(filter)
            .populate('createdBy', 'name')
            .populate('members.user', 'name')
            .select('-__v')
            .sort({ createdAt: -1 })
            .limit(limit * 1)
            .skip((page - 1) * limit);

        const total = await StudyGroup.countDocuments(filter);

        res.status(200).json({
            success: true,
            data: {
                studyGroups,
                pagination: {
                    currentPage: parseInt(page),
                    totalPages: Math.ceil(total / limit),
                    totalGroups: total,
                    hasNext: page < Math.ceil(total / limit),
                    hasPrev: page > 1
                }
            }
        });
    } catch (error) {
        console.error('Get study groups error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to get study groups',
            error: error.message
        });
    }
};

// Join study group
const joinStudyGroup = async (req, res) => {
    try {
        const { groupId } = req.params;
        const userId = req.user.id;

        const studyGroup = await StudyGroup.findById(groupId);

        if (!studyGroup) {
            return res.status(404).json({
                success: false,
                message: 'Study group not found'
            });
        }

        // Check if user is already a member
        const isAlreadyMember = studyGroup.members.some(
            member => member.user.toString() === userId
        );

        if (isAlreadyMember) {
            return res.status(400).json({
                success: false,
                message: 'You are already a member of this group'
            });
        }

        // Check if group is full
        if (studyGroup.members.length >= studyGroup.maxMembers) {
            return res.status(400).json({
                success: false,
                message: 'Study group is full'
            });
        }

        studyGroup.members.push({
            user: userId,
            role: 'member'
        });

        await studyGroup.save();

        res.status(200).json({
            success: true,
            message: 'Successfully joined the study group',
            data: studyGroup
        });
    } catch (error) {
        console.error('Join study group error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to join study group',
            error: error.message
        });
    }
};

// Leave study group
const leaveStudyGroup = async (req, res) => {
    try {
        const { groupId } = req.params;
        const userId = req.user.id;

        const studyGroup = await StudyGroup.findById(groupId);

        if (!studyGroup) {
            return res.status(404).json({
                success: false,
                message: 'Study group not found'
            });
        }

        // Check if user is a member
        const memberIndex = studyGroup.members.findIndex(
            member => member.user.toString() === userId
        );

        if (memberIndex === -1) {
            return res.status(400).json({
                success: false,
                message: 'You are not a member of this group'
            });
        }

        // Remove member
        studyGroup.members.splice(memberIndex, 1);

        // If group becomes empty, deactivate it
        if (studyGroup.members.length === 0) {
            studyGroup.isActive = false;
        }

        await studyGroup.save();

        res.status(200).json({
            success: true,
            message: 'Successfully left the study group'
        });
    } catch (error) {
        console.error('Leave study group error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to leave study group',
            error: error.message
        });
    }
};

// Get study group details
const getStudyGroupDetails = async (req, res) => {
    try {
        const { groupId } = req.params;

        const studyGroup = await StudyGroup.findById(groupId)
            .populate('createdBy', 'name')
            .populate('members.user', 'name');

        if (!studyGroup) {
            return res.status(404).json({
                success: false,
                message: 'Study group not found'
            });
        }

        res.status(200).json({
            success: true,
            data: studyGroup
        });
    } catch (error) {
        console.error('Get study group details error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to get study group details',
            error: error.message
        });
    }
};

// Create post in study group
const createGroupPost = async (req, res) => {
    try {
        const { groupId } = req.params;
        const { content, type = 'discussion' } = req.body;
        const userId = req.user.id;

        // Check if user is a member of the group
        const studyGroup = await StudyGroup.findById(groupId);
        if (!studyGroup) {
            return res.status(404).json({
                success: false,
                message: 'Study group not found'
            });
        }

        const isMember = studyGroup.members.some(
            member => member.user.toString() === userId
        );

        if (!isMember) {
            return res.status(403).json({
                success: false,
                message: 'You must be a member to post in this group'
            });
        }

        const post = new StudyGroupPost({
            groupId,
            author: userId,
            content,
            type
        });

        await post.save();

        const populatedPost = await StudyGroupPost.findById(post._id)
            .populate('author', 'name');

        res.status(201).json({
            success: true,
            message: 'Post created successfully',
            data: populatedPost
        });
    } catch (error) {
        console.error('Create group post error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to create post',
            error: error.message
        });
    }
};

// Get study group posts
const getStudyGroupPosts = async (req, res) => {
    try {
        const { groupId } = req.params;
        const { page = 1, limit = 10 } = req.query;

        const posts = await StudyGroupPost.find({
            groupId,
            isActive: true
        })
            .populate('author', 'name')
            .populate('likes.user', 'name')
            .populate('comments.user', 'name')
            .select('-__v')
            .sort({ isPinned: -1, createdAt: -1 })
            .limit(limit * 1)
            .skip((page - 1) * limit);

        const total = await StudyGroupPost.countDocuments({
            groupId,
            isActive: true
        });

        res.status(200).json({
            success: true,
            data: {
                posts,
                pagination: {
                    currentPage: parseInt(page),
                    totalPages: Math.ceil(total / limit),
                    totalPosts: total,
                    hasNext: page < Math.ceil(total / limit),
                    hasPrev: page > 1
                }
            }
        });
    } catch (error) {
        console.error('Get study group posts error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to get posts',
            error: error.message
        });
    }
};

// Like/Unlike post
const togglePostLike = async (req, res) => {
    try {
        const { postId } = req.params;
        const userId = req.user.id;

        const post = await StudyGroupPost.findById(postId);

        if (!post) {
            return res.status(404).json({
                success: false,
                message: 'Post not found'
            });
        }

        const likeIndex = post.likes.findIndex(
            like => like.user.toString() === userId
        );

        if (likeIndex !== -1) {
            // Unlike
            post.likes.splice(likeIndex, 1);
        } else {
            // Like
            post.likes.push({ user: userId });
        }

        await post.save();

        res.status(200).json({
            success: true,
            message: likeIndex !== -1 ? 'Post unliked' : 'Post liked',
            data: {
                likesCount: post.likes.length,
                isLiked: likeIndex === -1
            }
        });
    } catch (error) {
        console.error('Toggle post like error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to toggle like',
            error: error.message
        });
    }
};

// Add comment to post
const addComment = async (req, res) => {
    try {
        const { postId } = req.params;
        const { content } = req.body;
        const userId = req.user.id;

        const post = await StudyGroupPost.findById(postId);

        if (!post) {
            return res.status(404).json({
                success: false,
                message: 'Post not found'
            });
        }

        post.comments.push({
            user: userId,
            content
        });

        await post.save();

        const populatedPost = await StudyGroupPost.findById(postId)
            .populate('comments.user', 'name');

        res.status(200).json({
            success: true,
            message: 'Comment added successfully',
            data: populatedPost.comments[populatedPost.comments.length - 1]
        });
    } catch (error) {
        console.error('Add comment error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to add comment',
            error: error.message
        });
    }
};

// Get all study groups (Admin only)
const getAllStudyGroups = async (req, res) => {
    try {
        const { page = 1, limit = 50, exam, stage, isActive, isPublic } = req.query;

        const filter = {};

        if (exam) filter.exam = exam;
        if (stage) filter.stage = stage;
        if (isActive !== undefined) filter.isActive = isActive === 'true';
        if (isPublic !== undefined) filter.isPublic = isPublic === 'true';

        const studyGroups = await StudyGroup.find(filter)
            .populate('createdBy', 'name email')
            .populate('members.user', 'name email')
            .select('-__v')
            .sort({ createdAt: -1 })
            .limit(limit * 1)
            .skip((page - 1) * limit);

        const total = await StudyGroup.countDocuments(filter);

        res.status(200).json({
            success: true,
            data: {
                studyGroups,
                pagination: {
                    currentPage: parseInt(page),
                    totalPages: Math.ceil(total / limit),
                    totalGroups: total,
                    hasNext: page < Math.ceil(total / limit),
                    hasPrev: page > 1
                }
            }
        });
    } catch (error) {
        console.error('Get all study groups error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to get study groups',
            error: error.message
        });
    }
};

// Update study group (Admin only)
const updateStudyGroup = async (req, res) => {
    try {
        const { groupId } = req.params;
        const updateData = req.body;

        const studyGroup = await StudyGroup.findByIdAndUpdate(
            groupId,
            updateData,
            { new: true, runValidators: true }
        ).populate('createdBy', 'name email')
         .populate('members.user', 'name email');

        if (!studyGroup) {
            return res.status(404).json({
                success: false,
                message: 'Study group not found'
            });
        }

        res.status(200).json({
            success: true,
            message: 'Study group updated successfully',
            data: studyGroup
        });
    } catch (error) {
        console.error('Update study group error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to update study group',
            error: error.message
        });
    }
};

// Delete study group (Admin only)
const deleteStudyGroup = async (req, res) => {
    try {
        const { groupId } = req.params;

        const studyGroup = await StudyGroup.findByIdAndDelete(groupId);

        if (!studyGroup) {
            return res.status(404).json({
                success: false,
                message: 'Study group not found'
            });
        }

        res.status(200).json({
            success: true,
            message: 'Study group deleted successfully'
        });
    } catch (error) {
        console.error('Delete study group error:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to delete study group',
            error: error.message
        });
    }
};

module.exports = {
    createStudyGroup,
    getStudyGroups,
    joinStudyGroup,
    leaveStudyGroup,
    getStudyGroupDetails,
    createGroupPost,
    getStudyGroupPosts,
    togglePostLike,
    addComment,
    getAllStudyGroups,
    updateStudyGroup,
    deleteStudyGroup
};
