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

// @desc    Get order items for an order
// @route   GET /api/orders/:orderId/items
// @access  Private
exports.getOrderItems = 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 these order items
    if (req.user.role === 'user' && order.user_id.toString() !== req.user.id) {
      return res.status(403).json({ 
        success: false, 
        msg: 'Not authorized to view these order items' 
      });
    }
    
    const orderItems = await OrderItem.getByOrder(req.params.orderId);
    res.json({ success: true, data: orderItems });
  } catch (error) {
    console.error('Error fetching order items:', error);
    res.status(500).json({ success: false, msg: 'Server error' });
  }
};

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

  try {
    const { item_id, quantity } = req.body;
    
    // Verify the order exists and is in a modifiable state
    const order = await Order.findById(req.params.orderId);
    
    if (!order) {
      return res.status(404).json({ success: false, msg: 'Order not found' });
    }
    
    // Check if order can be modified
    if (['completed', 'cancelled', 'shipped'].includes(order.status)) {
      return res.status(400).json({ 
        success: false, 
        msg: 'Cannot modify a completed, cancelled, or shipped order' 
      });
    }
    
    // Get item details
    const item = await Item.findById(item_id);
    if (!item) {
      return res.status(404).json({ success: false, msg: 'Item not found' });
    }
    
    // Check if item is already in the order
    const existingItems = await OrderItem.getByOrder(req.params.orderId);
    const existingItem = existingItems.find(i => i.item_id === parseInt(item_id));
    
    let orderItem;
    
    if (existingItem) {
      // Update quantity if item already exists in order
      const newQuantity = existingItem.quantity + parseInt(quantity);
      
      // Update the existing order item
      await OrderItem.update(existingItem.id, { 
        quantity: newQuantity,
        total_price: newQuantity * existingItem.unit_price
      });
      
      orderItem = await OrderItem.findById(existingItem.id);
    } else {
      // Create new order item
      const totalPrice = item.sales_price * quantity;
      
      orderItem = await OrderItem.create({
        order_id: req.params.orderId,
        item_id: item.id,
        item_name: item.name,
        quantity,
        unit_price: item.sales_price,
        total_price: totalPrice,
        tax_amount: 0, // Calculate tax if needed
        discount_amount: 0 // Apply discounts if needed
      });
    }
    
    // Update order totals
    await Order.updateTotals(req.params.orderId);
    
    res.status(201).json({ 
      success: true, 
      data: orderItem,
      msg: 'Item added to order successfully' 
    });
  } catch (error) {
    console.error('Error adding item to order:', error);
    res.status(500).json({ success: false, msg: 'Error adding item to order' });
  }
};

// @desc    Update order item quantity
// @route   PUT /api/order-items/:id
// @access  Private
exports.updateOrderItem = async (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ success: false, errors: errors.array() });
  }

  try {
    const { quantity } = req.body;
    
    // Get the order item
    const orderItem = await OrderItem.findById(req.params.id);
    if (!orderItem) {
      return res.status(404).json({ success: false, msg: 'Order item not found' });
    }
    
    // Get the order to check permissions and status
    const order = await Order.findById(orderItem.order_id);
    
    if (!order) {
      return res.status(404).json({ success: false, msg: 'Order not found' });
    }
    
    // Check if user is authorized
    if (req.user.role === 'user' && order.user_id.toString() !== req.user.id) {
      return res.status(403).json({ 
        success: false, 
        msg: 'Not authorized to update this order item' 
      });
    }
    
    // Check if order can be modified
    if (['completed', 'cancelled', 'shipped'].includes(order.status)) {
      return res.status(400).json({ 
        success: false, 
        msg: 'Cannot modify a completed, cancelled, or shipped order' 
      });
    }
    
    // If quantity is 0, remove the item
    if (parseInt(quantity) <= 0) {
      await OrderItem.delete(req.params.id);
      
      // Update order totals
      await Order.updateTotals(orderItem.order_id);
      
      return res.json({ 
        success: true, 
        msg: 'Item removed from order',
        data: null
      });
    }
    
    // Update the order item
    const totalPrice = orderItem.unit_price * quantity;
    
    await OrderItem.update(req.params.id, { 
      quantity,
      total_price: totalPrice
    });
    
    // Update order totals
    await Order.updateTotals(orderItem.order_id);
    
    const updatedItem = await OrderItem.findById(req.params.id);
    
    res.json({ 
      success: true, 
      data: updatedItem,
      msg: 'Order item updated successfully' 
    });
  } catch (error) {
    console.error('Error updating order item:', error);
    res.status(500).json({ success: false, msg: 'Error updating order item' });
  }
};

// @desc    Remove item from order
// @route   DELETE /api/order-items/:id
// @access  Private
exports.removeOrderItem = async (req, res) => {
  try {
    // Get the order item
    const orderItem = await OrderItem.findById(req.params.id);
    if (!orderItem) {
      return res.status(404).json({ success: false, msg: 'Order item not found' });
    }
    
    // Get the order to check permissions and status
    const order = await Order.findById(orderItem.order_id);
    
    if (!order) {
      return res.status(404).json({ success: false, msg: 'Order not found' });
    }
    
    // Check if user is authorized
    if (req.user.role === 'user' && order.user_id.toString() !== req.user.id) {
      return res.status(403).json({ 
        success: false, 
        msg: 'Not authorized to remove this order item' 
      });
    }
    
    // Check if order can be modified
    if (['completed', 'cancelled', 'shipped'].includes(order.status)) {
      return res.status(400).json({ 
        success: false, 
        msg: 'Cannot modify a completed, cancelled, or shipped order' 
      });
    }
    
    // Delete the order item
    await OrderItem.delete(req.params.id);
    
    // Update order totals
    await Order.updateTotals(orderItem.order_id);
    
    res.json({ 
      success: true, 
      msg: 'Item removed from order successfully' 
    });
  } catch (error) {
    console.error('Error removing order item:', error);
    res.status(500).json({ success: false, msg: 'Error removing order item' });
  }
};
