const mongoose = require("mongoose");
const Order = mongoose.model("Orders");
const User = mongoose.model("User");
const WareHouse = mongoose.model("WareHouses");
const supplierCode = mongoose.model("SupplierCode");
const bcrypt = require("bcryptjs");
const BillHistory = mongoose.model("BillHistorys");
const Adminuser = mongoose.model("Adminuser");
const MainTag  = mongoose.model("MainTag");      
const Products = mongoose.model("Products");
const Category = mongoose.model("Category");
const CsvUpload = mongoose.model("CsvUpload");
const Transaction = mongoose.model("Transaction");
const BrowseNodes = mongoose.model("BrowseNodes");
const Orderprioritys = mongoose.model("Orderprioritys");
const CategoryDesc = mongoose.model("CategoryDesc");
const ObjectsToCsv = require("objects-to-csv");
const moment = require("moment-timezone");
const { mongooseConstantValues } = require("../../apps/common/systemConstents");

const {
  updateShopperrPriceAlgo,
  getMsrp,
} = require("../../apps/middlewares/priceAlgo");
const { userValidation } = require("../../validation");

const AWS = require("aws-sdk");
const _ = require("lodash");
var fs = require("fs");
const { Parser } = require("json2csv");

const csv = require("csvtojson");
// const ID = "AKIAVQ3EX433FYE7SGHW";
// const SECRET = "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";
const ID = "AKIAZQ3DPSAOW34EMAWP";
const SECRET = "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";
// const ID = process.env.AWS_ACCESS_KEY_ID;
// const SECRET = process.env.AWS_SECRET_ACCESS_KEY;

const BUCKET_NAME = "test-bucket";
const s3 = new AWS.S3({
  accessKeyId: ID,
  secretAccessKey: SECRET,
  apiVersion: "latest",
});

exports.AdminProfile = async (req, res) => {
  try {
    let adminData = await Adminuser.findOne(
      { _id: mongoose.Types.ObjectId(req.params.admin_id) },
      { password: 0 }
    );
    adminData = JSON.parse(JSON.stringify(adminData));
    // let supplierIds = adminData.supplier.map((el)=>mongoose.Types.ObjectId(el.supplier));
    //
    adminData.supplier = await Adminuser.find(
      { _id: { $in: adminData.supplier } },
      { supplier_id: 1 }
    ).then((supplierUser) => {
      return supplierUser.map((el) => el.supplier_id);
    });
    res.status(200).send({ error: 0, items: adminData });
  } catch (err) {
    return res.status(500).send({ error: 1, message: err.toString() });
  }
};
// exports.orderTicketDetail = async(req,res) => {
//     const{orderSerial, orderConsumerPrice, refundType, comments } = req.body;

//   const newOrder = new Order({
//     orderSerial,
//     orderConsumerPrice,
//     refundType,
//     comments,
//   });

//   try {
//     await newOrder.save();
//     res.status(200).json({ message: 'Ticket Detail Added Successfully' });
//   } catch (error) {
//     console.error('Error saving order:', error);
//     res.status(500).json({ message: 'Failed to add ticket detail', error: error.message });
//   }
// }

exports.AdminAccountUpdate = async (req, res) => {
  const updateUser = {
    name: req.body.name,
    email: req.body.email,
    phoneNo: req.body.phone,
    username: req.body.name,
  };
  //console.log(updateUser)
  try {
    //   if (req.body.password) {
    //     const salt = await bcrypt.genSalt(10);
    //     const hashPassword = await bcrypt.hash(req.body.password, salt);
    //     updateUser.password = hashPassword;
    //   }

    const data = await Adminuser.findOneAndUpdate(
      { _id: req.body.id },
      { $set: updateUser },
      { new: true }
    );
    return res.send("success");
  } catch (error) {
    return res.status(500).send(error.toString());
  }
};

exports.getSubAdmin = async (req, res) => {
  const adminData = await Adminuser.find(
    {},
    { name: 1, email: 1, category: 1 }
  );
  res.send({ error: 0, items: adminData, totalCount: adminData.length });
};

exports.supplierFullDetails = async (req, res) => {
  bar.then((data) => {
    return res.send(data);
  });
};

const newFunction = async () => {
  const supplierData = await User.find({ category: "supplier" }).sort({
    created_on: -1,
  });
  let suppObj = {};

  const result = await supplierData.map(async (data, i) => {
    var supplierArr = [];

    // let revenue =  await revenueSupplier(data._id);
    // let order =  await orderSupplier(data._id);
    // let product = await productLength(data._id)
    return {
      id: data._id,
      supplier_id: data.supplier_id,

      name: data.name,
      email: data.email,
      order: 0,
      revenue: 0,
      product: 0,
    };
  });
  return await Promise.all(result);
};

exports.OrderReply = async (req, res) => {
  const { userId } = req.params;
  Order.findById(userId, (err, order) => {
    if (err) {
      console.error(err);
      res.status(500).send("Error finding order");
    } else {
      order.replies.push({ text: replyText });

      order.save((err, savedOrder) => {
        if (err) {
          console.error(err);
          res.status(500).send("Error saving reply");
        } else {
          res.status(200).json(savedOrder);
        }
      });
    }
  });
};

exports.adminPaymentSupplier = async (req, res) => {
  const data = await newFunction();
  let result = data;
  let transData = await Transaction.find();
  let firstArr = [];
  transData.forEach((item, i) => {
    firstArr.push({
      supplier_id: item.supplier_id,
      amount: item.amount_paid,
    });
  });

  var holder = {};
  firstArr.forEach(function (d) {
    if (holder.hasOwnProperty(d.supplier_id)) {
      holder[d.supplier_id] = holder[d.supplier_id] + d.amount;
    } else {
      holder[d.supplier_id] = d.amount;
    }
  });

  var obj2 = [];
  for (var prop in holder) {
    obj2.push({ supplier_id: prop, amount: holder[prop] });
  }

  let resultArray = await result;
  obj2.forEach((trans, z) => {
    resultArray.forEach((res, y) => {
      if (obj2[z].supplier_id === resultArray[y].id.toString()) {
        resultArray[y].amount = obj2[z].amount;
      }
    });
  });
  return res.send(resultArray);
};
exports.adminTransactionDetail = async (req, res) => {
  const tranaction = await new Transaction({
    supplier_id: req.body.supplier_id,
    trans_id: req.body.trans_id,
    amount_paid: req.body.amount_paid,
    pmethod: req.body.pmethod,
    date: req.body.date,
    time: req.body.time,
  });
  try {
    const saveTransaction = await tranaction.save();
    return res.send("success");
  } catch (error) {
    return res.status(500).send(error.toString());
  }
};

exports.getTransaction = async (req, res) => {
  const page = parseInt(req.query.page);
  const limit = parseInt(req.query.limit);
  const startIndex = (page - 1) * limit;
  const endIndex = page * limit;
  const results = {};

  let query = {};
  
  try {

    if (req.query.text) {
      // query.inv_number = req.query.text; 

      query = {
          $or: [
              { email: req.query.text },
              { trans_id: req.query.text },
              { phone: req.query.text },
          ]
      };
    }

    if (req.query.orderdateFrom) {
    
      query.createdDate = {
          $gte: new Date(req.query.orderdateFrom+'T00:00:00.000Z'),
          $lt: new Date(req.query.orderdateTo+'T23:59:59Z')
      }
          
  }
    
    const transactionCount = await Transaction.countDocuments(query).exec();
    results.count = transactionCount;
    results.startIndex = startIndex;
    if (endIndex < transactionCount) {
      results.next = {
        page: page + 1,
        limit: limit,
      };
    }
    if (startIndex > 0) {
      results.previous = {
        page: page - 1,
        limit: limit,
      };
    }
    // console.log(startIndex)
    let data = await Transaction.find(query)
    .sort({ _id: -1 })  // Sorting in descending order by _id
    .skip(startIndex)   // Skipping documents based on the startIndex
    .limit(limit)       // Add the limit to restrict the number of documents returned
    .exec();

    // console.log(data);

    // let userData = await User.find();
    // let finalData = [];
    // let email = '';
    let orderData = await Promise.all(data.map(async(item, i) => {
      
      // userData.forEach((item1, index) => {
      //   console.log(data[i].supplier_id, userData[index].email)
      //   if (data[i].supplier_id === userData[index]._id.toString()) {
      //     email = userData[index].email
      //     data[i].supplier_id = userData[index].supplier_id;
      //     data[i].email = userData[index].email;
      //   }

        // });

        let userData = await User.findOne({
          _id: mongoose.Types.ObjectId(item.user_id),
        });

        // console.log(item)

        return {
          supplier_id: item.supplier_id,
          trans_id: item.trans_id ? item.trans_id : "0",
          amount_paid: item.amount_paid,
          pmethod: item.pmethod,
          createdAt: item.createdAt,
          createdDate: item.createdDate,
          // 'email' : userData?userData.email:'',
          email: item.email ? item.email : userData.email,
          orderId: item.order_id,
          _id: item._id,
          phone: item.phone,
        };

        // finalData.push(obj)
        // // console.log(finalData)
        // return finalData;
      })
    );
    results.results = orderData;
    // console.log(orderData)
    // console.log(finalData)

    // console.log(data);
    return res.send(results);
  } catch (e) {
    return res.status(500).send(e.toString());
  }
};

exports.adminAddwarehouse = async (req, res) => {
  var fileContent = req.files?.pincode.data;
  var name = req.body.name;
  var address = req.body.address;
  var city = req.body.city;
  var state = req.body.state;
  var country = req.body.country;
  var status = req.body.status;
  var priority = req.body.priority;
  var mobile = req.body.mobile;
  var phone = req.body.phone;
  var code = req.body.code;
  var pincodeflag = req.body.pincodeflag;

  if (fileContent !== undefined) {
    WareHouse.findOne({
      wc: code,
    })
      .then((result) => {
        if (result) {                            
          res.json({ errors: "Warehouse code already exists" });
          // res.send('warehouse code need to be unique')
        } else {          
          var d = new Date();
          const s3dir =
            "import_export/" +
            d.getFullYear().toString() +
            "/" +
            (d.getMonth() + 1).toString() +
            "/";    
          var filename = "upload" + makeid(6) + "_" + code + ".csv";
          var fullPath = s3dir + filename;

          uploadExcel(fileContent, s3dir + filename).then(async () => {
            var url = process.env.S3_BUCKET_FILE_URL;
            const wareCsv = await new WareHouse({
              wn: name,
              wa: address,
              wcty: city,
              ws: state,
              wct: country,
              wst: status,
              wpr: priority,
              wm: mobile,
              wph: phone,
              wc: code,
              wp: url + "/" + fullPath,
              wpf: pincodeflag,
            });
            // console.log('This is warecsv : ',wareCsv)
            const history = await new pinHistory({
              wn: name,
              wc: code,
              wp: url + "/" + fullPath,
            });
            try {
              const saveProduct = await wareCsv.save();
              const historyPin = await history.save();
              res.json({ saveProduct: saveProduct, historyPin: saveProduct });
              // res.send('success');
            } catch (err) {
              res.send("something went wrong");
              console.log(err);
            }
          });
        }
      })
      .catch((err) => {
        console.log(err);
      });
  } else {
    WareHouse.findOne({
      wc: code,
    })
      .then((result) => {
        // console.log('code found', result)
        if (result) {
          // console.log('warehouse code not unique')
          res.json({ errors: "Warehouse code already exists" });
          // res.send('warehouse code need to be unique')
        } else {
          console.log("here is eneter else");

          const wareCsv = new WareHouse({
            wn: name,
            wa: address,
            wcty: city,
            ws: state,
            wct: country,
            wst: status,
            wpr: priority,
            wm: mobile,
            wph: phone,
            wc: code,
            wp: "file not uploaded",
            wpf: pincodeflag,
          });
          wareCsv
            .save()
            .then((wareCsv) => {
              res.json(wareCsv);
            })
            .catch((err) => {
              res.json(err);
            });
        }
      })
      .catch((err) => {
        console.log(err);
      });
  }
};

exports.viewwarehouses = (req, res) => {
  // console.log(res.paginatedResults)
  let temp = [];
  for (let i = 0; i < res.paginatedResults.results.length; i++) {
    temp.push(res.paginatedResults.results[i]);
  }
  return res.status(200).send({ items: temp, totalCount: res.totalCount });
};

exports.deleteWare = async (req, res) => {
  WareHouse.findOneAndDelete({ _id: req.params.id })
    .then((result) => {
      return res.status(200).send("deleted");
    })
    .catch((err) => {
      console.log(err);
      return res.status(400).send("2");
    });
};
async function getNameOfTagId(tagIds) {
	return new Promise(function (resolve, reject) {
		const promises = []
		tagIds.map((tag) => {
			promises.push(getName(tag))
		})

		Promise.all(promises)
			.then((tagArr) => {
				resolve(tagArr)
			})
			.catch((e) => {
				console.log(e)
				reject(e)
			})
	})
}

async function getName(id) {
	return new Promise(function (resolve, reject) {
		MainTag.findOne({ _id: id })
			.then((tagArr) => {
				resolve(tagArr.tag)
			})
			.catch((e) => {
				console.log(e)
				reject(e)
			})
	})
}
exports.getSelectedCategory = async (req, res) => {
  Category.findOne({ _id: req.params.id })
    .then(async (result1) => {
      let result = {
        _id: result1._id,
        category: result1.category,
        subCategory: _.isEmpty(result1.subCategory) ? "" : result1.subCategory,
        description: _.isEmpty(result1.description) ? "" : result1.description,
        categoryImage: _.isEmpty(result1.categoryImage)
          ? ""
          : result1.categoryImage.src,
        mobileFlag: result1.mobileFlag,
        websiteFlag: result1.websiteFlag,
        keyword: _.isEmpty(result1.keyword)
          ? []
          : await getNameOfTagId(result1.keyword),
        code: result1.code,
        node: result1[mongooseConstantValues.PRODUCT_BROWSE_NODE],
      };
      return res
        .status(200)
        .send({ url: process.env.S3_BUCKET_FILE_URL, result });
    })
    .catch((err) => {
      console.log(err);
      return res.status(400).send(err.toString());
    });
};

/*exports.OrderList = async (req, res) => {
  const page = parseInt(req.query.page) || 1;
  const limit = parseInt(req.query.limit) || 10;
  const startIndex = (page - 1) * limit;
  const endIndex = page * limit;
  const results = {};
  let query = { isDelete: false };

  if (req.query.fromDate && req.query.toDate) {
    query.created_on = {
      $gte: new Date(req.query.fromDate),
      $lt: new Date(req.query.toDate),
    };
  }
  if (req.query.text) {
    query.orderId = req.query.text;
  }
  if (req.query.storeDomain) {
    query.storeDomain = req.query.storeDomain;
  }
  if (req.query.phoneNumber) {
    query["customer.phone"] = req.query.phoneNumber;
  }
  if (req.query.source) {
    query.source = req.query.source;
  }
  // console.log(query);

  try {
    const orderCount = await Order.countDocuments(query).exec();
    results.count = orderCount;
    results.startIndex = startIndex;
    if (endIndex < orderCount) {
      results.next = {
        page: page + 1,
        limit: limit,
      };
    }
    if (startIndex > 0) {
      results.previous = {
        page: page - 1,
        limit: limit,
      };
    }

    results.results = await Order.find(query)
      .sort({ _id: -1 })
      .limit(limit)
      .skip(startIndex)
      .exec();

    // Create a set to collect unique user IDs
    const userIds = new Set(results.results.map((order) => order.merchantId));
    const userMap = new Map();

    // Fetch all users in a single query
    const users = await User.find({ _id: { $in: Array.from(userIds) } }).exec();

    // Map users by their IDs
    users.forEach((user) => {
      userMap.set(user._id.toString(), user);
    });

    const orderData = [];
  
    const orderPromises = results.results.map(async (order) => {
        let sp = 0;
        let consumerPrice = 0;
  
        const promises = order.orderDetails.map(async (single) => {
          // console.log(single.consumerPrice)
          consumerPrice += single.consumerPrice
          
          const productData = await Products.find({code: single.sku});
          // console.log(productData.length)  
          // console.log(productData)  
            if(productData.length>0){
                
                if(productData[0].sp!=null){
                  return productData[0].sp;
                }else{
                  return productData[0].price;
                }

              }
             
        });
  
        const spValues = await Promise.all(promises);
        // console.log(spValues)
  
        spValues.forEach(spValue => {
            sp += spValue;
        });
  
        const user = userMap.get(order.merchantId.toString());
        if (user) {
            order.phone = user.phoneNo;
            order.customerFirstName = user.lName;
        }

        const dateStr = order.orderDate;
        const date = new Date(dateStr);
        
        // const formattedDate = `${date.getDate()}/${date.getMonth() + 1}/${date.getFullYear()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
        const formattedDate = `${date.getDate()}-${date.getMonth() + 1}-${date.getFullYear()}`;
        
  
        const obj = {
            currency: order.currency,
            shippingPhoneNumber: order.shippingPhoneNumber,
            shippingAddress1: order.shippingAddress1,
            shippingAddress2: order.shippingAddress2,
            shippingAddress3: order.shippingAddress3,
            pStatus: order.pStatus,
            oStatus: order.oStatus,
            sStatus: order.sStatus,
            dStatus: order.dStatus,
            rStatus: order.rStatus,
            commentStatus: order.commentStatus,
            disputeRole: order.disputeRole,
            trackingId: order.trackingId,
            paidDate: order.paidDate,
            shipDate: order.shipDate,
            ticketDate: order.ticketDate,
            cancelDate: order.cancelDate,
            processingDate: order.processingDate,
            deliveredDate: order.deliveredDate,
            shippingMethod: order.shippingMethod,
            fulfilmentsync: order.fulfilmentsync,
            source: order.source,
            isDelete: order.isDelete,
            _id: order._id,
            merchantId: order.merchantId,
            orderSerial: order.orderSerial,
            storeDomain: order.storeDomain,
            mkpOrderId: order.mkpOrderId,
            recipientName: order.recipientName,
            recipientEmail: order.recipientEmail,
            shippingCity: order.shippingCity,
            shippingState: order.shippingState,
            shippingPostalCode: order.shippingPostalCode,
            shippingCountry: order.shippingCountry,
            orderDetails: order.orderDetails,
            orderDate: formattedDate,
            order_shipping: order.order_shipping,
            createdAt: order.createdAt,
            updatedAt: order.updatedAt,
            consumerPrice: order.consumerPrice,
            order_dispute: order.order_dispute,
            shopperrPrice:sp,
            consumerPriceTotal:consumerPrice
        };
  
        orderData.push(obj);
    });
   
    await Promise.all(orderPromises);
  
    // Prepare the response object
    const response = {
      count: results.count,
      results: orderData,
      users: Array.from(userMap.values()), // Send the list of user objects
    };
    res.send(response);
  } catch (e) {
    res.status(500).json({ message: e.message });
  }
};*/

