
const CafeOrder = require('../models/CafeOrder');
const CafeOrderDetail = require('../models/CafeOrderDetail');
const User = require('../models/User'); // Import User model
const Item = require('../models/Item'); // Import Item model
const LogActivity = require('../models/LogActivity'); // Import
const PaymentHistory = require('../models/PaymentHistory'); // Import PaymentHistory model
const category = require('../models/Category'); // Import
const BranchInventory = require('../models/BranchInventory'); // Import
const mongoose = require('mongoose');

const { ObjectId } = mongoose.Types;
// Create a new cafe order

exports.updateOrderTable = async (req, res) => {
  try {
    const { orderId, tableNo } = req.query;

  console.log(req.query);
    const order = await CafeOrder.findById(orderId);

    if (!order) {
      return res.status(404).json({ message: "Order not found." });
    }

    order.tableNo = tableNo;
    await order.save();

    return res.status(200).json({ message: "Order table number updated successfully." });
  } catch (error) {
    console.error(error);
    return res.status(500).json({ message: "An error occurred while updating the order." });
  }
};


exports.createPaymentHistory = async (req, res) => {
  try {


const {paid,credit,customerId,description}=req.body;
console.log(req.body);
    const newPaymentHistory = new PaymentHistory({paid,credit,customerId,description});
    const savedPaymentHistory = await newPaymentHistory.save();
    res.status(201).json(savedPaymentHistory);
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: 'Error creating payment history' });
  }
};

exports.payOrder = async (req, res) => {
  try {
    const { orderId, customerId,userId,branchId ,waiterName} = req.query;

   console.log("send data is",req.query);
    const order = await CafeOrder.findById(orderId);

    if (order.status === "paid" || order.status === "cancelled") {
      return res.status(400).json({ 
        success: false, 
        message: `Order is already ${order.status}.`
      });
    }

    // Fetch order details and populate item information
    const orderDetails = await CafeOrderDetail.find({ orderId }).populate('itemId');
    if (!orderDetails || orderDetails.length === 0) {
      return res.status(404).json({ message: 'Order details not found.' });
    }

    // Check if all items are served
    for (const detail of orderDetails) {
      if (detail.quantity > detail.kitchenServedQty) {
        return res.status(400).json({ message: 'All items in the order are not served yet.' });
      }
    }


    // pre check if stock is available for foods which needs stock 

    for (const detail of orderDetails) {
     
      if (detail.itemId.needStock) {
        const branchInventory = await BranchInventory.findOne({
          branchId,
          itemId: detail.itemId._id
        });
        
        console.log("Branch inventory detail is", branchInventory);
        
        if (!branchInventory || branchInventory.quantity < detail.quantity) {

          console.log(`Insufficient stock for item ${detail.itemId.name}. ` +
                     `Available: ${branchInventory ? branchInventory.quantity : 0}, ` +
                     `Requested: ${detail.quantity}`);

          return res.status(400).json({
            success: false,
            message: `Insufficient stock for item ${detail.itemId.name}. ` +
                     `Available: ${branchInventory ? branchInventory.quantity : 0}, ` +
                     `Requested: ${detail.quantity}`
          });
        }
      }
    }
    

    for (const detail of orderDetails) {
      if (detail.itemId.needStock) {

        const branchInventory = await BranchInventory.findOneAndUpdate(
            {branchId, // the branch must be included to deduct from the quantity, else it will not work, becasue the branch quantity holds based on branch specific
             itemId: detail.itemId._id },
          { $inc: { quantity: -detail.quantity } },
          { new: true }
        );
       }
    }

   // Calculate the total amount for the order
   const totalAmount = orderDetails.reduce((sum, detail) => {
    return sum + (detail.itemId.selling_price * detail.quantity);
  }, 0);


    // Check if the customer exists
    if (customerId && customerId !== "undefined" && customerId !== "null"&& customerId !=='') {
      console.log(`Customer is: ${customerId}`);
      order.customerId = customerId;
      order.paymentType = "credit";


 
    // Record the payment in payment history
    const newPaymentHistory = new PaymentHistory({
      credit: totalAmount,
      customerId,
    });
    await newPaymentHistory.save();


    } else {
      console.error("Invalid customerId: Value is null, undefined, or not provided.");
    }
    
    // Associate the customer with the order and mark as paid
   
    order.status = 'paid';
    
    await order.save();
// save log activity
  



    const logActivity = new LogActivity({
      action: 'paid',
      orderId,
      paidAmount: totalAmount,
    userId,
    waiterName
    });
    await logActivity.save();



    res.status(200).json({ message: 'Order paid successfully.' });
  } catch (error) {
    console.error('Error paying order:', error);
    res.status(500).json({ message: 'Failed to pay order.', error: error.message });
  }
};



