const GroupMessage = require('../models/GroupMessage');
const Group = require('../models/Group');
const User = require('../models/User');
const fs = require('fs');
const path = require('path');

// Get recent messages for a group
exports.getRecentMessages = async (req, res) => {
    try {
        const { groupId } = req.params;
        const { limit = 500, offset = 0 } = req.query;
        
        console.log(`💬 [GROUP MESSAGE DEBUG] Getting recent messages for group: ${groupId}`);
        console.log(`💬 [GROUP MESSAGE DEBUG] Limit: ${limit}, Offset: ${offset}`);
        
        // Validate group exists
        const group = await Group.findById(groupId);
        if (!group) {
            console.log(`❌ [GROUP MESSAGE DEBUG] Group not found: ${groupId}`);
            return res.status(404).json({
                success: false,
                message: 'Group not found'
            });
        }
        
        console.log(`✅ [GROUP MESSAGE DEBUG] Group found: ${group.groupName}`);
        
        // Get recent messages
        const messages = await GroupMessage.getRecentMessages(groupId, parseInt(limit), parseInt(offset));
        const totalCount = await GroupMessage.getMessageCount(groupId);
        
        console.log(`📊 [GROUP MESSAGE DEBUG] Found ${messages.length} messages (${totalCount} total)`);
        
        res.json({
            success: true,
            message: 'Recent messages retrieved successfully',
            data: {
                group: {
                    groupId: group._id,
                    groupName: group.groupName,
                    groupType: group.groupType,
                    memberCount: group.memberCount
                },
                messages: messages,
                pagination: {
                    totalMessages: totalCount,
                    returnedMessages: messages.length,
                    limit: parseInt(limit),
                    offset: parseInt(offset),
                    hasMore: (parseInt(offset) + messages.length) < totalCount
                }
            }
        });
        
    } catch (error) {
        console.error('❌ [GROUP MESSAGE ERROR] Get recent messages failed:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to get recent messages',
            error: error.message
        });
    }
};

// Send a message to group
exports.sendMessage = async (req, res) => {
    try {
        const { groupId } = req.params;
        const { userId, message, messageType = 'text', replyTo, metadata } = req.body;
        
        console.log(`💬 [SEND MESSAGE DEBUG] User ${userId} sending message to group ${groupId}`);
        console.log(`💬 [SEND MESSAGE DEBUG] Message type: ${messageType}`);
        console.log(`💬 [SEND MESSAGE DEBUG] Message: ${message}`);
        
        // Validate required fields
        if (!userId || !message) {
            return res.status(400).json({
                success: false,
                message: 'User ID and message are required'
            });
        }
        
        // Check if user exists
        const user = await User.findById(userId).select('name mobile profileImage');
        if (!user) {
            console.log(`❌ [SEND MESSAGE DEBUG] User not found: ${userId}`);
            return res.status(404).json({
                success: false,
                message: 'User not found'
            });
        }
        
        // Check if group exists
        const group = await Group.findById(groupId);
        if (!group) {
            console.log(`❌ [SEND MESSAGE DEBUG] Group not found: ${groupId}`);
            return res.status(404).json({
                success: false,
                message: 'Group not found'
            });
        }
        
        // Check if user is member of the group
        const isMember = group.members ? group.members.some(member => 
            member.user_id.toString() === userId.toString()
        ) : false;
        
        if (!isMember) {
            console.log(`❌ [SEND MESSAGE DEBUG] User is not a member of the group`);
            return res.status(403).json({
                success: false,
                message: 'User is not a member of this group'
            });
        }
        
        // Create message object
        const messageData = {
            groupId: groupId,
            userId: userId,
            message: message,
            messageType: messageType,
            replyTo: replyTo || null,
            metadata: metadata || {}
        };
        
        // Handle media uploads if present
        if (req.files && req.files.length > 0) {
            const file = req.files[0];
            console.log(`💬 [SEND MESSAGE DEBUG] Processing media file: ${file.originalname}`);
            
            const mediaData = await saveMediaFile(file, groupId);
            messageData.media = mediaData;
            messageData.messageType = getMessageTypeFromFile(file);
        }
        
        // Create and save message
        const newMessage = new GroupMessage(messageData);
        await newMessage.save();
        
        // Populate the message for response
        const populatedMessage = await GroupMessage.findById(newMessage._id)
            .populate('userId', 'name mobile profileImage')
            .populate('replyTo', 'message userId');
        
        console.log(`✅ [SEND MESSAGE DEBUG] Message sent successfully: ${newMessage._id}`);
        
        res.status(201).json({
            success: true,
            message: 'Message sent successfully',
            data: {
                message: populatedMessage
            }
        });
        
    } catch (error) {
        console.error('❌ [SEND MESSAGE ERROR] Send message failed:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to send message',
            error: error.message
        });
    }
};

// Edit a message
exports.editMessage = async (req, res) => {
    try {
        const { messageId } = req.params;
        const { userId, newMessage } = req.body;
        
        console.log(`💬 [EDIT MESSAGE DEBUG] User ${userId} editing message ${messageId}`);
        
        // Find the message
        const message = await GroupMessage.findById(messageId);
        if (!message) {
            return res.status(404).json({
                success: false,
                message: 'Message not found'
            });
        }
        
        // Check if user is the message sender
        if (message.userId.toString() !== userId.toString()) {
            return res.status(403).json({
                success: false,
                message: 'You can only edit your own messages'
            });
        }
        
        // Edit the message
        await message.editMessage(newMessage);
        
        // Populate for response
        const updatedMessage = await GroupMessage.findById(messageId)
            .populate('userId', 'name mobile profileImage')
            .populate('replyTo', 'message userId');
        
        console.log(`✅ [EDIT MESSAGE DEBUG] Message edited successfully: ${messageId}`);
        
        res.json({
            success: true,
            message: 'Message edited successfully',
            data: {
                message: updatedMessage
            }
        });
        
    } catch (error) {
        console.error('❌ [EDIT MESSAGE ERROR] Edit message failed:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to edit message',
            error: error.message
        });
    }
};