exports.OrderList = async (req, res) => {
  const page = parseInt(req.query.page) || 1;
  const limit = parseInt(req.query.limit) || 10;
  const startIndex = (page - 1) * limit;
  const endIndex = page * limit;
  const results = {};
  // let query = {};
  // let query = { $and: [] };
  let query = {  };

  if((req.query.fromDate || req.query.toDate) && !req.query.text && !req.query.searchOrderStatus && !req.query.process && !req.query.marketplace){
    query = {};
  }
  
  else if(req.query.text || req.query.fromDate || req.query.toDate || req.query.searchOrderStatus || req.query.process || req.query.marketplace){
    query = { $and: [] };
  }

 
  if (req.query.text) {
    
    const users1 = await User.findOne({ customer_logid: req.query.text }, {_id:1}).exec();

    if(users1){
      
      query.$and.push({
        $or: [
          { orderSerial: req.query.text },
          { mkpOrderId: req.query.text },
          { recipientName: req.query.text },
          { "order_shipping.os_tracking_no": req.query.text },
          { "orderDetails.sku": req.query.text },
          { merchantId: users1._id }
        ]
      });

    }else{
     
      query.$and.push({
        $or: [
          { orderSerial: req.query.text },
          { mkpOrderId: req.query.text },
          { recipientName: req.query.text },
          { "order_shipping.os_tracking_no": req.query.text },
          { "orderDetails.sku": req.query.text }
        ]
      });
    }

    
  }

  if (req.query.fromDate && req.query.toDate) {
    
    const startOfDayKolkata = moment.tz(`${req.query.fromDate} 00:00:00`, "YYYY-MM-DD HH:mm:ss", "Asia/Kolkata");
    const endOfDayKolkata = moment.tz(`${req.query.toDate} 23:59:59`, "YYYY-MM-DD HH:mm:ss", "Asia/Kolkata");
    
    query.orderDate = {
      $gte: startOfDayKolkata,
      $lt: endOfDayKolkata,
    };
  } else if (req.query.fromDate) {
    query.orderDate = {
      $gte: startOfDayKolkata,
    };
  } else if (req.query.toDate) {
    query.orderDate = {
      $lt: endOfDayKolkata,
    };
  }

  /*if (req.query.orderNumber) {
    query.orderSerial = req.query.orderNumber;
  }

  if (req.query.marketplaceOrderId) {
    query.mkpOrderId = req.query.marketplaceOrderId;
  }

  if (req.query.buyerLoginName) {
    query.recipientName = req.query.buyerLoginName;
  }

  if (req.query.trackingNumber) {
    query.trackingId = req.query.trackingNumber;
  }*/

  if (req.query.paymentStatus) {
    query.pStatus = req.query.paymentStatus;
  }

  if (req.query.shippingStatus) {
    query.sStatus = req.query.shippingStatus;
  }

  if (req.query.returnStatus) {
    query.rStatus = req.query.returnStatus;
  }

  if (req.query.sku) {
    query.orderDetails = {
      $elemMatch: { sku: new RegExp(req.query.sku, "i") },
    };
  }

  // if (req.query.text) {
  //   query.orderId = req.query.text;
  // }
  if (req.query.marketplace == 1) {
    query.storeDomain = "Amazon.in";
  }
  if (req.query.marketplace == 2) {
    query.storeDomain = "Shopify";
  }
  if (req.query.marketplace == 3) {
    query.storeDomain = "Shopperr (Dropship)";
  }
  if (req.query.phoneNumber) {
    query["customer.phone"] = req.query.phoneNumber;
  }

  //console.log(req.query.searchOrderStatus);
  
  if (req.query.searchOrderStatus) {
   
      query.$and.push({
        $or: [
          { pStatus: req.query.searchOrderStatus },
          { oStatus: req.query.searchOrderStatus },
          { sStatus: req.query.searchOrderStatus },
          { dStatus: req.query.searchOrderStatus },
          { rStatus: req.query.searchOrderStatus }
        ]
      });
 
  }

  if (req.query.process) {
    // query.inv_number = req.query.text;
    //order_dispute: { $exists: true, $ne: [] }
    
    // query = { chinaProcess: req.query.process };
    query.chinaProcess = req.query.process ;
    
    
  }
  // console.log(query);

  try {
    const orderCount = await Order.countDocuments(query).exec();
    results.count = orderCount;
    results.startIndex = startIndex;
    if (endIndex < orderCount) {
      results.next = {
        page: page + 1,
        limit: limit,
      };
    }
    if (startIndex > 0) {
      results.previous = {
        page: page - 1,
        limit: limit,
      };
    }

    results.results = await Order.find(query)
      .sort({ _id: -1 })
      .limit(limit)
      .skip(startIndex)
      .exec();

    const userIds = new Set(results.results.map((order) => order.merchantId));
    const userMap = new Map();

    const users = await User.find({ _id: { $in: Array.from(userIds) } }).exec();

    // Map users by their IDs
    users.forEach((user) => {
      userMap.set(user._id.toString(), user);
    });

    const orderData = [];

    const orderPromises = results.results.map(async (order) => {
      let sp = 0;
      let consumerPrice = 0;

      const promises = order.orderDetails.map(async (single) => {
        // console.log(single.consumerPrice)
        consumerPrice += single.consumerPrice;

        const productData = await Products.findOne(
          { code: single.sku },
          { sp: 1 }
        );
        return productData.sp;
      });

      const spValues = await Promise.all(promises);

      spValues.forEach((spValue) => {
        //console.log(spValue)
        sp += spValue;
      });

      const user = userMap.get(order.merchantId);
      if (user) {
        order.phone = user.phoneNo;
        order.customerFirstName = user.lName;
      }

      const obj = {
        currency: order.currency,
        shippingPhoneNumber: order.shippingPhoneNumber,
        shippingAddress1: order.shippingAddress1,
        shippingAddress2: order.shippingAddress2,
        shippingAddress3: order.shippingAddress3,
        pStatus: order.pStatus,
        oStatus: order.oStatus,
        sStatus: order.sStatus,
        dStatus: order.dStatus,
        rStatus: order.rStatus,
        commentStatus: order.commentStatus,
        disputeRole: order.disputeRole,
        trackingId: order.trackingId,
        paidDate: order.paidDate,
        shipDate: order.shipDate,
        ticketDate: order.ticketDate,
        cancelDate: order.cancelDate,
        processingDate: order.processingDate,
        deliveredDate: order.deliveredDate,
        shippingMethod: order.shippingMethod,
        fulfilmentsync: order.fulfilmentsync,
        source: order.source,
        isDelete: order.isDelete,
        _id: order._id,
        merchantId: order.merchantId,
        orderSerial: order.orderSerial,
        storeDomain: order.storeDomain,
        mkpOrderId: order.mkpOrderId,
        recipientName: order.recipientName,
        recipientEmail: order.recipientEmail,
        supplierId: order.supplierId,
        shippingCity: order.shippingCity,
        shippingState: order.shippingState,
        shippingPostalCode: order.shippingPostalCode,
        shippingCountry: order.shippingCountry,
        orderDetails: order.orderDetails,
        orderDate: order.orderDate,
        order_shipping: order.order_shipping,
        chinaProcess: order.chinaProcess,
        china1: order.china1,
        china2: order.china2,
        china3: order.china3,
        api_return_status: order.api_return_status,
        createdAt: order.createdAt,
        updatedAt: order.updatedAt,
        consumerPrice: order.consumerPrice,
        order_dispute: order.order_dispute,
        shopperrPrice: sp,
        consumerPriceTotal: consumerPrice,
      };

      orderData.push(obj);
    });

    await Promise.all(orderPromises);

    // Prepare the response object
    const response = {
      count: results.count,
      results: orderData,
      users: Array.from(userMap.values()), // Send the list of user objects
    };
    res.send(response);
  } catch (e) {
    res.status(500).json({ message: e.message });
  }
};

exports.GetProductFindBySku = async (req, res) => {
  try {
    Products.findOne({
      skus: req.query.sku,
    }).then((result) => {
      if (!_.isEmpty(result)) {
        let obj = {
          _id: result._id,
          image: _.isEmpty(result.imgUrl) ? "" : result.imgUrl[0].src,
          supplierName: "",
          name: result.name,
          invoiceDesc: result.invoicedesc,
          code: result.code,
          category: result.category,
          price: result.price,
          sellingPrice: result.selliingPrice,
          orders: 0,
          revenue: 0,
          productUrl:
            process.env.VIEW_PRODUCT_URL + "/product/" + result.handle,
        };
        res.status(200).send({ obj });
      } else {
        res.status(200).send("1");
      }
    });
  } catch (err) {
    console.log(err);
    res.status(500).send(err);
  }
};

exports.GetProducts = async (req, res) => {
  const page = parseInt(req.query.page);
  const limit = parseInt(req.query.limit);

  // console.log(req.query.query)

  const startIndex = (page - 1) * limit;
  const results = {};
  let totalCount = await Products.countDocuments(
    buildQuery(JSON.parse(req.query.query))
  ).exec();

  // console.log(buildQuery(JSON.parse(req.query.query)))

  results.results = await Products.find(
    buildQuery(JSON.parse(req.query.query)),
    {
      imgUrl: 1,
      supplier_id: 1,
      sid: 1,
      name: 1,
      code: 1,
      category: 1,
      price: 1,
      sp: 1,
      handle: 1,
      tags: 1,
      varients: 1,
      options: 1,
      shippingCharge: 1,
      prices: 1,
      stock: 1,
      channel: 1,
      spData: 1,
      mrp: 1,
      cogs: 1,
      quantity: 1,
      weight: 1,
      description: 1,
      size: 1,
      cat_id: 1,
      length: 1,
      width: 1,
      height: 1,
      pd_manage_status: 1,
      pd_status: 1,
      pd_location: 1,
      hsn: 1,
      uc_status: 1,
      marketPlaceMrp: 1,
      pex: 1,
      skus: 1,
      createdAt: 1,
    }
  )
    .sort({ is_delete: 1, _id: -1 })
    .limit(limit)
    .skip(startIndex)
    .exec();

  res.totalCount = totalCount;
  res.paginatedResults = results;
  try {
    const temp = await Promise.all(
      res.paginatedResults.results.map(async (item) => {
        const supplierId =
          item.supplier_id instanceof mongoose.Types.ObjectId
            ? item.supplier_id.toString()
            : item.supplier_id;
        const sid =
          item.sid instanceof mongoose.Types.ObjectId
            ? item.sid.toString()
            : item.sid;

        let imageUrl = "";
        if ((await getSupplierName(supplierId)) === "Fulfillmen") {
          imageUrl = item.imgUrl.length > 0 ? `${process.env.S3_BUCKET_FILE_URL}/${item.imgUrl[0].src}` : "";
        } else {
          imageUrl =
            item.imgUrl.length > 0
              ? `${process.env.S3_BUCKET_FILE_URL}/${item.imgUrl[0].src}`
              : "";
        }

        const categorydesc = await CategoryDesc.findOne(
          { category_id: item.cat_id },
          { cd_name: 1 }
        );

        return {
          _id: item._id,
          image: imageUrl,
          supplierName: await getSupplierName(supplierId),
          sid, // Return sid as a string
          supplier_id: supplierId, // Return supplier_id as a string
          name: item.name,
          code: item.code,
          category: categorydesc ? categorydesc.cd_name : "",
          price: item.price,
          sellingPrice: item.sp,
          orders: 0,
          revenue: 0,
          productUrl: `${process.env.VIEW_PRODUCT_URL}/product/${item.handle}`,
          globalProductUrl: `${process.env.GLOBAL_PRODUCT_URL}/product/${item.handle}`,
          imgUrl: item.imgUrl,
          tags: item.tags,
          varients: item.varients,
          options: item.options,
          shippingCharge: item.shippingCharge,
          prices: item.prices,
          stock: item.stock,
          channel: item.channel,
          spData: item.spData,
          mrp: item.mrp,
          cogs: item.cogs,
          quantity: item.quantity,
          weight: item.weight,
          description: item.description,
          size: item.size,
          cat_id: item.cat_id,
          length: item.length,
          width: item.width,
          height: item.height,
          pd_manage_status: item.pd_manage_status,
          pd_status: item.pd_status,
          pd_location: item.pd_location,
          uc_status: item.uc_status,
          marketPlaceMrp: item.marketPlaceMrp,
          pex: item.pex,
          skus: item.skus,
          createdAt: item.createdAt,
        };
      })
    );

    return res.status(200).send({
      url: process.env.S3_BUCKET_FILE_URL,
      items: temp,
      totalCount: res.totalCount,
    });
  } catch (err) {
    res
      .status(500)
      .send({ url: process.env.S3_BUCKET_FILE_URL, message: err.toString() });
  }
};

exports.Productsofapi = async (req, res) => {
  try {
    const ids = req.body.checkedPids;

    const dataFetch = await Products.find({ code: { $in: ids } });

    if (dataFetch) {
      const objData = dataFetch.map((item) => {
        let arr = [];
        for (let i = 0; i < item.imgUrl.length; i++) {
          let value = item.imgUrl[i].src;
          arr.push({
            attached_id: "0",
            z_status: "0",
            languages_id: "0",
            path: `https://static-sellercentral.shopperr.in/${value}`,
          });
        }

        return {
          productID: item.code.replace(/\D/g, ""),
          is_display: 1,
          category_id: 200,
          productImages: arr,
          shippingMethod: [],
          product_model: item.pd_model,
          brand: "Generic",
          product_visible: "Y",
          product_pack_unit: 1,
          product_length: item.length,
          product_width: item.width,
          product_height: item.height,
          product_weight: item.weight,
          pd_name: item.name,
          pd_description: item.description,
          g_id: null,
          gst: "0.00",
          product_sum: 0,
          product_manage_status: 1,
          product_status: +item.pd_status,
          product_location: "China",
          stock: {
            cn_quantity: item.quantity,
            in_quantity: 0,
          },
          supplier_sku: item.code,
          varient_obj: item.vd,
          sub_suplier_name:
            item.taggedSuppliers.length === 0
              ? item.spData.name
              : item.taggedSuppliers[0].supplierName,

          prices: {
            product_base_price: item.price,
            ppm_price_2: item.price / 12,
            STK_Shopperr_price: item.price / 12,
          },
        };
      });

      try {
        fs.writeFile(
          __dirname + "price.txt",
          JSON.stringify(objData),
          (err) => {
            if (err) {
              console.log(err);
            } else {
              console.log("log created");
            }
          }
        );
      } catch (error) {
        console.log(error);
      }

      var axios = require("axios");
      var qs = require("qs");
      var data = qs.stringify({
        paramjson:
          '{"HeaderRequest":{"userid":"Leon","userkey":"VIGfMA0GCSqGSIb3DQEBAQUAA4","usertoken":"VIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBi","methodName":"ShopperrProduct"},"addProductRequestInfo":' +
          JSON.stringify(objData) +
          "}",
      });

      var config = {
        method: "post",
        url: "https://dropshipper.shopperr.in/webservice",
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
        },
        data: data,
      };

      axios(config)
        .then(function (response) {
          if (response.data.msg.success == 1) {
            try {
              const updateMany = Products.update(
                { code: { $in: ids } },
                { $set: { is_listed_on_ds: 1 } },
                function (err, result) {
                  if (err) {
                    res.send(err);
                  } else {
                    return res.json(response.data);
                  }
                }
              );
            } catch (error) {
              return res.json(error);
            }
          } else {
            return res.json({ msg: "not found" });
          }
          return res.json(response.data);
        })
        .catch(function (error) {
          return res.json(error);
        });
    } else {
      return res.json({ msg: "no product found" });
    }
  } catch (err) {
    return res.status(500).json({ error: err.toString() });
  }
};

exports.CategoryList = async (req, res) => {
  try {
    const categories = await Category.find({
      $or: [{ level: { $exists: false } }, { level: 1 }],
    })
      .sort({ created_on: 1 })
      .exec();
    res.status(200).send(categories);
  } catch (error) {
    res.status(400).send(error);
  }
};