// Cancel Order
exports.cancelOrder = async (req, res) => {
  try {
    const { orderId,userId,userType } = req.query;


    const order = await CafeOrder.findById(orderId);

    const isOrderFinalized = order.status === "paid" || order.status === "cancelled";
    const isNotAdmin = userType !== "ADMIN";
    
    if (isOrderFinalized && isNotAdmin) {
      return res.status(400).json({
        success: false,
        message: `Order is already ${order.status}.`,
      });
    }
    
    // Validate input
    if (!orderId) {
      return res.status(400).json({ message: 'Order ID is required.' });
    }

    // Find the order by ID and update status to "cancelled"
   order.status = 'cancelled';
   await order.save();

   const logActivity = new LogActivity({
    action: 'cancelled',
    orderId,
  userId,
  });
  await logActivity.save();
   
    res.status(200).json({ message: 'Order cancelled successfully.', order });
  } catch (error) {
    console.error('Error cancelling order:', error);
    res.status(500).json({ message: 'Failed to cancel order.', error: error.message });
  }
};

// Resume Order
exports.resumeOrder = async (req, res) => {
  try {
    const { orderId ,userId} = req.query;


    const order = await CafeOrder.findById(orderId);

    if (order.status === "paid") {
      return res.status(400).json({ 
        success: false, 
        message: `Order is already ${order.status}.`
      });
    }

   

    // Find the order by ID and update status to "pending"
    order.status = 'pending';
    await order.save();

    const logActivity = new LogActivity({
      action: 'resumed',
      orderId,
      userId,
    
    });
    await logActivity.save();
    res.status(200).json({ message: 'Order resumed successfully.', order });
  } catch (error) {
    console.error('Error resuming order:', error);
    res.status(500).json({ message: 'Failed to resume order.', error: error.message });
  }
};



exports.serveOrder = async (req, res) => {
  try {
    const { orderId, items } = req.body;

   
    const order = await CafeOrder.findById(orderId);

    if (order.status === "paid" || order.status === "cancelled") {
      return res.status(400).json({ 
        success: false, 
        message: `Order is already ${order.status}.`
      });
    }


    // Validate input
    if (!orderId || !items || items.length === 0) {
      return res.status(400).json({ success: false, message: 'Invalid order or items data.' });
    }

    // Iterate over the items and increment the `kitchenServedQty`
    for (const item of items) {
      const { itemId, remaining } = item;

      // Validate the data
      if (remaining <= 0) {
        throw new Error(`Invalid remaining quantity for item with ID ${itemId}.`);
      }

      // Fetch the existing item from the database
      const existingItem = await CafeOrderDetail.findOne({ orderId, itemId }).populate('itemId');
      if (!existingItem) {
        throw new Error(`Item with ID ${itemId} not found in order ${orderId}.`);
      }

      // Check if incrementing will exceed the ordered quantity
      if (existingItem.kitchenServedQty + remaining > existingItem.quantity) {
        throw new Error(
          `Cannot increment served quantity for item with ID ${itemId}. ` +
          `Current served: ${existingItem.kitchenServedQty}, Requested increment: ${remaining}, Ordered: ${existingItem.quantity}`
        );
      }



// include only for items who need  attachment

        // Check if incrementing will not exceed the attached ordered quantity
        if (itemId.attachmentReq==true&&(remaining > existingItem.attachmentServedQty-existingItem.kitchenServedQty)) {
          throw new Error(
            `Cannot increment served quantity for item with ID ${itemId}. ` +
            `Current attachmnet served: ${existingItem.attachmentServedQty}, Requested increment: ${remaining}, Ordered: ${existingItem.quantity}`
          );
        }
  

      // Increment the `kitchenServedQty`
       existingItem.kitchenServedQty += remaining;
       existingItem.servedAt = new Date();
      await existingItem.save();
    }

    // Respond with success
    res.status(200).json({ success: true, message: 'Quantities updated successfully!' });
  } catch (error) {
    console.error('Error updating quantities:', error.message);
    res.status(500).json({ success: false, message: error.message });
  }
};






