const Cart = require('../models/cartModel'); const Product = require('../models/productModel'); // add to cart function exports.addToCart = async (req, res) => { try { const userId = req.user.id; const { productId, quantity } = req.body; const product = await Product.findById(productId); if (!product) { return res.status(404).json({ message: 'Product not found' }); } let cart = await Cart.findOne({ user: userId }); if (!cart) { cart = await Cart.create({ user: userId, items: [{ product: productId, quantity }], }); } else { const existingItem = cart.items.find( (item) => item.product.toString() === productId, ); if (existingItem) { existingItem.quantity += quantity; } else { cart.items.push({ product: productId, quantity }); } await cart.save(); } // Populate product details before returning await cart.populate({ path: 'items.product', select: 'nameAr nameEn price salePrice imageCover stock', }); res.status(200).json({ status: 'success', message: 'Product added to cart', cart, }); } catch (err) { res .status(500) .json({ message: 'Failed to add product', error: err.message }); } }; exports.getCart = async (req, res) => { try { const userId = req.user.id; // Find the cart associated with the user const cart = await Cart.findOne({ user: userId }).populate({ path: 'items.product', select: 'nameAr nameEn price salePrice imageCover', }); if (!cart || cart.items.length === 0) { return res.status(200).json({ status: 'success', message: 'Cart is empty', cart: { items: [] }, }); } // Calculate the total price const totalPrice = cart.items.reduce((acc, item) => { const price = item.product.salePrice || item.product.price; return acc + price * item.quantity; }, 0); res.status(200).json({ status: 'success', cart, totalPrice, }); } catch (err) { res .status(500) .json({ message: 'Failed to fetch cart', error: err.message }); } }; // PATCH /samoulla/v1/cart/update-quantity exports.updateQuantity = async (req, res) => { try { const userId = req.user.id; const { productId, action } = req.body; const cart = await Cart.findOne({ user: userId }).populate({ path: 'items.product', select: 'nameAr nameEn price salePrice imageCover', }); if (!cart) { return res.status(404).json({ message: 'Cart not found' }); } const cartItem = cart.items.find( (el) => el.product._id.toString() === productId, ); if (!cartItem) { return res.status(404).json({ message: 'Product not found in cart' }); } if (action === 'increase') { cartItem.quantity += 1; } else if (action === 'decrease') { cartItem.quantity -= 1; if (cartItem.quantity <= 0) { cart.items = cart.items.filter( (el) => el.product._id.toString() !== productId, ); } } else { return res.status(400).json({ message: 'Invalid action' }); } await cart.save(); const totalPrice = cart.items.reduce((acc, item) => { const price = item.product.salePrice || item.product.price; return acc + price * item.quantity; }, 0); res.status(200).json({ status: 'success', cart, totalPrice, }); } catch (err) { res .status(500) .json({ message: 'Error updating quantity', error: err.message }); } }; // PATCH /samoulla/v1/cart/update-quantity // { // "productId": "ID_OF_PRODUCT", // "action": "increase" // } // { // "productId": "ID_OF_PRODUCT", // "action": "decrease" // } // DELETE /samoulla/v1/cart/remove-item exports.removeFromCart = async (req, res) => { try { const userId = req.user.id; const { productId } = req.params; const cart = await Cart.findOne({ user: userId }).populate({ path: 'items.product', select: 'nameAr nameEn price salePrice imageCover', }); if (!cart) { return res.status(404).json({ message: 'Cart not found' }); } const itemExists = cart.items.find( (el) => el.product._id.toString() === productId, ); if (!itemExists) { return res.status(404).json({ message: 'Product not found in cart' }); } cart.items = cart.items.filter( (el) => el.product._id.toString() !== productId, ); await cart.save(); const totalPrice = cart.items.reduce((acc, item) => { const price = item.product.salePrice || item.product.price; return acc + price * item.quantity; }, 0); res.status(200).json({ status: 'success', message: 'Product removed from cart', cart, totalPrice, }); } catch (err) { res .status(500) .json({ message: 'Error removing product', error: err.message }); } }; exports.clearCart = async (req, res) => { try { const cart = await Cart.findOne({ user: req.user._id }); if (!cart) { return res.status(404).json({ message: 'Cart not found' }); } cart.items = []; await cart.save(); res.status(200).json({ status: 'success', message: 'Cart cleared successfully', cart, }); } catch (err) { res .status(500) .json({ message: 'Something went wrong', error: err.message }); } }; // GET /samoulla/v1/cart/all (Admin only) exports.getAllCarts = async (req, res) => { try { // Find all carts that are not empty and belong to a user const carts = await Cart.find({ user: { $exists: true, $ne: null }, items: { $exists: true, $not: { $size: 0 } }, }) .populate({ path: 'user', select: 'name email phone', }) .populate({ path: 'items.product', select: 'nameAr nameEn price salePrice imageCover', }) .sort('-updatedAt'); res.status(200).json({ status: 'success', results: carts.length, data: { carts, }, }); } catch (err) { res.status(500).json({ status: 'error', message: 'Failed to fetch carts', error: err.message, }); } }; // DELETE /samoulla/v1/cart/:id (Admin only) exports.deleteCart = async (req, res) => { try { const cart = await Cart.findByIdAndDelete(req.params.id); if (!cart) { return res.status(404).json({ status: 'fail', message: 'No cart found with that ID', }); } res.status(204).json({ status: 'success', data: null, }); } catch (err) { res.status(500).json({ status: 'error', message: 'Failed to delete cart', error: err.message, }); } };