exports.TotalCategory = async (req, res) => {
  try {
    let arr = [];
    let categies = await Category.find({
      $or: [{ level: { $exists: false } }, { level: 1 }],
    }).sort({ created_on: 1 });
    arr = categies.map((el) => {
      return {
        _id: el._id,
        category: el.category,
        subCategory: _.isEmpty(el.subCategory) ? "" : el.subCategory,
        description: _.isEmpty(el.description) ? "" : el.description,
        created_on: _.isEmpty(el.created_on) ? "" : el.created_on,
        categoryImage: _.isEmpty(el.categoryImage)
          ? ""
          : `${process.env.S3_BUCKET_FILE_URL}/${el.categoryImage.src}`,
      };
    });
    return res.status(200).send(arr);
  } catch (error) {
    return res.status(400).send(error);
  }
};

exports.SupplierList = async (req, res) => {
  try {
    let supplierList = await User.find({ category: "supplier" }).exec();
    res.status(200).send(supplierList);
  } catch (err) {
    res.status(400).send(err);
  }
};

exports.GetUploadUpdateProductCsv = async (req, res) => {
  const page = parseInt(req.query.page);
  const limit = parseInt(req.query.limit);
  const startIndex = (page - 1) * limit;
  let supplierProduct = await Products.countDocuments({
    supplier_id: mongoose.Types.ObjectId(req.query.id),
  });
  let totalCount = await CsvUpload.countDocuments({
    spId: mongoose.Types.ObjectId(req.query.id),
    type: { $in: [1, 2] },
  }).exec();
  let results = await CsvUpload.find({
    spId: mongoose.Types.ObjectId(req.query.id),
    type: { $in: [1, 2] },
  })
    .sort({ _id: -1 })
    .limit(limit)
    .skip(startIndex)
    .exec();
  if (results.length > 0) {
    let items = await Promise.all(
      results.map((csv) => {
        return new Promise(async (resolve, reject) => {
          try {
            let status = "";
            if (csv.status == 0) {
              status = "Pending";
            } else if (csv.status == 1) {
              status = "Success";
            }
            let item = {
              status: status,
              action: csv.url,
              date: csv.date
                ? new Date(csv.date).toLocaleString(undefined, {
                    timeZone: "Asia/Kolkata",
                  })
                : "",
            };
            resolve(item);
          } catch (err) {
            reject(err);
          }
        });
      })
    )
      .then((data) => data)
      .catch((err) => err);
    if (items) {
      return res.status(200).send({
        error: 0,
        items: items,
        product: supplierProduct,
        totalCount: totalCount,
      });
    } else {
      return res.send({ error: 1, Response: "Something went wrong." });
    }
  } else {
    return res.send({ error: 1, Response: "Something went wrong." });
  }
};

exports.GetUploadProductCsv = async (req, res) => {
  const page = parseInt(req.query.page);
  const limit = parseInt(req.query.limit);
  const startIndex = (page - 1) * limit;

  let totalCount = await CsvUpload.countDocuments({
    spId: mongoose.Types.ObjectId(req.query.id),
    type: 11,
  }).exec();
  let results = await CsvUpload.find({
    spId: mongoose.Types.ObjectId(req.query.id),
    type: 11,
  })
    .sort({ _id: -1 })
    .limit(limit)
    .skip(startIndex)
    .exec();
  if (results.length > 0) {
    let items = await Promise.all(
      results.map((csv) => {
        return new Promise(async (resolve, reject) => {
          try {
            let status = "";
            if (csv.status == 0) {
              status = "Pending";
            } else if (csv.status == 1) {
              status = "Success";
            } else if (csv.status == 2) {
              status = "Processing";
            } else {
              status = "Fail";
            }
            let item = {
              status: status,
              action: csv.url,
              resUrl: csv.resUrl ? csv.resUrl : "#",
              date: csv.date
                ? new Date(csv.date).toLocaleString(undefined, {
                    timeZone: "Asia/Kolkata",
                  })
                : "",
            };
            resolve(item);
          } catch (err) {
            reject(err);
          }
        });
      })
    )
      .then((data) => data)
      .catch((err) => err);
    if (items) {
      return res
        .status(200)
        .send({ error: 0, items: items, totalCount: totalCount });
    } else {
      return res.send({ error: 1, Response: "Something went wrong." });
    }
  } else {
    return res.send({ error: 1, Response: "Something went wrong." });
  }
};

exports.DownloadProductCsv = async (req, res) => {
  var supplierId = req.params.supplier_id;
  const csvUpload = await new CsvUpload({
    type: 2,
    cond: [{ supplier_id: supplierId }],
    spId: mongoose.Types.ObjectId(supplierId),
    page: req.body.page,
    limit: req.body.limit,
    date: new Date(),
  });
  try {
    const saveProduct = await csvUpload.save();
    res.send("success");
  } catch (err) {
    res.status(400).send(err);
  }
};

exports.UploadProductCsv = async (req, res) => {
  let fileContent = req.files.file.data;
  if (fileContent) {
    console.log("inside upload product csv");
    let d = new Date();
    let supplierId = req.body.supplier_id;
    const s3dir =
      "product/" +
      supplierId +
      d.getFullYear().toString() +
      "/" +
      (d.getMonth() + 1).toString() +
      "/";
    let filename = makeid(6) + "_" + supplierId + ".csv";
    let fullPath = s3dir + filename;
    let uploadres = await uploadSupplierCsv(
      fileContent,
      fullPath,
      supplierId,
      11
    );
    if (uploadres == "success") {
      console.log("inside success");
      return res.send({ error: 0, Response: "File uploaded Successfully." });
    } else {
      return res.send({ error: 1, Response: "Something went wrong." });
    }
  } else {
    return res.send({ error: 1, Response: "Something went wrong." });
  }
};