exports.serveAttachment = async (req, res) => {
  try {
    const { orderId, items } = req.body;
    console.log(orderId, items)




    const order = await CafeOrder.findById(orderId);

    if (order.status === "paid" || order.status === "cancelled") {
      return res.status(400).json({ 
        success: false, 
        message: `Order is already ${order.status}.`
      });
    }
    
    // Proceed with your logic here
    


    // Validate input
    if (!orderId || !items || items.length === 0) {
      return res.status(400).json({ success: false, message: 'Invalid order or items data.' });
    }

    // Iterate over the items and increment the `kitchenServedQty`
    for (const item of items) {
      const { itemId, remaining } = item;

      // Validate the data
      if (remaining <= 0) {
        throw new Error(`Invalid remaining quantity for item with ID ${itemId}.`);
      }

      // Fetch the existing item from the database
      const existingItem = await CafeOrderDetail.findOne({ orderId, itemId }).populate('itemId');
      if (!existingItem) {
        throw new Error(`Item with ID ${itemId} not found in order ${orderId}.`);
      }

      // Check if incrementing will exceed the ordered quantity
      if (existingItem.attachmentServedQty + remaining > existingItem.quantity) {
        throw new Error(
          `Cannot increment attachment served quantity for item with ID ${itemId}. ` +
          `Current served: ${existingItem.attachmentServedQty}, Requested increment: ${remaining}, Ordered: ${existingItem.quantity}`
        );
      }

      // Increment the `attachmentServedQty`
       existingItem.attachmentServedQty += remaining;
       existingItem.attachmentServedAt = new Date();
// if food items is from attachment(siga bet) consider it as strore item and allow direct sell
// means update kitchen served quantity directly
       if(existingItem.itemId.type==='attachment')
       {
        existingItem.kitchenServedQty += remaining;
        existingItem.servedAt = new Date();


       }

      await existingItem.save();
    }

    // Respond with success
    res.status(200).json({ success: true, message: 'Attachment  Served successfully!' });
  } catch (error) {
    console.error('Error updating quantities:', error.message);
    res.status(500).json({ success: false, message: error.message });
  }
};











exports.createOrder = async (req, res) => {
  try {

    console.log('Creating order',req.body);


  
    const { companyId, branchId, userId, items, tableNo } = req.body.orders;

    // Define start and end of the current day
    const startDate = new Date().setUTCHours(0, 0, 0, 0);
    const endDate = new Date().setUTCHours(23, 59, 59, 999);

    // Get the maximum order number for the day
    const maxOrder = await CafeOrder.findOne({
      companyId,
      branchId,
      createdAt: { $gte: new Date(startDate), $lte: new Date(endDate) },
    })
      .sort({ orderNo: -1 })
      .select('orderNo');

    const orderNo = maxOrder ? maxOrder.orderNo + 1 : 1;

    // Create and save the main order
    const order = await new CafeOrder({
      companyId,
      branchId,
      orderNo,
      tableNo: tableNo || 0, // Default to 0 if tableNo is not provided
      userId,
    }).save();

    // Process and save each order item
    const orderDetails = items.map((item) => ({
      orderId: order._id, // Use the newly created order ID
      itemId: item.itemId,
      quantity: item.quantity,
      specialNeeds: item.specialNeeds||[],
    }));

    await CafeOrderDetail.insertMany(orderDetails); // Efficiently insert all items at once

    res.status(200).json({ success: true, message: 'Order created successfully!', orderNo, orderId: order._id });
  } catch (error) {
    console.error('Error during order creation:', error.message);
    res.status(500).json({ success: false, message: 'Error creating order', error: error.message });
  }};

  exports.updateOrder = async (req, res) => {
    const { items, orderId } = req.body;




      const session = await mongoose.startSession(); // Start a new session
    session.startTransaction(); // Start a transaction
  
    try {


      const order = await CafeOrder.findById(orderId);

      if (order.status === "paid" || order.status === "cancelled") {
        return res.status(400).json({ 
          success: false, 
          message: `Order is already ${order.status}.`
        });
      }
  
      
      // Fetch the previous order details (returns an array of orders)
      const previousOrders = await CafeOrderDetail.find({ orderId }).session(session);
  
      
     

      for (const order of previousOrders) {
        const orderExists = items.find(
          (item) => item.itemId.toString() === order.itemId.toString()
        );
      
        if (!orderExists) {
          // Check if the item has been served before deletion
          if (order.kitchenServedQty > 0 || order.attachmentServedQty > 0) {
            throw new Error(
              `Cannot delete item with ID ${order._id} because it has been served. ` +
              `Kitchen served quantity: ${order.kitchenServedQty}, ` +
              `Attachment served quantity: ${order.attachmentServedQty}`
            );
          }
          
          // Delete the order if it doesn't exist in the current items list and hasn't been served
          await CafeOrderDetail.findByIdAndDelete(order._id, { session });
        }
      }
      

     
      for (const item of items) {
        const existingOrder = previousOrders.find(
          (order) => order.itemId.toString() === item.itemId.toString()
        );
  
        if (!existingOrder) {
          // Add new item if it doesn't exist
          const newOrder = new CafeOrderDetail({
            orderId,
            itemId: item.itemId,
            quantity: item.quantity,
            attachmentServedQty: 0,
            kitchenServedQty: 0,
          });
  
          await newOrder.save({ session });
        } else {
          // Validate and update existing item
  
          // Check if the new quantity is valid
          if (item.quantity < existingOrder.attachmentServedQty) {
            throw new Error(
              `Cannot decrease quantity below attachment served quantity for item with ID ${existingOrder._id}. ` +
              `Attachment served quantity: ${existingOrder.attachmentServedQty}, ` +
              `Requested quantity: ${item.quantity}`
            );
          }
  
          if (item.quantity < existingOrder.kitchenServedQty) {
            throw new Error(
              `Cannot decrease quantity below kitchen served quantity for item with ID ${existingOrder._id}. ` +
              `Kitchen served quantity: ${existingOrder.kitchenServedQty}, ` +
              `Requested quantity: ${item.quantity}`
            );
          }
  
          if (item.quantity < 0) {
            throw new Error(`Quantity cannot be negative for item with ID ${existingOrder._id}.`);
          }
  
          // Update quantity
          existingOrder.quantity = item.quantity;
  
          // Save updated document
          await existingOrder.save({ session });
        }
      }
  
      // Commit the transaction if all updates succeed
      await session.commitTransaction();
      console.log("Order details updated successfully.");
      res.status(200).json({ success: true, message: "Order details updated successfully!" });
    } catch (error) {
      // Abort the transaction if any update fails
      await session.abortTransaction();
      console.error("Error updating order details:", error.message);
      res.status(500).json({ success: false, message: error.message });
    } finally {
      // End the session
      session.endSession();
    }
  };
  

