const Message = require('../models/messageModel');
const User = require('../models/userModel');
const { upload } = require('../middleware/uploadMiddleware');
const path = require('path');
const fs = require('fs');
const NotificationHelper = require('../utils/notificationHelper');
const pool = require('../config/db');

const messageController = {
  // Get all messages for a user
  getAllMessages: async (req, res, next) => {
    try {
      const userId = req.userId;
      
      console.log(userId)
      // Get messages
      const messages = await Message.getAllForUser(userId);
      
      res.status(200).json({
        success: true,
        statusCode: 200,
        message: "Messages retrieved successfully",
        data: messages
      });
    } catch (error) {
      next(error);
    }
  },

  // Get a specific message
  getMessageById: async (req, res, next) => {
    try {
      const messageId = req.params.id;
      const userId = req.userId;
      console.log(userId)
      // Get message details
      const message = await Message.getByIdForUser(messageId, userId);
      
      if (!message) {
        return res.status(404).json({
          success: false,
          statusCode: 404,
          message: "Message not found"
        });
      }
      
    await Message.markAsRead(messageId, userId);
      
      
      res.status(200).json({
        success: true,
        statusCode: 200,
        message: "Message retrieved successfully",
        data: message
      });
    } catch (error) {
      next(error);
    }
  },

  // Delete a message for a user (soft delete from recipient's view)
  deleteMessage: async (req, res, next) => {
    try {
      const messageId = req.params.id;
      const userId = req.userId;
      
      const success = await Message.deleteForRecipient(messageId, userId);
      
      if (!success) {
        return res.status(404).json({
          success: false,
          statusCode: 404,
          message: "Message not found or already deleted"
        });
      }
      
      res.status(200).json({
        success: true,
        statusCode: 200,
        message: "Message deleted successfully"
      });
    } catch (error) {
      next(error);
    }
  },

createMessage: async (req, res, next) => {
    try {
      const { subject, message, recipients } = req.body;
      const senderId = req.userId;
      
      // Parse recipients if it's a string
      let recipientIds = recipients;
      if (typeof recipients === 'string') {
        try {
          recipientIds = JSON.parse(recipients);
        } catch (e) {
          recipientIds = [recipients]; // fallback to array with single value
        }
      }
      
      // Ensure it's an array
      if (!Array.isArray(recipientIds)) {
        recipientIds = [recipientIds];
      }
      
      // Create the message
      const messageId = await Message.create(senderId, subject, message, recipientIds);
      
      // Process attachments if they exist
      let attachments = [];
      if (req.files && req.files.length > 0) {
        attachments = req.files.map(file => ({
          type: path.extname(file.originalname).substring(1).toUpperCase(),
          url: `/uploads/${file.filename}`
        }));
        
        await Message.addAttachments(messageId, attachments);
      }
      
      // Get sender details
      const sender = await User.findById(senderId);
      
      // Send notifications to all recipients
      await Promise.all(recipientIds.map(async recipientId => {
        await NotificationHelper.sendMessageNotification(
          req.app.locals.wss,
          req.app.locals.clients,
          recipientId,
          senderId,
          messageId,
          'message'
        );
      }));
      
      res.status(201).json({
        success: true,
        statusCode: 201,
        message: "Message sent successfully",
        data: {
          id: messageId,
          subject,
          message,
          sender: {
            id: sender.id,
            first_name: sender.first_name,
            last_name: sender.last_name,
            profile_url: sender.profile_url || null
          },
          attachments
        }
      });
    } catch (error) {
      // Clean up uploaded files if error occurs
      if (req.files) {
        req.files.forEach(file => {
          fs.unlink(file.path, () => {}); // Silent cleanup
        });
      }
      
      next(error);
    }
  },

  // Add a reply to a message
  addReply: async (req, res, next) => {
    try {
      const messageId = req.params.id;
      const { reply } = req.body;
      const userId = req.userId;
      
      if (!reply) {
        return res.status(400).json({
          success: false,
          statusCode: 400,
          message: "Reply text is required"
        });
      }
      
      // Create the reply
      const replyId = await Message.addReply(messageId, userId, reply);
      
      // Process attachments if they exist
      let attachments = [];
      if (req.files && req.files.length > 0) {
        attachments = req.files.map(file => ({
          type: path.extname(file.originalname).substring(1).toUpperCase(),
          url: `/uploads/${file.filename}`
        }));
        
        await Message.addReplyAttachments(replyId, attachments);
      }
      
      // Get user details
      const user = await User.findById(userId);
      
      res.status(201).json({
        success: true,
        statusCode: 201,
        message: "Reply added successfully",
        data: {
          id: replyId,
          message_id: messageId,
          reply,
          user: {
            id: user.id,
            first_name: user.first_name,
            last_name: user.last_name,
            profile_url: user.profile_url || null
          },
          attachments
        }
      });
      const [message] = await pool.query('SELECT message_from FROM messages WHERE id = ?', [messageId]);
        const originalSenderId = message[0].message_from;

        // Get all recipients of the original message
        const [recipients] = await pool.query(
        'SELECT user_id FROM message_recepient WHERE message_id = ?',
        [messageId]
        );

        const recipientsToNotify = recipients
        .map(r => r.user_id)
        .filter(id => id !== userId && id !== originalSenderId);

        // Also notify the original sender if they're not the one replying
        if (originalSenderId !== userId) {
        recipientsToNotify.push(originalSenderId);
        }

        await Promise.all(recipientsToNotify.map(async recipientId => {
        await NotificationHelper.sendMessageNotification(
            req.app.locals.wss,
            req.app.locals.clients,
            recipientId,
            userId,
            messageId,
            'reply'
        );
        }));
    } catch (error) {
      // Clean up uploaded files if error occurs
      if (req.files) {
        req.files.forEach(file => {
          fs.unlink(file.path, () => {}); // Silent cleanup
        });
      }
      
      next(error);
    }
  },

  getUnreadCount: async (req, res, next) => {
    try {
      const userId = req.userId;
      
      const unreadCount = await Message.getUnreadCount(userId);
      
      res.status(200).json({
        success: true,
        statusCode: 200,
        message: "Unread message count retrieved successfully",
        data: {
          unread_count: unreadCount
        }
      });
    } catch (error) {
      next(error);
    }
  },
};

module.exports = messageController;