exports.DownloadAllOrderCsv = async (req, res) => {
  const page = parseInt(req.query.page);
  const limit = parseInt(req.query.limit);
  const merchantId = "5e822d4e87206f6b6cf0090f";
  const startIndex = (page - 1) * limit;
  const endIndex = page * limit;
  const results = {};
  let query = { isDelete: false };
  if (req.query.fromDate && req.query.toDate) {
    query.created_on = {
      $gte: new Date(req.query.fromDate),
      $lt: new Date(req.query.toDate),
    };
  }
  if (req.query.text) {
    query.orderId = req.query.text;
  }
  if (req.query.marketplace == 1) {
    query.storeDomain = "Amazon.in";
  }
  if (req.query.phoneNumber) {
    query["customer.phone"] = req.query.phoneNumber;
  }
  if (req.query.source) {
    query.source = req.query.source;
  }
  if (req.query.text) {
    // query.inv_number = req.query.text;

    query = {
      $or: [
        { orderSerial: req.query.text },
        { mkpOrderId: req.query.text },
        { recipientName: req.query.text },
        { "order_shipping.os_tracking_no": req.query.text },
        { "orderDetails.sku": req.query.text },
      ],
    };
  }
  if (req.query.searchOrderStatus) {
    // query.inv_number = req.query.text;

    query = {
      $or: [
        { pStatus: req.query.searchOrderStatus },
        { oStatus: req.query.searchOrderStatus },
        { sStatus: req.query.searchOrderStatus },
        { dStatus: req.query.searchOrderStatus },
        { rStatus: req.query.searchOrderStatus },
      ],
    };
  }
  console.log(query);
  await Order.find(query)
    .sort({ _id: -1 })
    .limit(limit)
    .skip(startIndex)
    .exec()
    .then(async (results) => {
      //console.log(results);
      const csvData = await Promise.all(
        results.map((order) => {
          return new Promise(async (resolve, reject) => {
            //console.log(order);
            let fData = {
              "Shopperr Order Id": order.orderSerial,
              "MarketPlace Order Id": order.mkpOrderId,
              Quantity: order.orderDetails[0].quantity,
              Total: order.orderDetails[0].finalPrice,
              Recipient: order.recipientName,
              Mareketplace: order.storeDomain,
              "Status	": "Paid",
              Date: order.orderDate,
              "Carrier name": order.order_shipping[0].sm_title,
              "Shipping method": order.order_shipping[0].shipping_method,
              "Tracking number": order.order_shipping[0].os_tracking_no,
              "Delivery phone": order.shippingPhoneNumber,
            };
            resolve(fData);
          });
        })
      )
        .then((data) => data)
        .catch((err) => err);
      if (typeof csvData !== "undefined" && csvData.length > 0) {
        const csv = new ObjectsToCsv(csvData);
        await csv
          .toDisk("../uploads" + merchantId + ".csv")
          .then(async (result) => {
            var d = new Date();
            const s3dir =
              "merchantOrder/" +
              d.getFullYear().toString() +
              "/" +
              (d.getMonth() + 1).toString() +
              "/";
            var filename = makeid(6) + "_" + merchantId + ".csv";
            var fullPath = s3dir + filename;
            const fileContent = fs.readFileSync(
              "../uploads" + merchantId + ".csv"
            );

            var status = await uploadExcel(fileContent, s3dir + filename).then(
              async () => {
                var url = process.env.S3_BUCKET_FILE_URL;
                url = url + "/" + fullPath;
                const csvUpload = await new CsvUpload({
                  type: 12,
                  cond: [{ mId: mongoose.Types.ObjectId(merchantId) }],
                  mId: mongoose.Types.ObjectId(merchantId),
                  url: url,
                  date: new Date(),
                });
                try {
                  const saveCsv = await csvUpload.save().then(() => {
                    res.send({ error: 0, response: url });
                  });
                } catch (err) {
                  res.send("something went wrong");
                }
                fs.unlink("../uploads" + merchantId + ".csv", (err) => {
                  if (err) throw err;
                });
              }
            );
          });
      }
    });
};
exports.DownloadAllOrderCsv2 = async (req, res) => {
  const page = parseInt(req.query.page);
  const limit = parseInt(req.query.limit);
  const merchantId = "5e822d4e87206f6b6cf0090f";
  const startIndex = (page - 1) * limit;
  const endIndex = page * limit;
  const results = {};
  let query = { isDelete: false };
  if (req.query.fromDate && req.query.toDate) {
    query.created_on = {
      $gte: new Date(req.query.fromDate),
      $lt: new Date(req.query.toDate),
    };
  }
  if (req.query.text) {
    query.orderId = req.query.text;
  }
  if (req.query.marketplace == 1) {
    query.storeDomain = req.query.storeDomain;
  }
  if (req.query.phoneNumber) {
    query["customer.phone"] = req.query.phoneNumber;
  }
  if (req.query.source) {
    query.source = req.query.source;
  }
  await Order.find(query)
    .sort({ _id: -1 })
    .limit(limit)
    .skip(startIndex)
    .exec()
    .then(async (results) => {
      const csvData = await Promise.all(
        results.map((order) => {
          return new Promise(async (resolve, reject) => {
            if (
              typeof order.invoicePo !== "undefined" &&
              order.invoicePo.length > 0 &&
              order.poProcess == 1
            ) {
              let Po = await order.invoicePo.map((po) => {
                let poId = mongoose.Types.ObjectId(po.purchaseOrderId);
                return poId;
              });
              if (typeof Po !== "undefined" && Po.length > 0) {
                await PO.find({ _id: { $in: Po } }).then(async (poData) => {
                  let finalRow = await poData.map(async (porder) => {
                    let supplierName = "";
                    if (porder.sid == "5ff1fb6cb5a4c4a27a0580dd") {
                      supplierName = "SFC Inc.";
                    } else {
                      supplierName = await getSupplierName(porder.sid);
                    }

                    let fulfillmentData = "";
                    switch (porder.fulfillmentStatus) {
                      case 1:
                        fulfillmentData = "New";
                        break;
                      case 2:
                        fulfillmentData = "Acknowledge";
                        break;
                      case 3:
                        fulfillmentData = "Barcode Generated (Barcode Printed)";
                        break;
                      case 4:
                        fulfillmentData = "PO Packaging";
                        break;
                      case 5:
                        fulfillmentData = "Ready for Dispatch";
                        break;
                      case 6:
                        fulfillmentData = "Ready for Pickup";
                        break;
                      case 7:
                        fulfillmentData = "Pickup from source";
                        break;
                      case 8:
                        fulfillmentData = "Reached China Warehouse";
                        break;
                      case 9:
                        fulfillmentData = "Manifest Awaited";
                        break;
                      case 10:
                        fulfillmentData =
                          "Manifest Generated (Barcode Printed)";
                        break;
                      case 11:
                        fulfillmentData = "Ready for Dispatch to India";
                        break;
                      case 12:
                        fulfillmentData = "Packing Label Generated";
                        break;
                      case 13:
                        fulfillmentData = "Pick Up Requested";
                        break;
                      case 14:
                        fulfillmentData = "Pickup from China warehouse";
                        break;
                      case 15:
                        fulfillmentData = "In transit";
                        break;
                      case 16:
                        fulfillmentData = "Reached to India Customs";
                        break;
                      case 17:
                        fulfillmentData = "BCD payment awaited";
                        break;
                      case 18:
                        fulfillmentData = "BCD payment done";
                        break;
                      case 19:
                        fulfillmentData = "Custom Cleared";
                        break;
                      case 20:
                        fulfillmentData = "Dispatch to India Warehouse";
                        break;
                      case 21:
                        fulfillmentData =
                          "Receiving of goods at India Warehouse";
                        break;
                      case 22:
                        fulfillmentData = "PO Completed";
                        break;
                      case 23:
                        fulfillmentData = "Payment Requested";
                        break;
                      case 24:
                        fulfillmentData = "Payment Completed";
                        break;
                      default:
                        fulfillmentData = "None";
                    }
                    let fData = {
                      OrderId: order.orderNumber,
                      OrderBillingAddress1: order.billingAddress
                        ? order.billingAddress.address1
                        : "",
                      OrderBillingAddress2: order.billingAddress
                        ? order.billingAddress.address2
                        : "",
                      OrderBillingCity: order.billingAddress
                        ? order.billingAddress.city
                        : "",
                      OrderBillingCompany: order.billingAddress
                        ? order.billingAddress.company
                        : "",
                      OrderBillingCountry: order.billingAddress
                        ? order.billingAddress.country
                        : "",
                      // 'OrderBillingCountryCode'   : order.billingAddress ? order.billingAddress.country_code : '',
                      OrderBillingFirstName: order.billingAddress
                        ? order.billingAddress.first_name
                        : "",
                      OrderBillingLastName: order.billingAddress
                        ? order.billingAddress.last_name
                        : "",
                      OrderBillingName: order.billingAddress
                        ? order.billingAddress.name
                        : "",
                      OrderBillingPhone: order.billingAddress
                        ? order.billingAddress.phone
                        : "",
                      OrderBillingProvince: order.billingAddress
                        ? order.billingAddress.province
                        : "",
                      OrderBillingZip: order.billingAddress
                        ? order.billingAddress.zip
                        : "",
                      OrderShippingAddress1: order.shippingAddress
                        ? order.shippingAddress.address1
                        : "",
                      OrderShippingAddress2: order.shippingAddress
                        ? order.shippingAddress.address2
                        : "",
                      OrderShippingCity: order.shippingAddress
                        ? order.shippingAddress.city
                        : "",
                      OrderShippingCompany: order.shippingAddress
                        ? order.shippingAddress.company
                        : "",
                      OrderShippingCountry: order.shippingAddress
                        ? order.shippingAddress.country
                        : "",
                      // 'OrderShippingCountryCode'  : order.shippingAddress ? order.shippingAddress.country_code : '',
                      OrderShippingFirstName: order.shippingAddress
                        ? order.shippingAddress.first_name
                        : "",
                      OrderShippingLastName: order.shippingAddress
                        ? order.shippingAddress.last_name
                        : "",
                      OrderShippingName: order.shippingAddress
                        ? order.shippingAddress.name
                        : "",
                      OrderShippingPhone: order.shippingAddress
                        ? order.shippingAddress.phone
                        : "",
                      OrderShippingProvince: order.shippingAddress
                        ? order.shippingAddress.province
                        : "",
                      OrderShippingZip: order.shippingAddress
                        ? order.shippingAddress.zip
                        : "",
                      // 'OrderCustomerName' : order.customer && order.customer.firstName ? order.customer.firstName : '',
                      OrderCustomerAddress1: order.customer.default_address
                        ? order.customer.default_address.address1
                        : "",
                      OrderCustomerAddress2: order.customer.default_address
                        ? order.customer.default_address.address2
                        : "",
                      OrderCustomerCity: order.customer.default_address
                        ? order.customer.default_address.city
                        : "",
                      OrderCustomerCountry: order.customer.default_address
                        ? order.customer.default_address.country
                        : "",
                      // 'OrderCustomerCountryCode'  : order.customer.default_address ? order.customer.default_address.country_code : '',
                      OrderCustomerFirstName: order.customer.default_address
                        ? order.customer.default_address.first_name
                        : "",
                      OrderCustomerLastName: order.customer.default_address
                        ? order.customer.default_address.last_name
                        : "",
                      OrderCustomerName: order.customer.default_address
                        ? order.customer.default_address.name
                        : "",
                      OrderCustomerPhone: order.customer.default_address
                        ? order.customer.default_address.phone
                        : "",
                      OrderCustomerProvince: order.customer.default_address
                        ? order.customer.default_address.province
                        : "",
                      OrderCustomerZip: order.customer.default_address
                        ? order.customer.default_address.zip
                        : "",
                      OrderCustomerEmail: order.customer.email,
                      OrderCustomerOrderPrice: order.customer.price,
                      OrderCustomerTotalDiscountAmount:
                        order.customer.total_discount_amount,
                      OrderCustomerTotalGst: order.customer.total_gst,
                      OrderCustomerProductPrice:
                        order.customer.total_price_of_products,
                      OrderCustomerShippingCost:
                        order.customer.total_shipping_cost,
                      OrderCustomerTotalSpent: order.customer.total_spent,
                      Currency: order.currency,
                      OrderDiscountCodes: order.discountCodes,
                      OrderFulfillmentStatus: order.fulfillmentStatus,
                      OrderIsDelete: order.isDelete,
                      OrderMarketPlaceId: order.orderId,
                      OrderPaymentStatus: order.pStatus,
                      OrderPaymentDetails: order.paymentDetails,
                      OrderPoFlag: order.poFlag,
                      OrderPrice: order.price,
                      OrderStoreDomain: order.storeDomain,
                      PoBillingAddress1: porder.billingAddress
                        ? porder.billingAddress.address1
                        : "",
                      PoBillingAddress2: porder.billingAddress
                        ? porder.billingAddress.address2
                        : "",
                      PoBillingCity: porder.billingAddress
                        ? porder.billingAddress.city
                        : "",
                      PoBillingCompany: porder.billingAddress
                        ? porder.billingAddress.company
                        : "",
                      PoBillingCountry: porder.billingAddress
                        ? porder.billingAddress.country
                        : "",
                      // 'PoBillingCountryCode'  : porder.billingAddress ? porder.billingAddress.country_code : '',
                      PoBillingFirstName: porder.billingAddress
                        ? porder.billingAddress.first_name
                        : "",
                      PoBillingLastName: porder.billingAddress
                        ? porder.billingAddress.last_name
                        : "",
                      PoBillingName: porder.billingAddress
                        ? porder.billingAddress.name
                        : "",
                      PoBillingPhone: porder.billingAddress
                        ? porder.billingAddress.phone
                        : "",
                      PoBillingProvince: porder.billingAddress
                        ? porder.billingAddress.province
                        : "",
                      PoBillingZip: porder.billingAddress
                        ? porder.billingAddress.zip
                        : "",
                      PoShippingAddress1: porder.shippingAddress
                        ? porder.shippingAddress.address1
                        : "",
                      PoShippingAddress2: porder.shippingAddress
                        ? porder.shippingAddress.address2
                        : "",
                      PoShippingCity: porder.shippingAddress
                        ? porder.shippingAddress.city
                        : "",
                      PoShippingCompany: porder.shippingAddress
                        ? porder.shippingAddress.company
                        : "",
                      PoShippingCountry: porder.shippingAddress
                        ? porder.shippingAddress.country
                        : "",
                      // 'PoShippingCountryCode' : porder.shippingAddress ? porder.shippingAddress.country_code : '',
                      PoShippingFirstName: porder.shippingAddress
                        ? porder.shippingAddress.first_name
                        : "",
                      PoShippingLastName: porder.shippingAddress
                        ? porder.shippingAddress.last_name
                        : "",
                      PoShippingName: porder.shippingAddress
                        ? porder.shippingAddress.name
                        : "",
                      PoShippingPhone: porder.shippingAddress
                        ? porder.shippingAddress.phone
                        : "",
                      PoShippingProvince: porder.shippingAddress
                        ? porder.shippingAddress.province
                        : "",
                      PoShippingZip: porder.shippingAddress
                        ? porder.shippingAddress.zip
                        : "",
                      PoCustomerFirstName: porder.customer.first_name,
                      PoCustomerEmail: porder.customer.email,
                      PoCustomerId: porder.customerId,
                      PoDispatchDate: new Date(
                        porder.dispatchDate
                      ).toLocaleString(undefined, { timeZone: "Asia/Kolkata" }),
                      PoOrderDate: new Date(porder.orderDate).toLocaleString(
                        undefined,
                        { timeZone: "Asia/Kolkata" }
                      ),
                      PoFulfillmentData: fulfillmentData,
                      PoHsn: porder.hsn,
                      PoIgst: porder.igst,
                      PoImgSrc: porder.imgUrl
                        ? process.env.S3_BUCKET_FILE_URL + porder.imgUrl.src
                        : "",
                      PoInvoiceDesc: porder.invoicedesc,
                      PoMerchantId: porder.merchantId,
                      PoOrderDiscountAmount: porder.imgUrl
                        ? porder.orderAmt.discountAmount
                        : "",
                      PoOrderQuantity: porder.imgUrl
                        ? porder.orderAmt.quantity
                        : "",
                      PoOrderShippingGST: porder.imgUrl
                        ? porder.orderAmt.shippingGST
                        : "",
                      PoOrderShippingWithoutGST: porder.imgUrl
                        ? porder.orderAmt.shippingWithoutGST
                        : "",
                      PoOrderTotalAmount: porder.imgUrl
                        ? porder.orderAmt.totalAmount
                        : "",
                      PoOrderTotalNetAmount: porder.imgUrl
                        ? porder.orderAmt.totalNetAmount
                        : "",
                      PoOrderTotalShipping: porder.imgUrl
                        ? porder.orderAmt.totalShipping
                        : "",
                      PoOrderTotalTaxAmount: porder.imgUrl
                        ? porder.orderAmt.totalTaxAmount
                        : "",
                      PoOrderUnitPrice: porder.imgUrl
                        ? porder.orderAmt.unitPrice
                        : "",
                      PoOrderUnitPriceAfterDiscount: porder.imgUrl
                        ? porder.orderAmt.unitPriceAfterDiscount
                        : "",
                      PoOrderUnitPriceWithoutGST: porder.imgUrl
                        ? porder.orderAmt.unitPriceWithoutGST
                        : "",
                      PoOrderUnitPricetaxAmount: porder.imgUrl
                        ? porder.orderAmt.unitPricetaxAmount
                        : "",
                      PoOrderId: porder.orderId,
                      PoPaymentStatus: porder.pStatus,
                      PoOrderId: porder.orderId,
                      PoProductId: porder.productId,
                      ProductName: porder.productInfo
                        ? porder.productInfo.name
                        : "",
                      ProductPrice: porder.productInfo
                        ? porder.productInfo.price
                        : "",
                      ProductQuantity: porder.productInfo
                        ? porder.productInfo.quantity
                        : "",
                      ProductSku: porder.productInfo
                        ? porder.productInfo.sku
                        : "",
                      ProductTotalDiscount: porder.productInfo
                        ? porder.productInfo.total_discount
                        : "",
                      Porfm: porder.rfm,
                      PoScanCount: porder.scanCount,
                      Porfm: porder.rfm,
                      PoMarketplaceId: porder.shopifyOrderId,
                      PoSupplierId: porder.sid,
                      PoSupplierName: supplierName,
                      PoStoreDomain: porder.storeDomain,
                      PoSupplierPrice: porder.supplierPrice,
                      PoId: porder._id,
                    };
                    resolve(fData);
                  });
                });
              }
            } else {
              let fData = {
                OrderId: order.orderNumber,
                OrderBillingAddress1: order.billingAddress
                  ? order.billingAddress.address1
                  : "",
                OrderBillingAddress2: order.billingAddress
                  ? order.billingAddress.address2
                  : "",
                OrderBillingCity: order.billingAddress
                  ? order.billingAddress.city
                  : "",
                OrderBillingCompany: order.billingAddress
                  ? order.billingAddress.company
                  : "",
                OrderBillingCountry: order.billingAddress
                  ? order.billingAddress.country
                  : "",
                // 'OrderBillingCountryCode'   : order.billingAddress ? order.billingAddress.country_code : '',
                OrderBillingFirstName: order.billingAddress
                  ? order.billingAddress.first_name
                  : "",
                OrderBillingLastName: order.billingAddress
                  ? order.billingAddress.last_name
                  : "",
                OrderBillingName: order.billingAddress
                  ? order.billingAddress.name
                  : "",
                OrderBillingPhone: order.billingAddress
                  ? order.billingAddress.phone
                  : "",
                OrderBillingProvince: order.billingAddress
                  ? order.billingAddress.province
                  : "",
                OrderBillingZip: order.billingAddress
                  ? order.billingAddress.zip
                  : "",
                OrderShippingAddress1: order.shippingAddress
                  ? order.shippingAddress.address1
                  : "",
                OrderShippingAddress2: order.shippingAddress
                  ? order.shippingAddress.address2
                  : "",
                OrderShippingCity: order.shippingAddress
                  ? order.shippingAddress.city
                  : "",
                OrderShippingCompany: order.shippingAddress
                  ? order.shippingAddress.company
                  : "",
                OrderShippingCountry: order.shippingAddress
                  ? order.shippingAddress.country
                  : "",
                // 'OrderShippingCountryCode'  : order.shippingAddress ? order.shippingAddress.country_code : '',
                OrderShippingFirstName: order.shippingAddress
                  ? order.shippingAddress.first_name
                  : "",
                OrderShippingLastName: order.shippingAddress
                  ? order.shippingAddress.last_name
                  : "",
                OrderShippingName: order.shippingAddress
                  ? order.shippingAddress.name
                  : "",
                OrderShippingPhone: order.shippingAddress
                  ? order.shippingAddress.phone
                  : "",
                OrderShippingProvince: order.shippingAddress
                  ? order.shippingAddress.province
                  : "",
                OrderShippingZip: order.shippingAddress
                  ? order.shippingAddress.zip
                  : "",
                // 'OrderCustomerName' : order.customer && order.customer.firstName ? order.customer.firstName : '',
                OrderCustomerAddress1: order.customer.default_address
                  ? order.customer.default_address.address1
                  : "",
                OrderCustomerAddress2: order.customer.default_address
                  ? order.customer.default_address.address2
                  : "",
                OrderCustomerCity: order.customer.default_address
                  ? order.customer.default_address.city
                  : "",
                OrderCustomerCountry: order.customer.default_address
                  ? order.customer.default_address.country
                  : "",
                // 'OrderCustomerCountryCode'  : order.customer.default_address ? order.customer.default_address.country_code : '',
                OrderCustomerFirstName: order.customer.default_address
                  ? order.customer.default_address.first_name
                  : "",
                OrderCustomerLastName: order.customer.default_address
                  ? order.customer.default_address.last_name
                  : "",
                OrderCustomerName: order.customer.default_address
                  ? order.customer.default_address.name
                  : "",
                OrderCustomerPhone: order.customer.default_address
                  ? order.customer.default_address.phone
                  : "",
                OrderCustomerProvince: order.customer.default_address
                  ? order.customer.default_address.province
                  : "",
                OrderCustomerZip: order.customer.default_address
                  ? order.customer.default_address.zip
                  : "",
                OrderCustomerEmail: order.customer.email,
                OrderCustomerOrderPrice: order.customer.price,
                OrderCustomerTotalDiscountAmount:
                  order.customer.total_discount_amount,
                OrderCustomerTotalGst: order.customer.total_gst,
                OrderCustomerProductPrice:
                  order.customer.total_price_of_products,
                OrderCustomerShippingCost: order.customer.total_shipping_cost,
                OrderCustomerTotalSpent: order.customer.total_spent,
                Currency: order.currency,
                OrderDiscountCodes: order.discountCodes,
                OrderFulfillmentStatus: order.fulfillmentStatus,
                OrderIsDelete: order.isDelete,
                OrderMarketPlaceId: order.orderId,
                OrderPaymentStatus: order.pStatus,
                OrderPaymentDetails: order.paymentDetails,
                OrderPoFlag: order.poFlag,
                OrderPrice: order.price,
                OrderStoreDomain: order.storeDomain,
                PoBillingAddress1: "",
                PoBillingAddress2: "",
                PoBillingCity: "",
                PoBillingCompany: "",
                PoBillingCountry: "",
                // 'PoBillingCountryCode'      : '',
                PoBillingFirstName: "",
                PoBillingLastName: "",
                PoBillingName: "",
                PoBillingPhone: "",
                PoBillingProvince: "",
                PoBillingZip: "",
                PoShippingAddress1: "",
                PoShippingAddress2: "",
                PoShippingCity: "",
                PoShippingCompany: "",
                PoShippingCountry: "",
                // 'PoShippingCountryCode'     : '',
                PoShippingFirstName: "",
                PoShippingLastName: "",
                PoShippingName: "",
                PoShippingPhone: "",
                PoShippingProvince: "",
                PoShippingZip: "",
                PoCustomerFirstName: "",
                PoCustomerEmail: "",
                PoCustomerId: "",
                PoDispatchDate: "",
                PoOrderDate: "",
                PoFulfillmentData: "",
                PoHsn: "",
                PoIgst: "",
                PoImgSrc: "",
                PoInvoiceDesc: "",
                PoMerchantId: "",
                PoOrderDiscountAmount: "",
                PoOrderQuantity: "",
                PoOrderShippingGST: "",
                PoOrderShippingWithoutGST: "",
                PoOrderTotalAmount: "",
                PoOrderTotalNetAmount: "",
                PoOrderTotalShipping: "",
                PoOrderTotalTaxAmount: "",
                PoOrderUnitPrice: "",
                PoOrderUnitPriceAfterDiscount: "",
                PoOrderUnitPriceWithoutGST: "",
                PoOrderUnitPricetaxAmount: "",
                PoOrderId: "",
                PoPaymentStatus: "",
                PoOrderId: "",
                PoProductId: "",
                ProductName: "",
                ProductPrice: "",
                ProductQuantity: "",
                ProductSku: "",
                ProductTotalDiscount: "",
                Porfm: "",
                PoScanCount: "",
                PoMarketplaceId: "",
                PoSupplierId: "",
                PoStoreDomain: "",
                PoSupplierPrice: "",
                PoId: "",
              };
              resolve(fData);
            }
          });
        })
      )
        .then((data) => data)
        .catch((err) => err);
      if (typeof csvData !== "undefined" && csvData.length > 0) {
        const csv = new ObjectsToCsv(csvData);

        await csv
          .toDisk("../uploads" + merchantId + ".csv")
          .then(async (result) => {
            var d = new Date();
            const s3dir =
              "merchantOrder/" +
              d.getFullYear().toString() +
              "/" +
              (d.getMonth() + 1).toString() +
              "/";
            var filename = makeid(6) + "_" + merchantId + ".csv";
            var fullPath = s3dir + filename;
            const fileContent = fs.readFileSync(
              "../uploads" + merchantId + ".csv"
            );

            var status = await uploadExcel(fileContent, s3dir + filename).then(
              async () => {
                var url = process.env.S3_BUCKET_FILE_URL;
                url = url + "/" + fullPath;
                const csvUpload = await new CsvUpload({
                  type: 12,
                  cond: [{ mId: mongoose.Types.ObjectId(merchantId) }],
                  mId: mongoose.Types.ObjectId(merchantId),
                  url: url,
                  date: new Date(),
                });
                try {
                  const saveCsv = await csvUpload.save().then(() => {
                    res.send({ error: 0, response: url });
                  });
                } catch (err) {
                  res.send("something went wrong");
                }
                fs.unlink("../uploads" + merchantId + ".csv", (err) => {
                  if (err) throw err;
                });
              }
            );
          });
      }
    });
};
exports.SingleOrder = async (req, res) => {
  let results = {};
  const product_image = "";
  const id = req.params.id;
  if (!mongoose.Types.ObjectId.isValid(id)) {
    return res.status(400).json({ message: "Invalid Order ID format" });
  }
  const order = await Order.findById(id).then(async (order) => {
    let orderData = await Promise.all(
      order.orderDetails.map(async (item, i) => {
        const sku = item.sku.replace(/\D/g, "");

        let products = await Products.find(
          { code: sku },
          { imgUrl: 1, price: 1, handle:1 }
        );

        let products_data = products.map((product) => {
          return {
            imgUrl: `${process.env.S3_BUCKET_FILE_URL}/${product.imgUrl[0].src}`,
            price: product.price,
            handle: product.handle,
          };
        });
        return products_data[0];
      })
    );

    let condition = {
      _id: mongoose.Types.ObjectId(order.merchantId),
    };

    User.findOne(condition, { fName: 1, email: 1 })
      .then((merchantData) => {
        const results = {
          product_data: orderData,
          order: order,
          messages: order.order_dispute,
        };

        res.status(200).send({
          results,
          src: process.env.S3_BUCKET_FILE_URL,
          merchantData,
        });
      })
      .catch((err) => {
        res.status(500).send({ err });
      });
  });
};

exports.OrderIdmessages = async (req, res) => {
  const { id } = req.params;
  const { content, sender } = req.body;

  try {
    const order = await Order.findById(id);
    if (!order) {
      return res.status(404).send({ error: "Order not found" });
    }

    const newMessage = {
      sender,
      text: content,
      date: new Date(),
    };

    order.replies.push(newMessage);
    await order.save();

    res.status(200).send(newMessage);
  } catch (error) {
    res.status(500).send({ error: "Failed to add message" });
  }
};

exports.GetProductPrice = async (req, res) => {
  let productId = req.query.id;
  //console.log('ooo',productId)
  try {
    let products = await Products.findOne({
      _id: mongoose.Types.ObjectId(productId),
    }).limit(1);

    if (products) {
      let productArray = products;
      productArray = JSON.parse(JSON.stringify(productArray));
      let supplier = await User.findOne({
        _id: mongoose.Types.ObjectId(productArray.supplier_id),
      });
      var supplierOrigin = "";
      //console.log('ooo')
      if (productArray.spData !== undefined) {
        supplierOrigin = productArray.spData.price_algo ?? "";
      } else {
        //console.log('ooo')
        let suppliers = await User.findOne({
          _id: mongoose.Types.ObjectId(productArray.supplier_id),
        });
        if (suppliers) {
          supplierOrigin = suppliers.price_algo;
        }
      }
      let fp = productArray["price"];
      let mrps = productArray.mrp != "" ? productArray.mrp : 0;
      let pw = productArray.weight ? productArray.weight : 0;
      let lenght = productArray.length ? productArray.length : 0;
      let width = productArray.width ? productArray.width : 0;
      let height = productArray.height ? productArray.height : 0;
      let pbcd = productArray.bcd != undefined ? productArray.bcd : 10;
      let pigst = productArray.igst != undefined ? productArray.igst : 18;
      let retailerMargin =
        productArray.productMargin != undefined
          ? productArray.productMargin
          : 40;
      let pswc =
        productArray["swcOnBcd"] != undefined ? productArray["swcOnBcd"] : 10;
      let sp = await updateShopperrPriceAlgo(
        Number(fp),
        Number(pw),
        supplierOrigin,
        pbcd,
        pigst,
        pswc,
        lenght,
        width,
        height,
        mrps,
        40,
        1
      );
      sp.sku = productArray.code;
      return res.status(200).json(sp);
    } else {
      return res.json({ msg: "no product found" });
    }
  } catch (err) {
    return res.status(500).json({ error: err.toString() });
  }
};