// exports.updateOrder =  async (req, res) => {


//   const { items ,orderId} = req.body; // Array of { itemId, quantity }

//   const session = await mongoose.startSession();
//   session.startTransaction();
  
//   try {
//     const updatePromises = items.map(async (item) => {
//       const existingItem = await CafeOrderDetail.findById(item.orderDetailId).session(session);
  
//       if (!existingItem) {
//         throw new Error(`Item with ID ${item.orderDetailId} not found.`);
//       }
  
//       const servedQuantity = existingItem.servedQuantity || 0;
  
//       if (item.quantity < servedQuantity) {
//         throw new Error(`Cannot decrease quantity below served quantity for item with ID ${item.orderDetailId}.`);
//       }
  
//       if (item.quantity < 0) {
//         throw new Error(`Quantity cannot be negative for item with ID ${item.orderDetailId}.`);
//       }
  
//       await CafeOrderDetail.findByIdAndUpdate(item.orderDetailId, { quantity: item.quantity }, { session });
//     });
  
//     await Promise.all(updatePromises);
//     await session.commitTransaction();
//     console.log("All items updated successfully.");
//   } catch (error) {
//     await session.abortTransaction();
//     console.error("Transaction aborted due to error:", error);
//   } finally {
//     session.endSession();
//   }


//   // try {
//   //   const { items ,orderId} = req.body; // Array of { itemId, quantity }

//   //   const prvOrder =await CafeOrderDetail.find(orderId:orderId)

//   //   const updatePromises = items.map(async (item) => {
//   //     try {
//   //       if (item.quantity <prvOrder.quantity) {
//   //         throw new Error(`Cannot decrease quantity of an item. Current quantity: ${prvOrder.quantity}, requested quantity: ${item.quantity}`);
//   //       }
//   //       await CafeOrderDetail.findByIdAndUpdate(item.orderDetailId, { quantity: item.quantity });
//   //     } catch (error) {
//   //       console.error(`Failed to update item with ID ${item.orderDetailId}:`, error);
//   //     }
//   //   });
//   //   await Promise.all(updatePromises);
    

//   //   res.status(200).json({ success: true, message: 'Order details updated successfully!' });
//   // } catch (error) {
//   //   console.error('Error updating order details:', error.message);
//   //   res.status(500).json({ success: false, message: 'Error updating order details' });
//   // }
// }








// Get all cafe orders
// exports.getAllOrders = async (req, res) => {
//   try {
//     const{companyId,branchId}=req.query;
//     const orders = await CafeOrder.aggregate([
//       {
//         $match: {
//         //  companyId: companyId, // Optional filter (if needed)
//         //  branchId: branchId,   // Optional filter (if needed)
//         },
//       },
//       {
//         $sort: { createdAt: -1 }, // Sort by creation date (most recent first)
//       },
//       {
//         $lookup: {
//           from: 'cafeorderdetails', // Name of the collection for order details
//           localField: '_id',        // Field in `CafeOrder` to match
//           foreignField: 'orderId',  // Field in `CafeOrderDetail` to match
//           as: 'items',              // Alias for the joined data
//         },
//       },
//       {
//         $project: {
//           orderNo: 1,
//           tableNo: 1,
//           branchId: 1,
//           userId: 1,
//           createdAt: 1,
//           items: {
//             _id: 1, 
//             itemId: 1,
//             quantity: 1,
//             kitchenServedQty:1,
//             attachmentServedQty:1,
           
//           },
//         },
//       },
//     ]);
    
//     res.status(200).json({ success: true, data: orders });
//   } catch (error) {
//     res.status(500).json({ success: false, error: error.message });
//   }
// };      




