const AvailabilityNotification = require("../models/AvailabilityNotification");
const TherapistAvailability = require("../models/TherapistAvailability");
const User = require("../models/userModel");

// Get notifications for current user
const getUserNotifications = async (req, res) => {
  try {
    const userId = req.user.id;
    const { page = 1, limit = 20, status, type, unreadOnly = false } = req.query;
    
    const filter = { recipient: userId };
    
    if (status) {
      filter.status = status;
    }
    
    if (type) {
      filter.type = type;
    }
    
    if (unreadOnly === 'true') {
      filter.status = 'unread';
    }
    
    const notifications = await AvailabilityNotification.find(filter)
      .populate('sender', 'fullname email')
      .populate('relatedData.availabilityId')
      .populate('relatedData.appointmentId')
      .sort({ createdAt: -1 })
      .limit(limit * 1)
      .skip((page - 1) * limit);
    
    const total = await AvailabilityNotification.countDocuments(filter);
    const unreadCount = await AvailabilityNotification.countDocuments({
      recipient: userId,
      status: 'unread'
    });
    
    return res.status(200).json({
      success: true,
      message: "Notifications fetched successfully",
      data: {
        notifications,
        pagination: {
          currentPage: parseInt(page),
          totalPages: Math.ceil(total / limit),
          totalItems: total,
          itemsPerPage: parseInt(limit)
        },
        unreadCount
      }
    });
    
  } catch (error) {
    console.error("Get notifications error:", error);
    return res.status(500).json({
      success: false,
      message: "Server Error",
      error: error.message
    });
  }
};

// Mark notification as read
const markNotificationAsRead = async (req, res) => {
  try {
    const { notificationId } = req.params;
    const userId = req.user.id;
    
    const notification = await AvailabilityNotification.findOne({
      _id: notificationId,
      recipient: userId
    });
    
    if (!notification) {
      return res.status(404).json({
        success: false,
        message: "Notification not found"
      });
    }
    
    await notification.markAsRead();
    
    return res.status(200).json({
      success: true,
      message: "Notification marked as read",
      data: notification
    });
    
  } catch (error) {
    console.error("Mark notification as read error:", error);
    return res.status(500).json({
      success: false,
      message: "Server Error",
      error: error.message
    });
  }
};

// Mark all notifications as read
const markAllNotificationsAsRead = async (req, res) => {
  try {
    const userId = req.user.id;
    
    await AvailabilityNotification.updateMany(
      { recipient: userId, status: 'unread' },
      { 
        status: 'read',
        readAt: new Date()
      }
    );
    
    return res.status(200).json({
      success: true,
      message: "All notifications marked as read"
    });
    
  } catch (error) {
    console.error("Mark all notifications as read error:", error);
    return res.status(500).json({
      success: false,
      message: "Server Error",
      error: error.message
    });
  }
};

// Archive notification
const archiveNotification = async (req, res) => {
  try {
    const { notificationId } = req.params;
    const userId = req.user.id;
    
    const notification = await AvailabilityNotification.findOne({
      _id: notificationId,
      recipient: userId
    });
    
    if (!notification) {
      return res.status(404).json({
        success: false,
        message: "Notification not found"
      });
    }
    
    await notification.archive();
    
    return res.status(200).json({
      success: true,
      message: "Notification archived",
      data: notification
    });
    
  } catch (error) {
    console.error("Archive notification error:", error);
    return res.status(500).json({
      success: false,
      message: "Server Error",
      error: error.message
    });
  }
};

// Get notifications requiring action
const getActionRequiredNotifications = async (req, res) => {
  try {
    const userId = req.user.id;
    
    const notifications = await AvailabilityNotification.getActionRequiredForUser(userId);
    
    return res.status(200).json({
      success: true,
      message: "Action required notifications fetched successfully",
      data: notifications
    });
    
  } catch (error) {
    console.error("Get action required notifications error:", error);
    return res.status(500).json({
      success: false,
      message: "Server Error",
      error: error.message
    });
  }
};

// Get notification statistics
const getNotificationStats = async (req, res) => {
  try {
    const userId = req.user.id;
    
    const stats = await AvailabilityNotification.aggregate([
      { $match: { recipient: userId } },
      {
        $group: {
          _id: '$status',
          count: { $sum: 1 }
        }
      }
    ]);
    
    const typeStats = await AvailabilityNotification.aggregate([
      { $match: { recipient: userId } },
      {
        $group: {
          _id: '$type',
          count: { $sum: 1 }
        }
      }
    ]);
    
    const priorityStats = await AvailabilityNotification.aggregate([
      { $match: { recipient: userId, status: { $ne: 'archived' } } },
      {
        $group: {
          _id: '$priority',
          count: { $sum: 1 }
        }
      }
    ]);
    
    return res.status(200).json({
      success: true,
      message: "Notification statistics fetched successfully",
      data: {
        statusStats: stats,
        typeStats,
        priorityStats
      }
    });
    
  } catch (error) {
    console.error("Get notification stats error:", error);
    return res.status(500).json({
      success: false,
      message: "Server Error",
      error: error.message
    });
  }
};

// Send availability reminder to therapists (admin function)
const sendAvailabilityReminder = async (req, res) => {
  try {
    const { therapistIds, message } = req.body;
    const adminId = req.user.id;
    
    if (req.user.role !== 'admin') {
      return res.status(403).json({
        success: false,
        message: "Only admins can send availability reminders"
      });
    }
    
    let targetTherapists = [];
    
    if (therapistIds && Array.isArray(therapistIds)) {
      // Send to specific therapists
      targetTherapists = await User.find({
        _id: { $in: therapistIds },
        role: 'doctor'
      });
    } else {
      // Send to all therapists who haven't updated availability in the last week
      const oneWeekAgo = new Date();
      oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);
      
      const availabilities = await TherapistAvailability.find({
        updatedAt: { $lt: oneWeekAgo }
      }).populate('therapist');
      
      targetTherapists = availabilities.map(av => av.therapist);
    }
    
    const notifications = [];
    
    for (const therapist of targetTherapists) {
      const notification = await AvailabilityNotification.createAvailabilityChangeNotification({
        recipientId: therapist._id,
        senderId: adminId,
        type: 'availability_reminder',
        metadata: {
          customMessage: message,
          sentBy: 'admin'
        }
      });
      
      notifications.push(notification);
    }
    
    return res.status(200).json({
      success: true,
      message: `Availability reminders sent to ${targetTherapists.length} therapists`,
      data: {
        sentCount: notifications.length,
        targetTherapists: targetTherapists.map(t => ({
          id: t._id,
          name: t.fullname,
          email: t.email
        }))
      }
    });
    
  } catch (error) {
    console.error("Send availability reminder error:", error);
    return res.status(500).json({
      success: false,
      message: "Server Error",
      error: error.message
    });
  }
};

module.exports = {
  getUserNotifications,
  markNotificationAsRead,
  markAllNotificationsAsRead,
  archiveNotification,
  getActionRequiredNotifications,
  getNotificationStats,
  sendAvailabilityReminder
};