async function uploadSupplierCsv(fileContent, path, Id, csvtype) {
  let supplierId = Id;
  await uploadExcel(fileContent, path);
  var url = process.env.S3_BUCKET_FILE_URL;
  const csvUpload = await new CsvUpload({
    type: csvtype,
    cond: [{ supplier_id: supplierId }],
    spId: mongoose.Types.ObjectId(supplierId),
    url: url + "/" + path,
    date: new Date(),
  });
  try {
    const saveProduct = await csvUpload.save();
    return "success";
  } catch (err) {
    return "error";
  }
}
function makeid(length) {
  var result = "";
  var characters =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  var charactersLength = characters.length;
  for (var i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
  }
  return result;
}
// async function uploadExcel(file, key) {
//   const params = {
//     Bucket: process.env.S3_FILE_BUCKET,
//     Key: key, // File name you want to save as in S3
//     Body: file,
//   };

//   // Uploading files to the bucket
//   s3.upload(params, async function (err, data) {
//     if (err) {
//       throw err;
//     } else {
//     }
//   });
// }
async function uploadExcel(file, key) {
  console.log(key);
  const params = {
    Bucket: process.env.S3_FILE_BUCKET,
    Key: key, // File name you want to save as in S3
    Body: file,
  };

  return new Promise((resolve, reject) => {
    // Uploading files to the bucket
    s3.upload(params, async function (err, data) {
      if (err) {
        reject(err); // Reject the promise with the error
      } else {
        resolve(data); // Resolve the promise with the uploaded data
      }
    });
  });
}

function buildQuery(data) {
  let query = {};
  if (_.isEmpty(data)) {
    return query;
  } else {
    if (!_.isEmpty(data.name)) {
      // query["name"] = { "$regex": data.name, "$options": "i" }
      query["$or"] = [
        { name: String(data.name).trim() },
        // { skus: { $in: [String(data.name)] } },
      ];
    }

    if (!_.isEmpty(data.sku)) {
      // query["name"] = { "$regex": data.name, "$options": "i" }
      query = { code: String(data.sku) };
    }

    if (data.supplier_id && data.supplier_id !== "Select Supplier") {
      query["supplier_id"] = mongoose.Types.ObjectId(data.supplier_id);
    }

    // if (data.category !== "Select Category") {
    //   query["cid"] = mongoose.Types.ObjectId(data.category);
    // }

    if (data.price && data.price !== "") {
      query["price"] = { $gt: data.price.min, $lt: data.price.max };
    }

    return query;
  }
}

function getSupplierName(id) {
  return new Promise(function (resolve, reject) {
    User.findOne({ _id: id, category: "supplier" })
      .then((result) => {
        if (!result) {
          resolve("");
        } else {
          resolve(result.supplier_id);
        }
      })
      .catch((err) => {
        reject(err);
      });
  });
}

exports.AdminsupplierNewData = async (req, res) => {
  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 10;
    const startIndex = (page - 1) * limit;
    const category = req.query.category;
    const query = category ? { category } : {};

    const [totalCount, suppliers] = await Promise.all([
      User.countDocuments(query),
      User.find(query, { email: 1, supplier_id: 1, revenue: 1 })
        .sort({ _id: -1 })
        .limit(limit)
        .skip(startIndex)
        .exec(),
    ]);

    // console.log(suppliers)

    // return false
    const final_data = [];
    const supplier_data = await Promise.all(
      suppliers.map(async (supplier) => {
        try {
          let obj = {
            supplier_id: supplier._id.toString(),
          };

          let productCounts = await Products.countDocuments({
            supplier_id: supplier._id.toString(),
          }).exec();

          const products = await Products.find({
            supplier_id: supplier._id.toString(),
          })
            .select("code")
            .lean();
          // console.log(products);

          const skuCodes = products.map((product) => product.code);
          const batchSize = 10000; // Adjust the batch size as needed

          let totalOrdersCount = 0;
          let totalRevenue = 0;

          for (let i = 0; i < skuCodes.length; i += batchSize) {
            const batch = skuCodes.slice(i, i + batchSize);
            const batchOrdersCount = await Order.countDocuments({
              "orderDetails.sku": { $in: batch },
            }).exec();
            totalOrdersCount += batchOrdersCount;

            const revenueData = await Order.aggregate([
              { $match: { "orderDetails.sku": { $in: batch } } },
              { $unwind: "$orderDetails" },
              {
                $lookup: {
                  from: "products", // The collection to join with
                  localField: "orderDetails.sku", // Field in the "Order" collection
                  foreignField: "code", // Field in the "Products" collection
                  as: "productDetails",
                },
              },
              { $unwind: "$productDetails" },
              {
                $group: {
                  _id: null,
                  totalRevenue: { $sum: "$productDetails.sp" }, // Add sum of product prices
                },
              },
            ]);

            // Add the revenue from this batch to the total
            if (revenueData && revenueData.length > 0) {
              totalRevenue += revenueData[0].totalRevenue;
            }
          }

          return {
            supplier_id: supplier.supplier_id,
            email: supplier.email,
            totalProducts: productCounts,
            totalOrders: totalOrdersCount || 0,
            totalRevenue: totalRevenue || 0,
          };
        } catch (error) {
          console.error("Error processing supplier:", supplier._id, error);
        }
      })
    );

    // console.log(supplier_data);

    // return false

    return res.status(200).json({ totalCount, data: supplier_data });
  } catch (err) {}
};

exports.AdminsupplierNewData2 = async (req, res) => {
  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 10;
    const startIndex = (page - 1) * limit;
    const category = req.query.category;
    const query = category ? { category } : {};

    const [totalCount, suppliers] = await Promise.all([
      User.countDocuments(query),
      User.find(query, { email: 1, supplier_id: 1, revenue: 1 })
        .sort({ _id: -1 })
        .limit(limit)
        .skip(startIndex)
        .exec(),
    ]);

    const supplierIds = suppliers.map((supplier) => supplier._id.toString());
    // console.log(supplierIds)
    // return false;

    const productCounts = await Products.aggregate([
      { $match: { supplier_id: { $in: supplierIds } } },
      {
        $group: {
          _id: "$supplier_id",
          totalProducts: { $sum: 1 },
        },
      },
    ]);

    const supplierToProducts = productCounts.reduce((acc, product) => {
      acc[product._id.toString()] = product.totalProducts;
      return acc;
    }, {});

    const orderCountsAndRevenue = await Promise.all(
      suppliers.map(async (supplier) => {
        const products = await Products.find({
          supplier_id: supplier._id.toString(),
        })
          .select("code")
          .lean();

        // console.log(products)
        const skuCodes = products.map((product) => product.code);
        const totalOrdersCount =
          skuCodes.length > 0
            ? await Order.countDocuments({
                "orderDetails.sku": { $in: skuCodes },
              }).exec()
            : 0;

        const totalRevenueData =
          skuCodes.length > 0
            ? await Order.aggregate([
                { $match: { "orderDetails.sku": { $in: skuCodes } } },
                { $unwind: "$orderDetails" },
                {
                  $lookup: {
                    from: "products",
                    localField: "orderDetails.sku",
                    foreignField: "code",
                    as: "productDetails",
                  },
                },
                { $unwind: "$productDetails" },
                {
                  $group: {
                    _id: null,
                    totalRevenue: { $sum: "$productDetails.sp" },
                  },
                },
              ]).allowDiskUse(true)
            : [{ totalRevenue: 0 }];
        return {
          supplierId: supplier._id,
          totalOrdersCount,
          totalRevenue: totalRevenueData[0]?.totalRevenue || 0,
        };
      })
    );

    const rest = suppliers.map(async (item) => {
      const prCount = await Products.countDocuments({
        supplier_id: "5ff1fb6cb5a4c4a27a0580dd",
      });
      console.log(prCount);
    });

    const results = suppliers.map((supplier) => {
      const productCount = supplierToProducts[supplier._id.toString()] || 0;

      const orderData =
        orderCountsAndRevenue.find((oc) =>
          oc.supplierId.equals(supplier._id)
        ) || {};
      return {
        ...supplier._doc,
        totalProducts: productCount,
        totalOrders: orderData.totalOrdersCount || 0,
        totalRevenue: orderData.totalRevenue || 0,
      };
    });

    return res.status(200).json({ totalCount, data: results });
  } catch (e) {
    console.error("Error fetching supplier data:", e);
    res.status(500).json(e.toString());
  }
};

exports.AdminsupplierById = async (req, res) => {
  try {
    const supplierId = req.query.supplierId;
    let results = await User.find(
      { supplier_id: supplierId },
      { email: 1, supplier_id: 1, revenue: 1, orders: 1, products: 1 }
    )
      .sort({ _id: -1 })
      .limit(1)
      .exec();
    let result = { totalCount: results.length, data: results };
    return res.status(200).json(result);
  } catch (e) {
    res.status(500).json(e.toString());
  }
};

exports.AdminsupplierDel = async (req, res) => {
  try {
    const data = await User.deleteOne({ _id: req.params.id });
    return res.json("success");
  } catch (e) {
    return res.json({ message: e.toString() });
  }
};

exports.AdminsupplierProfile = async (req, res) => {
  try {
    let supp = await User.findOne({ _id: req.params.id });
    return res.send(supp);
  } catch (error) {
    return res.status(500).send(error.toString());
  }
};

exports.supplierSettingUpdate = async (req, res) => {
  var upObj = {};
  if (req.body.password) {
    const salt = await bcrypt.genSalt(10);
    const hashPassword = await bcrypt.hash(req.body.password, salt);
    upObj = {
      origin: req.body.origin,
      price_algo: req.body.priceAlgo,
      password: hashPassword,
    };
  } else {
    upObj = {
      origin: req.body.origin,
      price_algo: req.body.priceAlgo,
      revenue: 20,
    };
  }
  try {
    User.updateOne(
      { _id: mongoose.Types.ObjectId(req.body.supplier_id) },
      { $set: upObj },
      { upsert: false }
    )
      .exec()
      .then((ress) => {
        return res.send({ status: 1, response: "User Updated Successfully" });
      });
  } catch (e) {
    return res.send({ status: 0, response: e.toString() });
  }
};

exports.AddSupplierProfile = async (req, res) => {
  const { error } = userValidation(req.body);
  if (error) return res.status(400).send(error.details[0].message);
  const emailExist = await User.findOne({ email: req.body.email });
  if (emailExist) return res.status(400).send("Email Already Exists");
  const salt = await bcrypt.genSalt(10);
  const hashPassword = await bcrypt.hash(req.body.password, salt);
  const user = new User({
    supplier_id: req.body.supplier_id,
    email: req.body.email,
    password: hashPassword,
    origin: req.body.origin,
    price_algo: req.body.price_algo,
    category: "supplier",
    created_on: new Date(),
  });
  const savedUser = await user.save();
  // try {
  // const savedUser = await user.save().then(async (savedUser) => {
  // var SupplierCountryCode = savedUser.origin == "india" ? 91 : 86;
  // var supplierCode = await supplierCode.find().sort({ _id: -1 }).limit(1);
  // if (supplierCode.length > 0) {
  //   var supplierObj = new supplierCode({
  //     spId: mongoose.Types.ObjectId(savedUser._id),
  //     spCode: parseInt(supplierCode["0"].spCode + 1),
  //     scCode: parseInt(SupplierCountryCode),
  //     date: new Date(),
  //   });
  //   console.log(savedUser);
  //   try {
  //     await supplierObj.save();
  //     return res.send(savedUser);
  //   } catch (err) {
  //     return res.status(400).send(err);
  //   }
  // } else {
  //   var supplierObj = new supplierCode({
  //     spId: mongoose.Types.ObjectId(savedUser._id),
  //     spCode: parseInt(101),
  //     scCode: parseInt(SupplierCountryCode),
  //     date: new Date(),
  //   });
  try {
    // await supplierObj.save();
    return res.send(savedUser);
  } catch (err) {
    return res.status(400).send(err);
  }
  // }
  // });
  // } catch (err) {
  //   return res.status(400).send(err);
  // }
};

exports.AddMerchantProfile = async (req, res) => {
  const { error } = userValidation(req.body); // Ensure userValidation expects fName and lName
  if (error) return res.status(400).send(error.details[0].message);

  const emailExist = await User.findOne({ email: req.body.email });
  if (emailExist) return res.status(400).send("Email Already Exists");

  const salt = await bcrypt.genSalt(10);
  const hashPassword = await bcrypt.hash(req.body.password, salt);

  const user = new User({
    fName: req.body.fName,          
    lName: req.body.lName,          
    email: req.body.email,
    password: hashPassword,
    customer_logid: req.body.customer_logid,  
    category: "merchant",
    created_on: new Date(),
  });

  try {
    const savedUser = await user.save();
    return res.send(savedUser);
  } catch (err) {
    return res.status(400).send(err);
  }
};


exports.getLogisticUsers = async (req, res) => {
  let temp = [];
  for (let i = 0; i < res.paginatedResults.results.length; i++) {
    temp.push({
      _id: res.paginatedResults.results[i]._id,
      email: res.paginatedResults.results[i].email || "",
      name: res.paginatedResults.results[i].logisticUser_id || "",
      type: res.paginatedResults.results[i].type || "",
    });
  }

  return res.status(200).send({ items: temp, totalCount: res.totalCount });
};

exports.AddLogisticUser = async (req, res) => {
  //user email already exists
  const emailExist = await Adminuser.findOne({ email: req.body.email });
  if (emailExist) return res.status(400).send("Email Already Exists");

  const salt = await bcrypt.genSalt(10);
  const hashPassword = await bcrypt.hash(req.body.password, salt);
  const user = new Adminuser({
    logisticUser_id: req.body.logisticUser_id,
    email: req.body.email,
    category: req.body.category,
    password: hashPassword,
    phoneNo: req.body.phoneNo,
    type: req.body.price_algo,
    created_on: new Date(),
  });
  try {
    await user.save().then((result) => {
      return res.status(200).send("logistic User added");
    });
  } catch (err) {
    // console.log(err);
    return res.status(400).send(err);
  }
};

exports.LogisticViewWarehouse = async (req, res) => {
  WareHouse.find()
    .then((recipe) => {
      return res.json(recipe);
    })
    .catch((err) => {
      return res.json(err);
    });
};

exports.LogisticGetSelectedLogisticUser = async (req, res) => {
  Adminuser.findOne({ _id: req.params.id })
    .then((result) => {
      return res.status(200).send(result);
    })
    .catch((err) => {
      return res.status(400).send(err);
    });
};

exports.updateLogisticUser = async (req, res) => {
  let hashPassword = "";
  if (!_.isEmpty(req.body.password)) {
    const salt = await bcrypt.genSalt(10);
    hashPassword = await bcrypt.hash(req.body.password, salt);
  }
  let updateValues = {
    $set: {
      email: req.body.email,
      type: req.body.type,
      logisticUser_id: req.body.name,
      password: _.isEmpty(req.body.password)
        ? req.body.oldPassword
        : hashPassword,
      updatedOn: new Date(),
      warehouse: req.body.wareHouse,
      warehouseId: req.body.warehouseId,
      // warehouse code is fetched
    },
  };
  Adminuser.findOneAndUpdate({ _id: req.body._id }, updateValues, {
    new: true,
  })
    .then((result) => {
      return res.status(200).send("1");
    })
    .catch((err) => {
      console.log(err);
      return res.status(400).send("2");
    });
};

exports.deleteLogisticUser = async (req, res) => {
  Adminuser.findOneAndDelete({ _id: req.params.id })
    .then((result) => {
      return res.status(200).send("1");
    })
    .catch((err) => {
      console.log(err);
      return res.status(400).send("2");
    });
};

exports.autoMargin = async (req, res) => {
  try {
    const currDate = (sep) => {
      let d = new Date();
      let DD = d.getDate();
      let MM = d.getMonth() + 1;
      let YY = d.getFullYear();
      return DD + sep + MM + sep + YY;
    };

    const data = await Products.find({ category: req.body.category });
    data.forEach(async (item, i) => {
      let newArray = [];
      if (item.varientArray.length !== 0) {
        item.varientArray.forEach((arr, i) => {
          // console.log("varientArray", arr);

          let obj = {
            varient: arr.varient,
            price: arr.price,
            sku: arr.sku,
            quantity: arr.quantity,
            selliingPrice:
              parseInt(arr.price) +
              (parseInt(arr.price) * parseInt(req.body.margin)) / 100,
          };

          // console.log({obj});
          newArray.push(obj);
        });
        let updatePrice = await Products.updateOne(
          { _id: item._id },
          { $set: { varientArray: newArray } },
          {
            new: true,
            useFindAndModify: false,
          }
        );
        // console.log({ updatePrice });
      } else {
        let calPrice =
          parseInt(item.price) +
          (parseInt(item.price) * parseInt(req.body.margin)) / 100;
        let price = calPrice.toFixed(2);
        let updatePrice = await Products.updateOne(
          { _id: item._id },
          { $set: { selliingPrice: price } },
          {
            new: true,
            useFindAndModify: false,
          }
        );
        // console.log({ updatePrice });
      }
    });
    let categoryData = await Category.findOneAndUpdate(
      { category: req.body.category },
      { $set: { margin: req.body.margin, margin_updated: currDate("-") } },
      {
        new: true,
        useFindAndModify: false,
      }
    );
    //console.log("category updated", categoryData);
    //console.log("");
    return res.json("success");
  } catch (error) {
    console.log("update price error is:", error);
  }
};