// exports.getAllOrders = async (req, res) => {
//   try {
//     // Step 1: Fetch all orders and populate userId
//     const orders = await CafeOrder.find({})
//       .sort({ createdAt: -1 }) // Sort by creation date (most recent first)
//       .populate({
//         path: 'userId',
//         select: 'name', // Only include the user's name
//       })
//       .lean(); // Convert Mongoose documents to plain JavaScript objects

//     // Step 2: Fetch all order details and populate itemId
//     const orderDetails = await CafeOrderDetail.find({})
//       .populate({
//         path: 'itemId',
//         select: 'name', // Only include the item's name
//       })
//       .lean();

//     // Step 3: Merge orders and orderDetails locally
//     const mergedOrders = orders.map((order) => {
//       // Find all order details that match the current order's _id
//       const items = orderDetails
//         .filter((detail) => detail.orderId.toString() === order._id.toString())
//         .map((detail) => ({
//           _id: detail._id,
//           itemId: detail.itemId._id,
//           itemName: detail.itemId.name, // Include item name
//           quantity: detail.quantity,
//           kitchenServedQty: detail.kitchenServedQty,
//           attachmentServedQty: detail.attachmentServedQty,
//         }));

//       // Return the order with its items
//       return {
//         _id: order._id,
//         orderNo: order.orderNo,
//         tableNo: order.tableNo,
//         branchId: order.branchId,
//         userId: order.userId._id,
//         userName: order.userId.name, // Include user name
//         createdAt: order.createdAt,
//         items: items,
//       };
//     });

//     // Step 4: Send the merged data to the frontend
//     res.status(200).json({ success: true, data: mergedOrders });
//   } catch (error) {
//     res.status(500).json({ success: false, error: error.message });
//   }
// };






exports.getAllOrders = async (req, res) => {
  try {
    const { companyId, userId } = req.query;

    console.log(companyId, userId);

    let objectUserId;
    if (userId && userId !== "undefined" && userId !== "null") {
      objectUserId = new mongoose.Types.ObjectId(userId);
    }

    const objectCompanyId = new mongoose.Types.ObjectId(companyId);
    // Set start and end of the current day in UTC
    const startDate = new Date(new Date().setUTCHours(0, 0, 0, 0));
    const endDate = new Date(new Date().setUTCHours(23, 59, 59, 999));

    // Query conditions
    const matchConditions = {
      // transferStatus: {
      //   $in: ['returned', 'accepted', '', 'rejected'] // Match any of these values
      // },
      createdAt: { $gte: startDate, $lte: endDate }, // Ensure date range matches today
    };
console.log("user id is",userId);
    // Conditionally include userId if it's defined and not null
    if (userId && userId !== "undefined" && userId !== "null") {
       matchConditions.userId = objectUserId;
    }
    if (objectCompanyId) {
      matchConditions.companyId = objectCompanyId;
    }

   const orders = await CafeOrder.aggregate([
      {
        $match: matchConditions
      },
      {
        $sort: { createdAt: -1 }, // Sort by creation date (most recent first)
      },
      {
        $lookup: {
          from: 'cafeorderdetails', // Join with order details collection
          localField: '_id',
          foreignField: 'orderId',
          as: 'items',
        },
      },
      {
        $lookup: {
          from: 'items', // Join with items collection to get item details
          let: { itemIds: '$items.itemId' }, // Define variables for the subpipeline
          pipeline: [
            {
              $match: {
                $expr: { $in: ['$_id', '$$itemIds'] }, // Match items by itemId
              },
            },
            {
              $project: {
                _id: 1,
                name: 1, // Include item name
                selling_price: 1, // Include sellingPrice
                attachmentReq: 1, // Include attachmentReq
                defaultItemType: 1, // Include defaultItemType
                kitchenId: 1, // Include kitchenId
              },
            },
          ],
          as: 'itemDetails',
        },
      },
      {
        $lookup: {
          from: 'users', // Join with users collection to get user details
          localField: 'userId',
          foreignField: '_id',
          as: 'userDetails',
        },
      },
      {
        $addFields: {
          items: {
            $map: {
              input: '$items', // Iterate over the items array
              as: 'item',
              in: {
                $mergeObjects: [
                  '$$item',
                  {
                    itemName: {
                      $arrayElemAt: [
                        {
                          $map: {
                            input: {
                               $filter: {
                                input: '$itemDetails',
                                as: 'detail',
                                cond: { $eq: ['$$detail._id', '$$item.itemId'] },
                              },
                            },
                            as: 'filteredDetail',
                            in: '$$filteredDetail.name', // Extract item name
                          },
                        },
                        0,
                      ],
                    },
                    selling_price: {
                      $arrayElemAt: [
                        {
                          $map: {
                            input: {
                              $filter: {
                                input: '$itemDetails',
                                as: 'detail',
                                cond: { $eq: ['$$detail._id', '$$item.itemId'] },
                              },
                            },
                            as: 'filteredDetail',
                            in: '$$filteredDetail.selling_price', // Extract sellingPrice
                          },
                        },
                        0,
                      ],
                    },
                    attachmentReq: {
                      $arrayElemAt: [
                        {
                          $map: {
                            input: {
                              $filter: {
                                input: '$itemDetails',
                                as: 'detail',
                                cond: { $eq: ['$$detail._id', '$$item.itemId'] },
                              },
                            },
                            as: 'filteredDetail',
                            in: '$$filteredDetail.attachmentReq', // Extract attachmentReq
                          },
                        },
                        0,
                      ],
                    },
                    defaultItemType: {
                      $arrayElemAt: [
                        {
                          $map: {
                            input: {
                              $filter: {
                                input: '$itemDetails',
                                as: 'detail',
                                cond: { $eq: ['$$detail._id', '$$item.itemId'] },
                              },
                            },
                            as: 'filteredDetail',
                            in: '$$filteredDetail.defaultItemType', // Extract defaultItemType
                          },
                        },
                        0,
                      ],
                    },
                    kitchenId: {
                      $arrayElemAt: [
                        {
                          $map: {
                            input: {
                              $filter: {
                                input: '$itemDetails',
                                as: 'detail',
                                cond: { $eq: ['$$detail._id', '$$item.itemId'] },
                              },
                            },
                            as: 'filteredDetail',
                            in: '$$filteredDetail.kitchenId', // Extract kitchenId
                          },
                        },
                        0,
                      ],
                    },
                  },
                ],
              },
            },
          },
          userName: { $arrayElemAt: ['$userDetails.username', 0] }, // Add user name
        },
      },
      {
        $project: {
          orderNo: 1,
          tableNo: 1,
          branchId: 1,
          userId: 1,
          userName: 1, // Include user name in the final output
          transferFrom: 1,
          createdAt: 1,
          updatedAt: 1,
          status: 1,
          items: {
            _id: 1,
            itemId: 1,
            itemName: 1, // Include item name in the final output
            selling_price: 1, // Include sellingPrice in the final output
            attachmentReq: 1, // Include attachmentReq
            defaultItemType: 1, // Include defaultItemType
            kitchenId: 1, // Include kitchenId in the final output
            quantity: 1,
            kitchenServedQty: 1,
            attachmentServedQty: 1,
            specialNeeds: 1,
            createdAt: 1,
            servedAt: 1, // Include servedAt field
            attachmentServedAt: 1, // Include attachmentServedAt field
          },
        },
      },
    ]);

   console.log("orders are", orders.items);
    res.status(200).json({ success: true, data: orders });
  } catch (error) {
    res.status(500).json({ success: false, error: error.message });
  }
};