// Delete a message
exports.deleteMessage = async (req, res) => {
    try {
        const { messageId } = req.params;
        const { userId } = req.body;
        
        console.log(`💬 [DELETE MESSAGE DEBUG] User ${userId} deleting message ${messageId}`);
        
        // Find the message
        const message = await GroupMessage.findById(messageId);
        if (!message) {
            return res.status(404).json({
                success: false,
                message: 'Message not found'
            });
        }
        
        // Check if user is the message sender or group admin
        if (message.userId.toString() !== userId.toString()) {
            // Check if user is admin of the group
            const group = await Group.findById(message.groupId);
            const isAdmin = group.members ? group.members.some(member => 
                member.user_id.toString() === userId.toString() && member.role === 'admin'
            ) : false;
            
            if (!isAdmin) {
                return res.status(403).json({
                    success: false,
                    message: 'You can only delete your own messages'
                });
            }
        }
        
        // Delete the message (soft delete)
        await message.deleteMessage();
        
        console.log(`✅ [DELETE MESSAGE DEBUG] Message deleted successfully: ${messageId}`);
        
        res.json({
            success: true,
            message: 'Message deleted successfully'
        });
        
    } catch (error) {
        console.error('❌ [DELETE MESSAGE ERROR] Delete message failed:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to delete message',
            error: error.message
        });
    }
};

// Add reaction to message
exports.addReaction = async (req, res) => {
    try {
        const { messageId } = req.params;
        const { userId, emoji } = req.body;
        
        console.log(`💬 [ADD REACTION DEBUG] User ${userId} adding reaction ${emoji} to message ${messageId}`);
        
        // Find the message
        const message = await GroupMessage.findById(messageId);
        if (!message) {
            return res.status(404).json({
                success: false,
                message: 'Message not found'
            });
        }
        
        // Add reaction
        await message.addReaction(userId, emoji);
        
        // Get updated message
        const updatedMessage = await GroupMessage.findById(messageId)
            .populate('userId', 'name mobile profileImage')
            .populate('reactions.userId', 'name mobile');
        
        console.log(`✅ [ADD REACTION DEBUG] Reaction added successfully`);
        
        res.json({
            success: true,
            message: 'Reaction added successfully',
            data: {
                message: updatedMessage
            }
        });
        
    } catch (error) {
        console.error('❌ [ADD REACTION ERROR] Add reaction failed:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to add reaction',
            error: error.message
        });
    }
};

// Search messages in group
exports.searchMessages = async (req, res) => {
    try {
        const { groupId } = req.params;
        const { searchTerm, limit = 100 } = req.query;
        
        console.log(`💬 [SEARCH MESSAGE DEBUG] Searching messages in group: ${groupId}`);
        console.log(`💬 [SEARCH MESSAGE DEBUG] Search term: ${searchTerm}`);
        
        if (!searchTerm) {
            return res.status(400).json({
                success: false,
                message: 'Search term is required'
            });
        }
        
        // Check if group exists
        const group = await Group.findById(groupId);
        if (!group) {
            return res.status(404).json({
                success: false,
                message: 'Group not found'
            });
        }
        
        // Search messages
        const messages = await GroupMessage.searchMessages(groupId, searchTerm, parseInt(limit));
        
        console.log(`📊 [SEARCH MESSAGE DEBUG] Found ${messages.length} matching messages`);
        
        res.json({
            success: true,
            message: 'Messages searched successfully',
            data: {
                group: {
                    groupId: group._id,
                    groupName: group.groupName,
                    groupType: group.groupType
                },
                searchTerm: searchTerm,
                messages: messages,
                totalFound: messages.length
            }
        });
        
    } catch (error) {
        console.error('❌ [SEARCH MESSAGE ERROR] Search messages failed:', error);
        res.status(500).json({
            success: false,
            message: 'Failed to search messages',
            error: error.message
        });
    }
};

// Helper function to save media files
const saveMediaFile = async (file, groupId) => {
    try {
        const timestamp = Date.now();
        const randomString = Math.random().toString(36).substring(2, 15);
        const fileExtension = path.extname(file.originalname);
        const fileName = `group_${groupId}_${timestamp}_${randomString}${fileExtension}`;
        const filePath = path.join(__dirname, '..', 'uploads', 'group_messages', fileName);
        
        // Create directory if it doesn't exist
        const uploadDir = path.dirname(filePath);
        if (!fs.existsSync(uploadDir)) {
            fs.mkdirSync(uploadDir, { recursive: true });
        }
        
        // Save file
        fs.writeFileSync(filePath, file.buffer);
        
        const stats = fs.statSync(filePath);
        
        return {
            fileName: fileName,
            filePath: filePath,
            url: `/uploads/group_messages/${fileName}`,
            originalName: file.originalname,
            size: stats.size,
            mimeType: file.mimetype
        };
        
    } catch (error) {
        console.error('❌ [SAVE MEDIA ERROR] Failed to save media file:', error);
        throw error;
    }
};

// Helper function to determine message type from file
const getMessageTypeFromFile = (file) => {
    if (file.mimetype.startsWith('image/')) {
        return 'image';
    } else if (file.mimetype.startsWith('video/')) {
        return 'video';
    } else {
        return 'file';
    }
};
