const OrderStatusHistory = require('../models/OrderStatusHistory');
const Order = require('../models/Order');
const { validationResult } = require('express-validator');

// @desc    Get status history for an order
// @route   GET /api/orders/:orderId/status-history
// @access  Private
exports.getOrderStatusHistory = async (req, res) => {
  try {
    // First verify the order exists and user has permission
    const order = await Order.findById(req.params.orderId);
    
    if (!order) {
      return res.status(404).json({ success: false, msg: 'Order not found' });
    }
    
    // Check if user is authorized to view this order's history
    if (req.user.role === 'user' && order.user_id.toString() !== req.user.id) {
      return res.status(403).json({ 
        success: false, 
        msg: 'Not authorized to view this order\'s status history' 
      });
    }
    
    const history = await OrderStatusHistory.getByOrder(req.params.orderId);
    res.json({ success: true, data: history });
  } catch (error) {
    console.error('Error fetching order status history:', error);
    res.status(500).json({ success: false, msg: 'Server error' });
  }
};

// @desc    Add status update to order
// @route   POST /api/orders/:orderId/status-history
// @access  Private/Admin,Staff
exports.addOrderStatusUpdate = async (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ success: false, errors: errors.array() });
  }

  try {
    const { status, notes } = req.body;
    
    // Verify the order exists
    const order = await Order.findById(req.params.orderId);
    if (!order) {
      return res.status(404).json({ success: false, msg: 'Order not found' });
    }
    
    // Get the current status to prevent duplicates
    const currentStatus = order.status;
    
    // If status hasn't changed and no notes are provided, no need to update
    if (status === currentStatus && !notes) {
      return res.status(400).json({ 
        success: false, 
        msg: 'Status has not changed and no notes provided' 
      });
    }
    
    // Add to status history
    const statusUpdate = await OrderStatusHistory.create({
      order_id: req.params.orderId,
      status: status || currentStatus, // Use current status if not provided
      notes: notes || `Status updated to ${status || currentStatus}`
    });
    
    // Update the order status if it's different
    if (status && status !== currentStatus) {
      await Order.updateStatus(req.params.orderId, status);
    }
    
    res.status(201).json({ 
      success: true, 
      data: statusUpdate,
      msg: 'Order status updated successfully' 
    });
  } catch (error) {
    console.error('Error updating order status:', error);
    res.status(500).json({ success: false, msg: 'Error updating order status' });
  }
};

// @desc    Get orders by status
// @route   GET /api/status-history/status/:status
// @access  Private/Admin,Staff
exports.getOrdersByStatus = async (req, res) => {
  try {
    const { status } = req.params;
    const { startDate, endDate } = req.query;
    
    // Validate status
    const validStatuses = [
      'pending', 'confirmed', 'processing', 'shipped', 
      'delivered', 'cancelled', 'returned', 'refunded'
    ];
    
    if (!validStatuses.includes(status)) {
      return res.status(400).json({ 
        success: false, 
        msg: 'Invalid status' 
      });
    }
    
    const orders = await OrderStatusHistory.getOrdersByStatus(status, startDate, endDate);
    
    res.json({ 
      success: true, 
      data: orders,
      count: orders.length
    });
  } catch (error) {
    console.error('Error fetching orders by status:', error);
    res.status(500).json({ success: false, msg: 'Server error' });
  }
};

// @desc    Get latest status for multiple orders
// @route   POST /api/status-history/latest-status
// @access  Private
exports.getLatestStatusForOrders = async (req, res) => {
  try {
    const { orderIds } = req.body;
    
    if (!Array.isArray(orderIds) || orderIds.length === 0) {
      return res.status(400).json({ 
        success: false, 
        msg: 'Please provide an array of order IDs' 
      });
    }
    
    // Get latest status for each order
    const statusPromises = orderIds.map(orderId => 
      OrderStatusHistory.getLatestStatus(orderId)
    );
    
    const statuses = await Promise.all(statusPromises);
    
    // Create a map of orderId to status
    const statusMap = {};
    statuses.forEach((status, index) => {
      statusMap[orderIds[index]] = status || { status: 'unknown' };
    });
    
    res.json({ 
      success: true, 
      data: statusMap
    });
  } catch (error) {
    console.error('Error fetching latest status for orders:', error);
    res.status(500).json({ success: false, msg: 'Server error' });
  }
};