exports.getAllOrdersForAttachment = async (req, res) => {
  try {
    const { companyId, branchId } = req.query;

 const startDate = new Date(new Date().setUTCHours(0, 0, 0, 0));
const endDate = new Date(new Date().setUTCHours(23, 59, 59, 999));

    const orders = await CafeOrder.aggregate([
      {
        $match: {
          createdAt: { $gte: startDate, $lte: endDate }, // Ensure date range matches today
        },
      },
      {
        $sort: { createdAt: -1 }, // Sort by creation date (most recent first)
      },
      {
        $lookup: {
          from: 'cafeorderdetails', // Join with order details collection
          localField: '_id',
          foreignField: 'orderId',
          as: 'items',
        },
      },
      {
        $lookup: {
          from: 'items', // Join with items collection to get item details
          let: { itemIds: '$items.itemId' }, // Define variables for the subpipeline
           pipeline: [
            {
              $match: {
                $expr: { $in: ['$_id', '$$itemIds'] }, // Match items by itemId
              },
            },
            {
              $project: {
                _id: 1,
                name: 1, // Include item name
                attachmentReq: 1, // Include attachmentReq
                defaultItemType: 1, // Include defaultItemType
              },
            },
          ],
          as: 'itemDetails',
        },
      },
      {
        $lookup: {
          from: 'users', // Join with users collection to get user details
          localField: 'userId',
          foreignField: '_id',
          as: 'userDetails',
        },
      },
      {
        $addFields: {
          items: {
            $map: {
              input: '$items', // Iterate over the items array
              as: 'item',
              in: {
                $mergeObjects: [
                  '$$item',
                  {
                    itemName: {
                      $arrayElemAt: [
                        {
                          $map: {
                            input: {
                              $filter: {
                                input: '$itemDetails',
                                as: 'detail',
                                cond: { $eq: ['$$detail._id', '$$item.itemId'] },
                              },
                            },
                            as: 'filteredDetail',
                            in: '$$filteredDetail.name', // Extract item name
                          },
                        },
                        0,
                      ],
                    },
                    attachmentReq: {
                      $arrayElemAt: [
                        {
                          $map: {
                            input: {
                              $filter: {
                                input: '$itemDetails',
                                as: 'detail',
                                cond: { $eq: ['$$detail._id', '$$item.itemId'] },
                              },
                            },
                            as: 'filteredDetail',
                            in: '$$filteredDetail.attachmentReq', // Extract attachmentReq
                          },
                        },
                        0,
                      ],
                    },
                    defaultItemType: {
                      $arrayElemAt: [
                        {
                          $map: {
                            input: {
                              $filter: {
                                input: '$itemDetails',
                                as: 'detail',
                                cond: { $eq: ['$$detail._id', '$$item.itemId'] },
                              },
                            },
                            as: 'filteredDetail',
                            in: '$$filteredDetail.defaultItemType', // Extract defaultItemType
                          },
                        },
                        0,
                      ],
                    },
                  },
                ],
              },
            },
          },
          userName: { $arrayElemAt: ['$userDetails.username', 0] }, // Add user name
        },
      },
      {
        $addFields: {
          items: {
            $filter: {
              input: '$items',
              as: 'item',
              cond: { $eq: ['$$item.attachmentReq', true] }, // Filter items with attachmentReq: true
            },
          },
        },
      },
      {
        $match: {
          items: { $ne: [] }, // Exclude orders with no items after filtering
        },
      },
      {
        $project: {
          orderNo: 1,
          tableNo: 1,
          branchId: 1,
          userId: 1,
          userName: 1, // Include user name in the final output
          createdAt: 1,
          updatedAt: 1,
          
          items: {
            _id: 1,
            itemId: 1,
            itemName: 1, // Include item name in the final output
            attachmentReq: 1, // Include attachmentReq
            defaultItemType: 1, // Include defaultItemType
            quantity: 1,
            kitchenServedQty: 1,
            attachmentServedQty: 1,
            specialNeeds: 1,
          },
        },
      },
    ]);
console.log("orders are",orders);
    res.status(200).json({ success: true, data: orders });
  } catch (error) {
    res.status(500).json({ success: false, error: error.message });
  }
};