exports.totalCategoryMargin = async (req, res) => {
  try {
    const categories = await Category.find({}).sort({ margin_updated: -1 });
    // console.log(categories);
    return res.json(categories);
  } catch (error) {
    return res.status(500).send(error.toString());
  }
};

exports.customMerchantDetail = async (req, res) => {
  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 10;
    const startIndex = (page - 1) * limit;

    // 🔹 Handle search query
    const searchQuery = req.query.search;
    let filter = { category: "merchant" };

    if (searchQuery) {
      filter.$or = [
        { fName: { $regex: searchQuery, $options: "i" } },
        { lName: { $regex: searchQuery, $options: "i" } },
        { email: { $regex: searchQuery, $options: "i" } },
      ];
    }

    // 🔹 Count total results (filtered if search is applied)
    let totalCount = await User.countDocuments(filter);

    // 🔹 Fetch filtered users
    let results = await User.find(filter, {
      fName: 1,
      lName: 1,
      email: 1,
      phoneNo: 1,
      createdAt: 1,
      balance: 1,
      category: 1,
      totalLoginCount: 1,
      weeklyLoginCount: 1,
    })
      .sort({ createdAt: -1 })
      .limit(limit)
      .skip(startIndex)
      .exec();

    // 🔹 Process merchants with additional data (orders & revenue)
    let newObject = await Promise.all(
      results.map(async (merchant) => {
        let orderCount = await Order.countDocuments({ merchantId: merchant._id });
        let orders = await Order.find({ merchantId: merchant._id }, { orderDetails: 1 });

        let totalRevenue = 0;
        await Promise.all(
          orders.map(async (order) => {
            await Promise.all(
              order.orderDetails.map(async (product) => {
                const productSp = await Products.findOne({ code: product.sku }, { sp: 1 });
                if (productSp) {
                  totalRevenue += productSp.sp;
                }
              })
            );
          })
        );

        return {
          id: merchant._id,
          email: merchant.email,
          fName: merchant.fName,
          lName: merchant.lName,
          phone: merchant.phoneNo,
          createdAt: merchant.createdAt,
          balance: merchant.balance,
          totalLoginCount: merchant.totalLoginCount,
          weeklyLoginCount: merchant.weeklyLoginCount,
          category: merchant.category,
          count: orderCount,
          revenue: totalRevenue,
        };
      })
    );

    return res.status(200).json({ totalCount, data: newObject });
  } catch (e) {
    console.error("Error fetching merchant details:", e);
    res.status(500).json({ error: e.toString() });
  }
};


exports.adminResellerByName = async (req, res) => {
  try {
    let { search } = req.body;
    if (!search) {
      return res.status(400).json({ message: "Please enter a search term" });
    }

    const searchTerm = search.trim().toLowerCase();
    const regex = new RegExp(searchTerm, "i");

    let result = await User.find({
      $or: [
        { fName: regex },
        { lName: regex },
        { email: regex },
        {
          $expr: {
            $regexMatch: {
              input: { $concat: ["$fName", " ", "$lName"] },
              regex: searchTerm,
              options: "i",
            },
          },
        },
      ],
    }).sort({ createdAt: -1 });

    if (!result || result.length === 0) {
      return res.status(404).json({ message: "User not found" });
    }

    let resdata = await Promise.all(
      result.map(async (user) => {
        let orderCount = await Order.countDocuments({ merchantId: user._id });

        let orders = await Order.find(
          { merchantId: user._id },
          { orderDetails: 1 }
        );

        let totalRevenue = 0;
        await Promise.all(
          orders.map(async (order) => {
            await Promise.all(
              order.orderDetails.map(async (product) => {
                const productSp = await Products.findOne(
                  { code: product.sku },
                  { sp: 1 }
                );
                if (productSp) {
                  totalRevenue += productSp.sp;
                }
              })
            );
          })
        );

        return {
          id: user._id,
          email: user.email,
          fName: user.fName,
          lName: user.lName,
          phone: user.phoneNo,
          joiningDate: user.createdAt,
          balance: user.balance,
          category: user.category,
          price: user.revenue,
          count: orderCount,
          revenue: totalRevenue,  
        };
      })
    );
    return res.status(200).json({ data: resdata, totalCount: resdata.length });
  } catch (e) {
    console.error("Error in adminResellerByName:", e);
    res
      .status(500)
      .json({ message: "Internal Server Error", error: e.toString() });
  }
};


// const getSupplierName = async (supplierId) => {
//   // Replace with actual implementation to fetch supplier name based on supplierId
//   // For example:
//   // const supplier = await Suppliers.findById(supplierId);
//   // return supplier ? supplier.name : 'Unknown';
// };

exports.GetSingleProduct = async (req, res) => {
  try {
    let data = await Products.find({ code: req.params.code }).lean();

    if (_.isEmpty(data)) {
      let proData = await Products.find({ code: req.params.code }).lean();
      if (_.isEmpty(proData)) {
        return res.status(200).send("1");
      } else {
        proData = await Promise.all(
          proData.map(async (product) => {
            product.imgUrl = product.imgUrl.map((img) => ({
              ...img,
              src: `${process.env.S3_BUCKET_FILE_URL}/${img.src}`,
            }));
            const supplierId =
              product.supplier_id instanceof mongoose.Types.ObjectId
                ? product.supplier_id.toString()
                : product.supplier_id;

            const supplierName = (await getSupplierName(supplierId)) || "NA";

            return {
              ...product,
              supplierName,
            };
          })
        );

        // console.log('Final product data with supplierName:', proData);  // Log final product
        return res.status(200).send({ product: proData });
      }
    } else {
      data = await Promise.all(
        data.map(async (product) => {
          product.imgUrl = product.imgUrl.map((img) => ({
            ...img,
            src: `${process.env.S3_BUCKET_FILE_URL}/${img.src}`,
          }));

          const supplierId =
            product.supplier_id instanceof mongoose.Types.ObjectId
              ? product.supplier_id.toString()
              : product.supplier_id;

          const supplierName = (await getSupplierName(supplierId)) || "NA";

          return {
            ...product,
            supplierName,
          };
        })
      );

      // console.log('Final product data with supplierName:', data);  // Log final product
      return res.status(200).send({ product: data });
    }
  } catch (err) {
    return res.status(500).send(err);
  }
};

exports.adminOrderDisputeReply = async (req, res) => {
  try {
    const order = await Order.findById(mongoose.Types.ObjectId(req.params.id));
    if (!order) {
      return res.status(404).json({ error: "Order not found" });
    }

    const adminUser = await Adminuser.findById(
      mongoose.Types.ObjectId(req.body.adminUser)
    );
    if (!adminUser) {
      return res.status(404).json({ error: "Admin user not found" });
    }

    const newDispute = {
      userId: adminUser._id,
      reason: req.body.reason,
      type: "admin",
      dispute_date: new Date(),
    };

    order.order_dispute.push(newDispute);
    await order.save();

    res.status(201).json(newDispute);
  } catch (err) {
    res.status(400).json("Error: " + err);
  }
};

exports.adminOrdercloseTicket = async (req, res) => {
  try {
    const order = await Order.findById(mongoose.Types.ObjectId(req.params.id));
    if (!order) {
      return res.status(404).json({ error: "Order not found" });
    }

    const adminUser = await Adminuser.findById(req.body.adminUser);
    if (!adminUser) {
      return res.status(404).json({ error: "Admin user not found" });
    }

    const newDispute = {
      userId: adminUser._id,
      reason: req.body.reason,
      type: "admin",
      dispute_date: new Date(),
    };

    order.order_dispute.push(newDispute);
    await order.save();

    res.status(201).json(newDispute);
  } catch (err) {
    res.status(400).json("Error: " + err);
  }
};

exports.adminOrderRefund = async (req, res) => {
  try {
    const {
      orderId,
      orderSerial,
      orderConsumerPrice,
      comment,
      percentage,
      refundAmt,
    } = req.body;
    if (!orderId || !orderSerial || !orderConsumerPrice || !refundAmt) {
      return res.status(400).json({ error: "Missing required fields" });
    }

    const order = await Order.findById(orderId);
    if (!order) {
      return res.status(404).json({ error: "Order not found" });
    }

    const user = await User.findById(order.merchantId);
    if (!user) {
      return res.status(404).json({ error: "User not found" });
    }

    const orderConsumerPriceNum = parseFloat(orderConsumerPrice);
    const refundAmtNum = parseFloat(refundAmt);
    if (isNaN(orderConsumerPriceNum) || isNaN(refundAmtNum)) {
      return res
        .status(400)
        .json({ error: "Invalid order consumer price or refund amount" });
    }

    const beforeAmt = user.balance;
    const afterAmt = (beforeAmt + refundAmtNum).toFixed(2);
    const billHistory = new BillHistory({
      merchantId: order.merchantId,
      pgOrderId: order.orderSerial,
      systemId: orderId,
      billType: 2,
      billAmt: refundAmtNum,
      beforeAmt: beforeAmt,
      afterAmt: afterAmt,
      crDate: new Date(),
      modDate: new Date(),
      comment: comment || "Refund issued",
    });
    await billHistory.save();

    order.status = "refunded";
    await order.save();

    user.balance = parseFloat(user.balance) || 0;

    // Update the user's balance with the refund amount
    user.balance = afterAmt;
    await user.save();

    // Respond with success message and the created bill history
    res
      .status(200)
      .json({ message: "Refund processed successfully", billHistory });
  } catch (error) {
    console.error("Error processing refund:", error);
    res.status(500).json({ error: "Internal server error" });
  }
};

exports.GetBrowseNodes = async (req, res) => {
  try {
    const nodes = await BrowseNodes.find({
      path: { $regex: new RegExp(req.query.text.toLocaleLowerCase(), "i") },
    }).limit(100);

    return res.status(200).json({ error: 0, nodes: nodes });

    // return messageBuilder(res, 200, { ...req.body }, "", {
    //   error: 0,
    //   nodes: nodes,
    // });
  } catch (err) {
    return res.status(500).json({ error: 1 });

    // return messageBuilder(res, 500, { ...req.body }, err.toString(), {
    //   error: 1,
    // });
  }
  return res.send({});
};

exports.SubscribeByShopperr = async (req, res) => {
  const _id = req.query.productId;
  if (!_id) {
    // return messageBuilder(res, 400, { ...req.query }, "Invalid Input Param mobile");
    return res
      .status(400)
      .json({ error: 1, message: "Invalid Input Param mobile" });
  }
  try {
    // const sproduct = await SubscribeProducts.find({ mId: mongoose.Types.ObjectId("600d67ca51b296e894178f3c"), pId: mongoose.Types.ObjectId(_id) }).sort({ "su_status": -1 }).limit(1);
    const sproduct = await Products.find({
      _id: mongoose.Types.ObjectId(_id),
      "subscribeProduct.merchantId": "63974a766862885aadd627b4",
    });
    if (!sproduct || (sproduct && !sproduct.length)) {
      // return messageBuilder(res, 404, { ...req.query }, "Product not Subscribed.");
      return res
        .status(404)
        .json({ error: 1, message: "Product not Subscribed." });
    }
    // return messageBuilder(res, 200, { ...req.query }, "Verified Successfully", { data: sproduct[0] });
    return res
      .status(200)
      .json({ error: 1, message: "Verified Successfully", data: sproduct[0] });
  } catch (err) {
    // return messageBuilder(res, 500, { ...req.query }, err);
    return res.status(500).json({ error: 1, message: err });
  }
};

