const mongoose = require("mongoose");
const orderModel = require("../models/order");
const productModel = require("../models/productModel");

const createOrder = async (req) => {
    // const data = req.body;
    // return data
    const newOrder = new orderModel(req.body);
    const result = await newOrder.save()
    const order = await orderModel.findById({_id: result._id}).populate("product.productId").populate({
        path: "shopId",
        select: "barName shopImage"
    });
    return order;
};

const getOrderById = async (req) => {
    const { orderId } = req.query;
    const order = await orderModel.findById({_id: orderId}).populate({
        path: "product.productId",
    }).populate({
        path: "shopId",
        select: "barName shopImage"
    }).populate({
        path: "userId",
        select: "fullName profileImage"
    });
    return order;
};

const getAllordersByUserId = async (req) => {
    const { userId, status } = req.query;
    const filter = { userId };
    if(status !== undefined && status !== null && status !== ""){
        filter.status = status
    }

    const order = await orderModel.find(filter).populate("product.productId").populate({
        path: "shopId",
        select: "barName shopImage"
    });
    return order;
};

const getAllOrdersByAdminId = async (req) => {
    const { adminId, status } = req.query;
    const filter = { adminId };
    if(status !== undefined && status !== null && status !== ""){
        filter.status = status;
    };
    const order = await orderModel.find(filter).populate({
        path: "userId",
        select: "fullName profileImage"
    });
    return order
};

const updateOrderStatus = async (req) => {
    const { orderId, status } = req.query;

    const order = await orderModel.findByIdAndUpdate({_id: orderId},
        { $set: { status: status}},
        { new: true }
    );
    return order;
};

const deleteOrder = async (req) => {
    const { orderId } = req.query;
    const order = await orderModel.findByIdAndDelete({_id: orderId});
    return order
};

const udpateProductInventory = async (products) => {
    const updates = products.map(({ productId, quantity}) => ({
        updateOne: {
            filter: { _id: productId},
            update: { $inc: { StockQuantity: -quantity }}
        }
    }));
    const result = await productModel.bulkWrite(updates);
    console.log("Updated Procuts :", result);
};

const updateOrder = async (req) => {
    const { orderId } = req.query;
    const updatedData = req.query;

    const order = await orderModel.findByIdAndUpdate(orderId, 
        { $set: updatedData },
        { new: true }
    );
    return order;
};

const getAllOrders = async (req) => {
    const { userId, adminId, status } = req.query;

    const filter = {};

    if(userId){
        filter.userId = userId
    };

    if(adminId){
        filter.adminId = adminId
    };
    
    if(status){
        filter.status = status
    };

    const orders = await orderModel.find(filter).populate({
        path: "userId",
        select: "fullName profileImage"  
    }).populate({
        path: "shopId",
        select: "barName shopImage"
    }).populate("product.productId")

    return orders
};

const vendorStatistics = async (req) => {
    const { adminId } = req.query;
    const totalCustomers = await orderModel.find({adminId: adminId}).countDocuments();
    const newCustmoers = await orderModel.distinct("userId", { adminId: adminId }).countDocuments();

    const result = await orderModel.aggregate([
        { $match: { adminId: new mongoose.Types.ObjectId(adminId) } }, // filter by admin
        {
            $group: {
            _id: null, // no grouping key, just sum across all
            totalGrandTotal: { $sum: "$grandTotal" }
            }
        }
    ]);

    const totalGrandTotal = result.length > 0 ? result[0].totalGrandTotal : 0;

    const monthlyRevenue = await orderModel.aggregate([
        { $match: { adminId: new mongoose.Types.ObjectId(adminId) } },
        {
            // Convert string "DD-MM-YYYY" to date
            $addFields: {
              orderDate: {
                $dateFromString: {
                  dateString: "$date",
                  format: "%d-%m-%Y"
                }
              }
            }
          },
          {
            // Group by year and month
            $group: {
              _id: { 
                year: { $year: "$orderDate" },
                month: { $month: "$orderDate" }
              },
              totalGrandTotal: { $sum: "$grandTotal" } // sum grandTotal per month
            }
          },
          {
            // Format output
            $project: {
              year: "$_id.year",
              month: "$_id.month",
              totalGrandTotal: 1,
              _id: 0
            }
          },
          { $sort: { year: 1, month: 1 } } // sort by time
    ]);

    const statsData = {
        totalCustomers: totalCustomers,
        newCustmoers: newCustmoers,
        monthlyRevenue: monthlyRevenue,
        TotalRevenue: totalGrandTotal
    }; 
    return statsData;
};

module.exports = {
    createOrder,
    getOrderById,
    getAllordersByUserId,
    getAllOrdersByAdminId,
    updateOrderStatus,
    deleteOrder,
    udpateProductInventory,
    updateOrder,
    getAllOrders,
    vendorStatistics
};