exports.getLogActivity = async (req, res) => {
  try {
    // Fetch log activities, populate the orderId field, and sort by creation date (descending)
   
    const startDate = new Date(new Date().setUTCHours(0, 0, 0, 0));
const endDate = new Date(new Date().setUTCHours(23, 59, 59, 999));

 
  
       
   
const logs = await LogActivity.find(
  { timestamp: { $gte: startDate, $lte: endDate } }
)
.populate('orderId userId')
.sort({ timestamp: -1 });

res.status(200).json({
  success: true,
  logs,
});
  } catch (error) {
    console.error('Error fetching log activities:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to fetch log activities.',
      error: error.message,
    });
  }
};


exports.getBono = async (req, res) => {
  try {
    // Get startDate and endDate from query parameters, default to current date if not provided
    let startDate, endDate;
    
    if (req.query.startDate && req.query.endDate) {
      startDate = new Date(req.query.startDate);
      startDate.setUTCHours(0, 0, 0, 0);
      endDate = new Date(req.query.endDate);
      endDate.setUTCHours(23, 59, 59, 999);
    } else {
      // Default to current date
      startDate = new Date(new Date().setUTCHours(0, 0, 0, 0));
      endDate = new Date(new Date().setUTCHours(23, 59, 59, 999));
    }

    
    const orderDetails = await CafeOrderDetail.aggregate([
      {
        $match: {
          createdAt: { $gte: startDate, $lte: endDate } // Match documents within the date range
        }
      },
      {
        $group: {
          _id: "$itemId", // Group by itemId
          totalKitchenServedQty: { $sum: "$kitchenServedQty" } // Sum up kitchenServedQty
        }
      },
      {
        $match: {
          totalKitchenServedQty: { $gt: 0 }// Only include items where totalKitchenServedQty > 0
      
        }
      },
      {
        $lookup: {
          from: "items", // Assuming the collection name is 'items'
          localField: "_id", // itemId from CafeOrderDetail
          foreignField: "_id", // _id from the Item collection
          as: "itemDetails"
        }
      },
      {
        $unwind: {
          path: "$itemDetails",
          preserveNullAndEmptyArrays: true
        }
      },
      {
        $project: {
          itemId: "$_id",
          totalKitchenServedQty: 1,
          itemName: "$itemDetails.name", // Include item name from the related collection
          selling_price: "$itemDetails.selling_price", // Include selling_price from the Item collection
          totalSales: {
            $multiply: ["$totalKitchenServedQty", "$itemDetails.selling_price"]
          } // Calculate total sales (kitchenServedQty * selling_price)
        }
      },
      {
        $sort: {
          itemName: 1 // Sort by itemName in ascending order
        }
      }
    ]);
console.log("bono",orderDetails);
    res.status(200).json({
      success: true,
      data: orderDetails
    });
  } catch (error) {
    console.error("Error fetching data:", error);
    res.status(500).json({
      success: false,
      message: "Failed to fetch data",
      error: error.message
    });
  }
};