exports.UpdateProduct = async (req, res) => {
  try {
 
    let varientPromise = [];
    let imagePromise = [];
    let imageUrlPromise = [];
    let skuss = [];
    if (req.body.varientArrayCombo.length > 0) {
      skuss = req.body.varientArrayCombo.map((item) => {
        return item.sku;
      });
    } else {
      skuss.push(req.body.idOrSku ? req.body.idOrSku : "");
    }

    let handle = await generate_handle(req.body.productTitle);
    let d = new Date();
    // const s3dir = `images/${d.getFullYear().toString()}/${(d.getMonth().toString() + 1)}/${handle}/`
    const s3dir =
      "images/" +
      d.getFullYear().toString() +
      "/" +
      (d.getMonth() + 1).toString() +
      "/";

    if (req.body.isVarien)
      varientPromise.push(await getVarientArray1(req.body, s3dir));
    if (!_.isEmpty(req.body.imageArray)) {
      req.body.imageArray.forEach(async (imageObj, index) => {
        if (imageObj.status === "old") {
          imagePromise.push({
            position: index + 1,
            src: imageObj.src,
            varient_id: "",
          });
        } else if (imageObj.status === "new") {
          // console.log("image obj");
          // console.log(imageObj.image);
          imagePromise.push(await getImagearray1(imageObj.image, s3dir, index));
          // console.log(imagePromise)
        } else if (imageObj.status === "new_url") {
          // console.log("image obj");
          // console.log(imageObj.image);
          imageUrlPromise.push(
            await uploadImageUrlArray(imageObj.image, index + 1)
          );
        }
      });
    }
    // return false;
    if (!_.isEmpty(req.body.videoUrl)) {
      const videourl = req.body.videoUrl;
      await uploadVideoUrl(videourl, s3dir);
    }
    let category = await Category.find({ category: req.body.category }).exec();
   
    let shippingObj = {
      method: req.body.shippingMode,
      usa: req.body.usaShippingPrice,
      canada: req.body.canadaShippingPrice,
      unitedKingdom: req.body.ukShippingPrice,
      australia: req.body.ausShippingPrice,
      international: req.body.interShippingPrice,
    };

    let vprice = 0;
    let vquantity = 0;
    let vsku = 0;
    let vmrp = 0;
    let sp = {};
    let vcbm = 0;
    if (req.body.isVarien) {
      vprice = req.body.varientArrayCombo[0].price;
      vquantity = req.body.varientArrayCombo[0].quantity;
      vsku = req.body.varientArrayCombo[0].sku;
      vcbm = req.body.varientArrayCombo[0].cbm || 0;

      sp = await getDataBeforeApplyPriceAlgo(
        vprice,
        req.body.varientArrayCombo[0].weight,
        0,
        req.body._id,
        _.isEmpty(req.body.varientArrayCombo[0].height)
          ? 0
          : req.body.varientArrayCombo[0].height,
        _.isEmpty(req.body.varientArrayCombo[0].width)
          ? 0
          : req.body.varientArrayCombo[0].width,
        _.isEmpty(req.body.varientArrayCombo[0].length)
          ? 0
          : req.body.varientArrayCombo[0].length
      );
      if (req.body.mrp !== "") vmrp = req.body.mrp;
      else vmrp = sp.airPrice.mrp;
    } else {
      vprice = req.body.factoryPrice;
      // STK_Shopperr_price = req.body.factoryPrice / 12;
      vquantity = req.body.quantity;
      vsku = req.body.idOrSku;
      vcbm = req.body.cbm || 0;
    
      // exit;
      sp = await getDataBeforeApplyPriceAlgo(
        vprice,
        req.body.weight,
        0,
        req.body._id,
        _.isEmpty(req.body.height) ? 0 : req.body.height,
        _.isEmpty(req.body.width) ? 0 : req.body.width,
        _.isEmpty(req.body.length) ? 0 : req.body.length
      );
      // if(req.body.mrp !== '')
      //     vmrp = req.body.mrp
      // else
      vmrp = sp.airPrice.mrp;
    
    }
 
    const allPromises = Promise.all([
      varientPromise,
      imagePromise,
      imageUrlPromise,
    ]);
    allPromises.then(
      async ([varientArrayResponse, imageArrayResponse, imageUrlPromise]) => {
        let imageArrayFinal = _.isEmpty(imageArrayResponse)
          ? []
          : imageArrayResponse;
        let imageUrlFinal = _.isEmpty(imageUrlPromise) ? [] : imageUrlPromise;
        let varientArrayFinal = [];
        if (_.isEmpty(varientArrayResponse)) {
          varientArrayFinal = [];
        } else if (!_.isEmpty(varientArrayResponse)) {
          varientArrayFinal = varientArrayResponse[0][0];
          if (!_.isEmpty(varientArrayResponse[0][1])) {
            imageArrayFinal = [
              ...imageArrayFinal,
              ...varientArrayResponse[0][1],
            ];
          }
        }
        if (imageArrayFinal.length && req.body.spStatus == "1") {
          await updateVariantFlag(
            { pId: mongoose.Types.ObjectId(req.body._id) },
            { [mongooseConstantValues.IS_VARIANT_UPDATE]: 1 }
          );
        }
        let updateValues = {
          $set: {
            name: req.body.productTitle,
            subtitle: req.body.productSubTitle,
            invoicedesc: req.body.invoiceDescription,
            handle: handle,
            tags: await getTagId(req.body.tags),
            price: parseFloat(vprice) || 0,
            mrp: parseFloat(vmrp) || 0,
            sp: parseInt(sp.airPrice.price) || 0,
            quantity: parseInt(vquantity) || 0,
            cbm: parseInt(vcbm) || 0,
            warranty: req.body.warranty || 0,
            description: req.body.detailDescription || "",
            category: req.body.category || "",
            cid: category[0]._id,
            code: vsku || "",
            hsn: req.body.hsn || 0,
            weight: parseFloat(req.body.weight) || 0,
            mu: req.body.weightLabel,
            imgUrl: imageArrayFinal,
            imgFromUrl: imageUrlFinal,
            videoUrl: req.body.videoUrl,
            height: req.body.height,
            width: req.body.width,
            length: req.body.length,
            options: _.isEmpty(req.body.varientArray)
              ? []
              : req.body.varientArray,
            vo: _.isEmpty(req.body.varientArray) ? [] : req.body.varientArray,
            vd: varientArrayFinal,
            shippingCharge: shippingObj,
            selliingPrice: req.body.isVarien
              ? parseFloat(vprice)
              : req.body.factoryPrice,
            cogs: parseInt(sp.airPrice.cogs) || 0,
            is_display: req.body.isDisplay ? req.body.isDisplay.toString() : "",
            pd_status: req.body.pdStatus ? req.body.pdStatus.toString() : "",
            marketPlaceUrl: req.body.marketPlaceUrl
              ? req.body.marketPlaceUrl
              : "",
            seaPrice: sp.seaPrice,
            bcd: 20,
            swcOnBcd: 10,
            igst: 18,
            price_update_flag: 1,
            bcd: req.body.bcd === "" ? 20 : parseInt(req.body.bcd),
            swcOnBcd: req.body.swc === "" ? 10 : parseInt(req.body.swc),
            igst: req.body.igst === "" ? 18 : parseInt(req.body.igst),
            marketPlacePrice: !req.body.marketPlacePrice
              ? ""
              : parseFloat(req.body.marketPlacePrice),
            marketPlaceMrp: !req.body.marketPlaceMrp
              ? ""
              : parseFloat(req.body.marketPlaceMrp),
            taggedSuppliers: req.body.taggedSuppliers,
            so: req.body.slabOne,
            st: req.body.slabTwo,
            stt: req.body.slabThree,
            sf: req.body.slabFour,
            // "deliveryDaysFrom": req.body.deliveryDaysFrom, "deliveryDaysTo": req.body.deliveryDaysTo,
            [mongooseConstantValues.NUMBER_OF_ITEMS]:
              req.body.numberOfItems ?? "0",
            [mongooseConstantValues.PACKAGE_INCLUDES]:
              req.body.packageIncludes ?? "0",
            [mongooseConstantValues.YEAR_OF_MANUFACTURE]:
              req.body.yearOfManufacturer ?? "",
            [mongooseConstantValues.PRODUCT_EXPIRY]:
              req.body.productExpiry ?? "",
            [mongooseConstantValues.IS_LIQUID]: req.body.isLiquid ?? 0,
            [mongooseConstantValues.IS_BATTARY]: req.body.isBattary ?? 0,
            [mongooseConstantValues.PRODUCT_BULLET_POINTS]:
              req.body.bulletpoints ?? [],
            [mongooseConstantValues.PRODUCT_BROWSE_NODE]:
              req.body.browseNode ?? "",
            catId: req.body.categoryId
              ? mongoose.Types.ObjectId(req.body.categoryId)
              : "",
            customfields: req.body.customfields ? req.body.customfields : [],
            channel: req.body.channel ? req.body.channel : [],
            skus: skuss,
            uc_status: 0,
          },
        };
        // console.log(updateValues)
        Products.findOneAndUpdate({ _id: req.body._id }, updateValues, {
          new: true,
        })
          .then((result) => {
            //
            // console.log("results");
            // console.log(result);
            if (result.is_listed_on_ds == 1) {
              try {
                Products.find({ code: "861011034368" }).then((response) => {
                  if (response) {
                    const objData = response.map((item) => {
                      let arr = [];
                      for (let i = 0; i < item.imgUrl.length; i++) {
                        let value = item.imgUrl[i].src;
                        arr.push({
                          attached_id: "0",
                          z_status: "0",
                          languages_id: "0",
                          path: `https://static-sellercentral.shopperr.in/${value}`,
                        });
                      }

                      return {
                        productID: item.code.replace(/\D/g, ""),
                        is_display: 1,
                        category_id: 200,
                        productImages: arr,
                        shippingMethod: [],
                        product_model: item.pd_model,
                        brand: "Generic",
                        product_visible: "Y",
                        product_pack_unit: 1,
                        product_length: item.length,
                        product_width: item.width,
                        product_height: item.height,
                        product_weight: item.weight,
                        pd_name: item.name,
                        pd_description: item.description,
                        g_id: null,
                        gst: "0.00",
                        product_sum: 0,
                        product_manage_status: 1,
                        product_status: +item.pd_status,
                        product_location: "China",
                        stock: {
                          cn_quantity: item.quantity,
                          in_quantity: 0,
                        },
                        supplier_sku: item.code,
                        varient_obj: item.vd,
                        sub_suplier_name:
                          item.taggedSuppliers.length === 0
                            ? item.spData.name
                            : item.taggedSuppliers[0].supplierName,

                        prices: {
                          product_base_price: item.price,
                          ppm_price_2: item.price / 12,
                          STK_Shopperr_price: item.price / 12,
                        },
                      };
                    });

                    try {
                      fs.writeFile(
                        __dirname + "price.txt",
                        JSON.stringify(objData),
                        (err) => {
                          if (err) {
                            console.log(err);
                          } else {
                            console.log("log created");
                          }
                        }
                      );
                    } catch (error) {
                      console.log(error);
                    }

                    var axios = require("axios");
                    var qs = require("qs");
                    var data = qs.stringify({
                      paramjson:
                        '{"HeaderRequest":{"userid":"Leon","userkey":"VIGfMA0GCSqGSIb3DQEBAQUAA4","usertoken":"VIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBi","methodName":"UpdateProduct"},"addProductRequestInfo":' +
                        JSON.stringify(objData) +
                        "}",
                    });
                    // console.log("data after json stringify");
                    // console.log(data);
                    var config = {
                      method: "post",
                      url: "https://dropshipper.shopperr.in/webservice",
                      headers: {
                        "Content-Type": "application/x-www-form-urlencoded",
                      },
                      data: data,
                    };
                    
                    axios(config)
                      .then(function (response) {
                         
                        if (response.data.msg.success == 1) {
                          try {
                        

                            return res.json(response);
                          } catch (error) {
                            return res.json(error);
                          }
                        } else {
                          return res.json({ msg: "not found" });
                        }
                        return res.json(response.data);
                      })
                      .catch(function (error) {
                        return res.json(error);
                      });
                  } else {
                    return res.json({ msg: "no product found" });
                  }
                });
              } catch (err) {
                return res.status(500).json({ error: err.toString() });
              }
            }
            return res.status(200).send("1");
          })
          .catch((err) => {
            return res.status(400).send(err);
          });
      }
    );
  } catch (err) {
    return res.status(400).send(err);
  }
};

exports.OrderPriority = async (req, res) => {
  const prioritys = await Orderprioritys.find({});

  if (prioritys.length > 0) {
    upObj = {
      china: req.body.priorityChina,
      india: req.body.priorityIndia,
      bulk: req.body.priorityBulk,
    };

    try {
      Orderprioritys.updateOne(
        { _id: mongoose.Types.ObjectId(prioritys[0]["_id"]) },
        { $set: upObj },
        { upsert: false }
      )
        .exec()
        .then((ress) => {
          return res.send({
            status: 1,
            response: "Settings Updated Successfully",
          });
        });
    } catch (e) {
      return res.send({ status: 0, response: e.toString() });
    }
  } else {
    const orderprioritys = new Orderprioritys({
      merchantId: req.body.merchantId,
      china: req.body.priorityChina,
      india: req.body.priorityIndia,
      bulk: req.body.priorityBulk,
    });

    await orderprioritys.save();
  }
};

exports.OrderPriorityList = async (req, res) => {
  const prioritys = await Orderprioritys.find({});
  if (prioritys.length > 0) {
    return res.send({
      status: 1,
      data: prioritys,
      response: "Settings Updated Successfully",
    });
  } else {
    return res.send({ status: 0, response: e.toString() });
  }
};

exports.currentStockImport = async (req, res) => {
  // if(req.body.mark_discontinued==3){
  //   const updateStatus= {
  //     pd_manage_status: 1,
  //   };

  //   try {
  //     const data = await Products.findOneAndUpdate(
  //       { code: req.body.sku },
  //       { $set: updateStatus },
  //       { new: true }
  //     );
  //     return res.send({ status: 1 });
  //   } catch (error) {
  //     return res.send({ status: 0, response: error.toString() });
  //   }
  // }

  /*if(req.body.instock==3){

    var fileContent = req.files.file.data
    // console.log(req.body.export_excel)
    // console.log(fileContent)

    let csv_data = await csv().fromString(fileContent.toString());
    let sku_list = [];

    await Promise.all(csv_data.map(async (item) => {
      try {
        // console.log(item.SKU)
        let obj = {
          sku:item.SKU,
          qty:item.QTY,
        }

        // sku_list.push(obj);

      }catch(err){

      }
    }));

  }*/

  if (req.body.export_excel == 5) {
    const product_data = await Products.find(
      {},
      { price: 1, mrp: 1, stock: 1, code: 1, createdAt: 1, prices: 1 }
    );
    const merchantId = req.body.merchantId;

    var csvType = req.body.csvType;
    var d = new Date();
    const s3dir =
      "import_export/" +
      d.getFullYear().toString() +
      "/" +
      (d.getMonth() + 1).toString() +
      "/";
    var filename = "exportStock_" + makeid(6) + "_" + merchantId + ".csv";
    var fullPath = s3dir + filename;
    let all_data = [];

    if (product_data.length > 0) {
      product_data.forEach((item) => {
        let obj = {
          SKU: item.code,
          "Istore Qty": item.stock.cn_qty,
          "India Qty": item.stock.in_qty ? item.stock.in_qty : 0,
          "Bulk Qty": item.stock.blk_qty ? item.stock.blk_qty : 0,
          Price: item.price,
        };

        all_data.push(obj);
      });

      const fields = ["SKU", "Istore Qty", "India Qty", "Bulk Qty", "Price"];
      const opts = { fields };
      const parser = new Parser(opts);
      const csv = parser.parse(all_data);

      const writeStream = fs.createWriteStream("exportStock.csv");
      writeStream.write(csv);
      writeStream.end();

      // Check if file exists and verify content
      writeStream.on("finish", async () => {
        const filePath = "exportStock.csv";
        if (fs.existsSync(filePath)) {
     

          const fileContent = fs.readFileSync(filePath, "utf8");

          try {
            // You can add your S3 upload code here
            // For example:
            await uploadExcel(fileContent, s3dir + filename);

            var url = process.env.S3_BUCKET_FILE_URL;
            // console.log(url + '/' + s3dir + filename);
            return res.send({ status: 1, data: url + "/" + s3dir + filename });
          } catch (err) {
            console.error("Error uploading to S3:", err);
            // Handle the error as per your application's requirements
            return res.send({ status: 0, error: err });
          }
        } else {
  
          return res.send({ status: 0, error: "File not created." });
        }
      });

      // return res.send({ status: 1, data:all_data });
    } else {
      return res.send({ status: 0, response: e.toString() });
    }
  }

  // if(req.body.export_excel==0){

  //   const updateStatus= {
  //     pd_status: 1,
  //   };

  //   try {

  //     const data = await Products.findOneAndUpdate(
  //       { code: req.body.sku },
  //       { $set: updateStatus },
  //       { new: true }
  //     );
  //     return res.send({ status: 1 });
  //   } catch (error) {
  //     return res.send({ status: 0, response: error.toString() });
  //   }

  // }

  if (req.body.export_excel == 1) {
    const product_data = await Products.find(
      {},
      { price: 1, mrp: 1, stock: 1, code: 1, createdAt: 1 }
    );

    const merchantId = req.body.merchantId;

    var csvType = req.body.csvType;
    var d = new Date();
    const s3dir =
      "import_export/" +
      d.getFullYear().toString() +
      "/" +
      (d.getMonth() + 1).toString() +
      "/";
    // const s3dir = "dispute/2024/6/";
    var filename = "exportStock_" + makeid(6) + "_" + merchantId + ".csv";
    var fullPath = s3dir + filename;

    let all_data = [];
    // return false;
    if (product_data.length > 0) {
      product_data.forEach((item) => {
        let obj = {
          SKU: item.code,
          Price: item.price,
          "Istore Qty": item.stock.cn_qty,
          "India Qty": item.stock.in_qty ? item.stock.in_qty : 0,
          "Bulk Qty": item.stock.blk_qty ? item.stock.blk_qty : 0,
          "Add time": item.createdAt,
        };

        all_data.push(obj);
      });
      // console.log(all_data)

      const fields = [
        "SKU",
        "Price",
        "Istore Qty",
        "India Qty",
        "Bulk Qty",
        "Add time",
      ];
      const opts = { fields };
      const parser = new Parser(opts);
      const csv = parser.parse(all_data);

      const writeStream = fs.createWriteStream("exportStock.csv");
      writeStream.write(csv);
      writeStream.end();

      // Check if file exists and verify content
      writeStream.on("finish", async () => {
        const filePath = "exportStock.csv";
        if (fs.existsSync(filePath)) {
    

          const fileContent = fs.readFileSync(filePath, "utf8");
          // console.log('File content:');
          // console.log(fileContent);
          // console.log(s3dir + filename);

          try {
            // You can add your S3 upload code here
            // For example:
            await uploadExcel(fileContent, s3dir + filename);

            var url = process.env.S3_BUCKET_FILE_URL;
            // console.log(url + '/' + s3dir + filename);
            return res.send({ status: 1, data: url + "/" + s3dir + filename });
          } catch (err) {
            console.error("Error uploading to S3:", err);
            // Handle the error as per your application's requirements
            return res.send({ status: 0, error: err });
          }
        } else {
 
          return res.send({ status: 0, error: "File not created." });
        }
      });

      // return res.send({ status: 1, data:all_data });
    } else {
      return res.send({ status: 0, response: "error" });
    }
  }

  if (req.body.export_excel == 9) {
    const product_data = await Products.find({}, { category: 1, code: 1 });
    const merchantId = req.body.merchantId;
    let all_data = [];
    var d = new Date();
    const s3dir =
      "import_export/" +
      d.getFullYear().toString() +
      "/" +
      (d.getMonth() + 1).toString() +
      "/";
    var filename = "exportStock_" + makeid(6) + "_" + merchantId + ".csv";

    if (product_data.length > 0) {
      product_data.forEach((item) => {
        let obj = {
          SKU: item.code,
          Category: item.category,
        };

        all_data.push(obj);
      });

      const fields = ["SKU", "Category"];
      const opts = { fields };
      const parser = new Parser(opts);
      const csv = parser.parse(all_data);

      const writeStream = fs.createWriteStream("exportStock.csv");
      writeStream.write(csv);
      writeStream.end();

      // Check if file exists and verify content
      writeStream.on("finish", async () => {
        const filePath = "exportStock.csv";
        if (fs.existsSync(filePath)) {
          

          const fileContent = fs.readFileSync(filePath, "utf8");
          try {
            await uploadExcel(fileContent, s3dir + filename);

            var url = process.env.S3_BUCKET_FILE_URL;
            return res.send({ status: 1, data: url + "/" + s3dir + filename });
          } catch (err) {
            console.error("Error uploading to S3:", err);
            // Handle the error as per your application's requirements
            return res.send({ status: 0, error: err });
          }
        } else {
       
          return res.send({ status: 0, error: "File not created." });
        }
      });

      // return res.send({ status: 1, data:all_data });
    } else {
      return res.send({ status: 0, response: e.toString() });
    }
  }

  if (req.body.export_excel == 8) {
    var fileContent = req.files.file.data;

    let csv_data = await csv().fromString(fileContent.toString());
    let sku_list = [];
    var d = new Date();
    const merchantId = req.body.merchantId;
    const s3dir =
      "import_export/" +
      d.getFullYear().toString() +
      "/" +
      (d.getMonth() + 1).toString() +
      "/";
    var filename = "exportStock_" + makeid(6) + "_" + merchantId + ".csv";

    const limitedCsvData = csv_data.slice(0, 10001);
    await Promise.all(
      limitedCsvData.map(async (item) => {
        try {
          let obj = {
            sku: item.SKU,
          };

          sku_list.push(obj);
        } catch (err) {}
      })
    );

    // let skus = sku_list.map(item => `'${item.sku}'`);
    let skus = sku_list.map((item) => item.sku);
    let skuString1 = skus.join(",");

    if (sku_list.length > 0) {
      try {
        const skuArray = skuString1.split(",");

        const exportProducts = await Products.find(
          { code: { $in: skuArray } },
          {
            _id: 0,
            code: 1,
            category: 1,
            name: 1,
            price: 1,
            description: 1,
            createdAt: 1,
            imgUrl: 1,
          }
        );
        let all_data = [];

        if (exportProducts.length > 0) {
          await Promise.all(
            exportProducts.map(async (item) => {
              let src_list = [];
              await Promise.all(
                item.imgUrl.map(async (item1) => {
                  try {
                    let obj1 = {
                      src: item1.src,
                    };

                    src_list.push(obj1);
                  } catch (err) {}
                })
              );

              let srcs = src_list.map((item) => item.src);
              let srclist = srcs.join(", ");

              let obj = {
                SKU: item.code,
                "Category Name": item.category,
                Title: item.name,
                Price: item.price,
                "Product Date Added": item.createdAt,
                Description: item.description.replace(/\s+/g, " ").trim(),
                "Image Paths": srclist,
              };

              all_data.push(obj);
            })
          );

          const fields = [
            "SKU",
            "Category Name",
            "Title",
            "Price",
            "Product Date Added",
            "Description",
            "Image Paths",
          ];
          const opts = { fields };
          const parser = new Parser(opts);
          const csv = parser.parse(all_data);

          const writeStream = fs.createWriteStream("exportStock.csv");
          writeStream.write(csv);
          writeStream.end();

          // Check if file exists and verify content
          writeStream.on("finish", async () => {
            const filePath = "exportStock.csv";
            if (fs.existsSync(filePath)) {

              const fileContent = fs.readFileSync(filePath, "utf8");
              try {
                await uploadExcel(fileContent, s3dir + filename);

                var url = process.env.S3_BUCKET_FILE_URL;
                return res.send({
                  status: 1,
                  data: url + "/" + s3dir + filename,
                });
              } catch (err) {
                console.error("Error uploading to S3:", err);
                // Handle the error as per your application's requirements
                return res.send({ status: 0, error: err });
              }
            } else {
              return res.send({ status: 0, error: "File not created." });
            }
          });
        }
      } catch (err) {
        console.log(err);
      }
    }
  }
};