// const mongoose = require('mongoose');
//const CafeOrderDetail = require('./CafeOrderDetail');

exports.getDailySales = async (req, res) => {
  try {
    // Extract start and end dates from request query
    const { startDate, endDate } = req.query;
console.log(startDate, endDate);
    // Validate the presence of both dates
    if (!startDate || !endDate) {
      return res.status(400).json({ error: 'Both startDate and endDate are required.' });
    }

    const salesData = await CafeOrderDetail.aggregate([
      // Step 1: Lookup CafeOrder to filter by status
      {
        $lookup: {
          from: 'cafeorders', // Collection name for CafeOrder
          localField: 'orderId',
          foreignField: '_id',
          as: 'orderDetails'
        }
      },
      { $unwind: '$orderDetails' }, // Unwind the orderDetails array
      { $match: { 'orderDetails.status': 'paid' } }, // Filter only 'paid' orders

      // Step 2: Lookup Item to get selling_price
      {
        $lookup: {
          from: 'items', // Collection name for Item
          localField: 'itemId',
          foreignField: '_id',
          as: 'itemDetails'
        }
      },
      { $unwind: '$itemDetails' }, // Unwind the itemDetails array

      // Step 3: Calculate total sales for each item
      {
        $addFields: {
          totalItemSales: { $multiply: ['$itemDetails.selling_price', '$quantity'] },
          orderDate: {
            $dateToString: { format: '%Y-%m-%d', date: '$orderDetails.createdAt' }
          }
        }
      },

      // Step 4: Filter by the provided date range (by orderDate)
      {
        $match: {
          orderDate: {
            $gte: startDate,
            $lte: endDate
          }
        }
      },

      // Step 5: Group by each day and sum up the daily sales
      {
        $group: {
          _id: '$orderDate', // Group by order date
          dailyTotalSales: { $sum: '$totalItemSales' }
        }
      },

      // Step 6: Sort results by date (ascending order)
      { $sort: { _id: 1 } }
    ]);

    // Send response with sales data
    res.status(200).json(salesData);
  } catch (error) {
    console.error('Error fetching daily sales:', error);
    res.status(500).json({ error: 'An error occurred while calculating sales.' });
  }
};



// Fetch orders by time interval
exports.fetchOrders = async (req, res) => {
  try {
    const { startDate, endDate } = req.query;

  
    if (!startDate || !endDate) {
      return res.status(400).json({ success: false, message: 'Start and end dates are required.' });
    }

   // Convert to Date objects and set UTC hours
const start = new Date(startDate);
start.setUTCHours(0, 0, 0, 0); // Set to the start of the UTC day (00:00:00.000)

const end = new Date(endDate);
end.setUTCHours(23, 59, 59, 999); // Set to the end of the UTC day (23:59:59.999)

    const orders = await CafeOrder.find({
      createdAt: {
        $gte: new Date(start),
        $lte: new Date(end),
      },
    }).select('orderNo status'); // Select only orderNo and status fields

    res.status(200).json({ success: true, data: orders });
  } catch (error) {
    console.error('Error fetching orders:', error);
    res.status(500).json({ success: false, message: 'An error occurred while fetching orders.' });
  }
};



// Delete all orders and their details based on time interval
exports.deleteAllOrders = async (req, res) => {
  try {
    const { startDate, endDate } = req.body; // Expecting dates in the request body

    if (!startDate || !endDate) {
      return res.status(400).json({ success: false, message: 'Start and end dates are required.' });
    }


   // Convert to Date objects and set UTC hours
   const start = new Date(startDate);
   start.setUTCHours(0, 0, 0, 0); // Set to the start of the UTC day (00:00:00.000)
   
   const end = new Date(endDate);
   end.setUTCHours(23, 59, 59, 999); // Set to the end of the UTC day (23:59:59.999)
   

    // Find all orders within the interval
    const orders = await CafeOrder.find({
      createdAt: {
        $gte: new Date(start),
        $lte: new Date(end),
      },
    });

    if (orders.length === 0) {
      return res.status(404).json({ success: false, message: 'No orders found in the given interval.' });
    }

    // Extract all order IDs
    const orderIds = orders.map(order => order._id);

    // Delete all related CafeOrderDetail entries
    await CafeOrderDetail.deleteMany({ orderId: { $in: orderIds } });

    // Delete all orders
    await CafeOrder.deleteMany({ _id: { $in: orderIds } });

    res.status(200).json({ success: true, message: 'All orders and related details deleted successfully.' });
  } catch (error) {
    console.error('Error deleting orders:', error);
    res.status(500).json({ success: false, message: 'An error occurred while deleting the orders.' });
  }
};