function getImagearray1(image, s3dir, index) {
  return new Promise(async function (resolve, reject) {
    try {
      let filename = Date.now().toString() + makeid(6) + ".png";
      await uploadFile(image, s3dir + filename);
      resolve({ position: index + 1, src: s3dir + filename, varient_id: "" });
    } catch (err) {
      reject(err);
    }
  });
}

async function uploadFile(file, key) {
  buf = Buffer.from(file.replace(/^data:image\/\w+;base64,/, ""), "base64");
 
  // Setting up S3 upload parameters
  const params = {
    Bucket: process.env.S3_FILE_BUCKET,
    Key: key, // File name you want to save as in S3
    Body: buf,
    ContentEncoding: "base64",
    ContentType: "image/jpeg",
  };
 
  // Uploading files to the bucket
  s3.upload(params, (err, data) => {
    // s3.putObject(params, function(err, params){

    if (err) {
      console.log("err: ", err);
      console.log("Error uploading data: ", params);
    } else {
      console.log("NO ERROR WHILE UPLOADING IMAGE");
    }
  });
}

function uploadImageUrlArray(image, index) {
  return new Promise(async function (resolve, reject) {
    try {
 
      // let filename = Date.now().toString() + makeid(6) + '.png'
      await uploadFile(image);
      resolve({ position: index + 1, src: image, varient_id: "" });
    } catch (err) {
      reject(err);
    }
  });
}
function doSomeAsyncStuff(tag) {
	return new Promise(function (resolve, reject) {
		MainTag.find({ tag: tag })
			.limit(1)
			.exec()
			.then((if_tag) => {
				if (if_tag) {
					if (if_tag[0]) {
						resolve(if_tag[0]._id)
					} else {
						const mainTag = new MainTag({ tag: tag })
						mainTag.save().then((new_tag) => {
							resolve(new_tag._id)
						})
					}
				}
			})
	})
}

function getTagId(tags) {
  return new Promise(function (resolve, reject) {
    if (tags) {
      const promises = [];
      for (i = 0; i < tags.length; i++) {
        promises.push(doSomeAsyncStuff(tags[i]));
      }
      Promise.all(promises)
        .then((tagArr) => {
          resolve(tagArr);
        })
        .catch((e) => {
          reject(e);
        });
    } else resolve([]);
  });
}

async function generate_handle(title) {
  var str = title.replace(/[^a-zA-Z0-9 ]/g, "");
  var strLower = str.toLowerCase();
  var finalStr = strLower.replace(/ /g, "-");
  return finalStr;
}

async function getDataBeforeApplyPriceAlgo(
  factoryPrice,
  pweight,
  mrp,
  productId,
  height,
  width,
  length
) {
  return new Promise(function (resolve, reject) {
    Products.findOne({ _id: productId })
      .then(async (productResult) => {
        User.findOne({ _id: productResult.supplier_id })
          .then((supplierResult) => {
            resolve(
              updateShopperrPriceAlgo(
                parseFloat(factoryPrice),
                pweight,
                supplierResult.price_algo ? supplierResult.price_algo : "",
                productResult.bcd ? productResult.bcd : 20,
                productResult.igst ? productResult.igst : 18,
                productResult.swcOnBcd ? productResult.swcOnBcd : 10,
                length ? length : 0,
                width ? width : 0,
                height ? height : 0,
                mrp,
                productResult.productMargin ? productResult.productMargin : 40
              )
            );
          })
          .catch((err) => {
            reject(err);
          });
      })
      .catch((err) => {
        reject(err);
      });
  });
}

exports.productUpdate = async (req, res) => {
  try {
    const files = await req.files;

    var handle = "";
    await generate_handle(req.body.name, function (result) {
      handle = result;
    });
    let vrarrays = [];
    var vr = req.body.varientArray;
    if (vr && vr.length > 0) {
      var vardetail = JSON.parse(vr);
      var vdArr = await updatevarientsArray(vardetail, req.body.weight);
      vdArr.forEach(function (vrdata, index) {
        vrarrays.push(vrdata.varient);
      });
    }
    var sp = pricealgo(req.body.price, req.body.weight);
    if (req.body.mrp != "") {
      mrp = req.body.mrp;
    } else {
      mrp = sp.mrp;
    }
    let shippingObj = {
      method: req.body.method,
      usa: req.body.usa,
      canada: req.body.canada,
      unitedKingdom: req.body.uk,
      australia: req.body.australia,
      international: req.body.international,
    };
    let obj = {
      name: req.body.name,
      handle: handle,
      price: req.body.price,
      subtitle: req.body.subtitle,
      mrp: mrp,
      sp: sp.price,
      suid: req.body.suid,
      quantity: req.body.quantity,
      warranty: req.body.warranty,
      description: req.body.description,
      invoicedesc: req.body.invoicedesc,
      category: req.body.category,
      code: req.body.code,
      shippingCharge: shippingObj,
      varientArray: vrarrays,
      selliingPrice: req.body.selliingPrice,
    };
    const data = await Products.updateOne(
      { _id: req.body._id },
      { $set: obj },
      { upsert: true }
    );
    return res.json("success");
  } catch (error) {
    return res.json({ message: error.message });
  }
};

function updatevarientsArray(varients, weight) {
  return new Promise(async function (resolve, reject) {
    // var data = 'productImage'+'1';
    // resolve(varients);
    varientsArr = [];
    if (varients) {
      const promises = [];
      for (i = 0; i < varients.length; i++) {
        // var result = Object.keys(productImage).map((key) => [productImage[key]]);
        var varient = varients[i];
        // var imgsuf = 'productImage'+i;
        var vrdata = await updatevarient(varient, weight, i + 1);
        promises.push(vrdata);
      }
      Promise.all(promises)
        .then((varientsArr) => {
          resolve(varientsArr);
        })
        .catch((e) => {
          e;
        });
    }
  });
}

function updatevarient(varients, weight, inc) {
  return new Promise(function (resolve, reject) {
    const varientId = new VarientId({ supplier_id: "" });
    varientId.save().then((result) => {
      // var imgData = {'url' : vrr.src, 'handle' : handle };
      // var imgfile = '';
      // var imgpath = [];
      var varient_id = "";
      var d = new Date();

      var sp = pricealgo(varients.price, weight);
      if (varients.mrp != "") {
        mrp = varients.mrp;
      } else {
        mrp = price.mrp;
      }
      var varientdata = {
        varient_id: result._id,
        varient: varients.varient,
        price: parseInt(varients.price),
        mrp: parseInt(mrp),
        sp: parseInt(sp.price),
        quantity: varients.quantity,
        sku: varients.sku, 
        selliingPrice: varients.selliingPrice,
      };
      var tgs = [];
      var res = { varient: varientdata, tags: tgs };
      resolve(res); //
    });
  });
}



exports.usersList = async (req, res) => {
  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) ;
    const startIndex = (page - 1) * limit;
    const searchQuery = req.query.search;
    const fromDate = req.query.fromDate ? new Date(req.query.fromDate) : null;
    const toDate = req.query.toDate ? new Date(req.query.toDate) : null;
    
    let filter = { category: "merchant" };
    
    if (searchQuery) {
      filter.$or = [
        { customer_logid: { $regex: searchQuery, $options: "i" } }
      ];
    }

    if (fromDate && toDate) {
      filter.createdAt = { $gte: fromDate, $lte: toDate };
    } else if (fromDate) {
      filter.createdAt = { $gte: fromDate };
    } else if (toDate) {
      filter.createdAt = { $lte: toDate };
    }

    const totalCount = await User.countDocuments(filter);
    let results = await User.find(filter, {
      fName: 1,
      lName: 1,
      email: 1,
      phoneNo: 1,
      createdAt: 1,
      balance: 1,
      category: 1,
      customer_logid: 1,
      amazonStoreData: 1,
      storeData: 1,
      totalLoginCount: 1,
      weeklyLoginCount: 1,
      remark: 1,
      userType: 1
    })
      .sort({ createdAt: -1 })
      .limit(limit)
      .skip(startIndex)
      .exec();

    let newObject = await Promise.all(
      results.map(async (merchant) => {
        try {
          let orderCount = await Order.countDocuments({ merchantId: merchant._id });

          const sevenDaysAgo = new Date();
          sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);

          let WeekorderCount = await Order.countDocuments({
            merchantId: merchant._id,
            createdAt: { $gte: sevenDaysAgo }
          });

          const orders = await Order.find({ merchantId: merchant._id }).populate("orderDetails");

          let storeDomainCount = 0;
          let amazonCount = 0;
          let shopifyCount = 0;

          let amazonTotalQuantity = 0;
          let shopifyTotalQuantity = 0;

          let totalQuantity = 0;
          let amazonWeekQuantity = 0;
          let shopifyWeekQuantity = 0;

          orders.forEach(order => {
            if (order.storeDomain) {
              storeDomainCount++;

              if (order.createdAt >= sevenDaysAgo) {
                if (order.storeDomain === "Amazon.in" || order.storeDomain === "Amazon") {
                  amazonCount++;
                } else if (order.storeDomain === "Shopify") {
                  shopifyCount++;
                }
              }

              if (order.orderDetails && order.orderDetails.length > 0) {
                order.orderDetails.forEach(detail => {
                  let quantity = detail.quantity || 0;
                  totalQuantity += quantity;

                  if (order.storeDomain === "Amazon.in" || order.storeDomain === "Amazon") {
                    amazonTotalQuantity += quantity;
                  } else if (order.storeDomain === "Shopify") {
                    shopifyTotalQuantity += quantity;
                  }

                  if (order.createdAt >= sevenDaysAgo) {
                    if (order.storeDomain === "Amazon.in" || order.storeDomain === "Amazon") {
                      amazonWeekQuantity += quantity;
                    } else if (order.storeDomain === "Shopify") {
                      shopifyWeekQuantity += quantity;
                    }
                  }
                });
              }
            }
          });

          return {
            id: merchant._id,
            name: merchant.fName + ' ' + merchant.lName,
            customer_logid: merchant.customer_logid,
            email: merchant.email,
            phone: merchant.phoneNo,
            createdAt: merchant.createdAt,
            amazonApiData: merchant.amazonStoreData.length > 0,
            shopifyApiData: merchant.storeData.length > 0,
            balance: merchant.balance,
            totalLoginCount: merchant.totalLoginCount,
            weeklyLoginCount: merchant.weeklyLoginCount,
            remark: merchant.remark,
            userType: merchant.userType,
            category: merchant.category,
            count: orderCount,
            WeekorderCount: WeekorderCount,
            storeDomainCount: storeDomainCount,
            amazonCount: amazonCount,
            shopifyCount: shopifyCount,
            amazonTotalQuantity: amazonTotalQuantity,
            shopifyTotalQuantity: shopifyTotalQuantity,
            totalQuantity: totalQuantity,
            amazonWeekQuantity: amazonWeekQuantity,
            shopifyWeekQuantity: shopifyWeekQuantity
          };
        } catch (error) {
          // console.error("Error processing merchant", merchant._id, error);
          return null;
        }
      })
    );

    res.json({ data: newObject, totalCount: totalCount });

  } catch (e) {
    // console.error("Error fetching merchant details:", e);
    res.status(500).json({ error: e.toString() });
  }
};


exports.updateUserType = async (req, res) => {
  try {
    const { userId, userType, remark } = req.body;

    if (!userId) {
      return res.status(400).json({ message: "User ID is required" });
    }

    const updateData = {};
    if (userType !== undefined) updateData.userType = userType;
    if (remark !== undefined) updateData.remark = remark;

    if (Object.keys(updateData).length === 0) {
      return res.status(400).json({ message: "At least one field (userType or remark) is required" });
    }

    const updatedUser = await User.findByIdAndUpdate(userId, updateData, { new: true });

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

    res.json({ message: "User updated successfully", user: updatedUser });
  } catch (error) {
    // console.error("Error updating user:", error);
    res.status(500).json({ message: "Internal server error" });
  }
};

exports.UpdateAddress = async (req, res) => {
  
  const obj = {
    recipientName:req.body.recName,
    shippingCity:req.body.city,
    shippingAddress1:req.body.shippingAdd1,
    shippingAddress2:req.body.shippingAdd2,
    shippingAddress3:req.body.shippingAdd3,
    // shippingCity:req.body.district,
    // shippingCity:req.body.city,
    shippingState:req.body.state,
    shippingCountry:req.body.country,
    shippingPostalCode:req.body.postal,
    shippingPhoneNumber:req.body.phone,
  }

  try {
    Order.updateOne(
      { _id: mongoose.Types.ObjectId(req.body.orderId) },
      { $set: obj },
      { upsert: false }
    )
      .exec()
      .then((ress) => {
        return res.send({ status: 1, response: "Address Updated Successfully" });
      });
  } catch (e) {
    return res.send({ status: 0, response: e.toString() });
  }

}

exports.AddCategory = async (req, res) => {
  const currDate = (sep) => {
    let d = new Date();
    let DD = d.getDate();
    let MM = d.getMonth() + 1;
    let YY = d.getFullYear();
    return DD + sep + MM + sep + YY;
  };
  Category.find({ category: req.body.categoryName })
    .then(async (result) => {
      if (_.isEmpty(result)) {
        const add = new Category({
          category: req.body.categoryName,
          subCategory: req.body.subCategory,
          description: req.body.description,
          keyword: await getTagId(req.body.keyword.toString()),
          mobileFlag: parseInt(req.body.mobileFlag),
          websiteFlag: parseInt(req.body.websiteFlag),
          categoryImage: "",
          created_on: currDate("-"),
        });
        try {
          add.save().then((categoryResponse) => {
            if (!_.isEmpty(req.body.categoryImage)) {
              let d = new Date();
              const s3dir = `images/categoryImages/${d
                .getFullYear()
                .toString()}/${categoryResponse._id}.png`;
              uploadFile(req.body.categoryImage, s3dir);
              Category.findOneAndUpdate(
                { _id: categoryResponse._id },
                { $set: { categoryImage: { src: s3dir } } },
                { new: true }
              )
                .then((result) => {  
                  return res.status(200).send("1");
                })
                .catch((err) => {
                  return res.status(400).send(err);
                });
            } else {
              return res.status(200).send("1");
            }
          });
        } catch (error) {
          return res.status(400).send(error);
        }
      } else {
        return res.status(200).send("2");
      }
    })
    .catch((err) => {
      return res.status(400).send(err);
    });
};

exports.AddUpdateCategory = async (req, res) => {
	const currDate = (sep) => {
		let d = new Date()
		let DD = d.getDate()
		let MM = d.getMonth() + 1
		let YY = d.getFullYear()
		return DD + sep + MM + sep + YY
	}

	let updateValues = {
		$set: {
			category: req.body.categoryName,
			subCategory: req.body.subCategory,
			description: req.body.description,
			keyword: await getTagId(req.body.keyword.toString()),
			mobileFlag: parseInt(req.body.mobileFlag),
			websiteFlag: parseInt(req.body.websiteFlag),
			updatedOn: currDate('-'),
			code: req.body.code,
			[mongooseConstantValues.PRODUCT_BROWSE_NODE]: req.body.node
		},
	}
	try {
		Category.findOneAndUpdate({ _id: req.body.id }, updateValues, {
			new: true,
		}).then((updateResponse) => {
			if (!_.isEmpty(req.body.categoryImage)) {
				if (req.body.categoryImage.status === 'new') {
					let d = new Date()
					const s3dir = `images/categoryImages/${d
						.getFullYear()
						.toString()}/${makeid(6)}_${updateResponse._id}.png`
					uploadFile(req.body.categoryImage.image, s3dir)
					Category.findOneAndUpdate(
						{ _id: updateResponse._id },
						{ $set: { categoryImage: { src: s3dir } } },
						{ new: true }
					)
						.then((result) => {
							return res.status(200).send('1')
						})
						.catch((err) => {
							return res.status(400).send(err)
						})
				} else {
					return res.status(200).send('1')
				}
			} else {
				Category.findOneAndUpdate(
					{ _id: updateResponse._id },
					{ $set: { categoryImage: '' } },
					{ new: true }
				)
					.then((result) => {
						return res.status(200).send('1')
					})
					.catch((err) => {
						console.log(err)
						return res.status(400).send(err)
					})
			}
		})
	} catch (error) {
		// console.log('category update error', error)
		return res.status(400).send(error)
	}
}
exports.categoryDel = async(req,res) =>{
 try {
  const data =  await Category.deleteOne({_id:req.params.id})
  return res.json('success')
 } catch (error) {
  return res.json({message:error.messgae})
 }
}