const mongoose = require("mongoose");
const Order = mongoose.model("Orders");
const Customer = mongoose.model("Customer");
const User = mongoose.model("User");
const PO = mongoose.model("PurchaseOrder");
const BillHistory = mongoose.model("BillHistorys");
const Transaction = mongoose.model("Transaction");
const Adminuser = mongoose.model("Adminuser");
// const getGstData = require('../../apps/common/getGstData')
// const {messageBuilder} = require("../../apps/common/CommonFunctions")
// const Product = mongoose.model("Product");
const MarketplaceSubscribes = mongoose.model("MarketplaceSubscribes");
const Product = mongoose.model("Products");
// const PO = mongoose.model("PurchaseOrder");
const CsvUpload = mongoose.model("CsvUpload");
const Orderprioritys = mongoose.model("Orderprioritys");
const WInward = mongoose.model("WInward");
const moment = require("moment-timezone");
const {
  constantValues,
  mongooseConstantValues,
} = require("../../apps/common/systemConstents");
const {
  updateShopperrPriceAlgo,
  getMsrp,
} = require("../../apps/middlewares/priceAlgo");
const path = require("path");
const crypto = require("crypto");
const shortid = require("shortid");
const Razorpay = require("razorpay");

const registerWebhooks = require("../../apps/common/registerWebhooks");

const request = require("request-promise");
const csv = require("csvtojson");
const ObjectsToCsv = require("objects-to-csv");
const fs = require("fs");
const AWS = require("aws-sdk");
const { Console } = require("console");
const ID = "AKIAZQ3DPSAOW34EMAWP";
const SECRET = "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";
const BUCKET_NAME = "test-bucket";
const s3 = new AWS.S3({
  accessKeyId: ID,
  secretAccessKey: SECRET,
  apiVersion: "latest",
});

const razorpay = new Razorpay({
  key_id: "rzp_live_IC42DK5275ZEr9",
  key_secret: "arcpeeTwh9MTMppmyYwAxkHA",
});

// order create webhook routes
exports.orderCreateShopify = (req, res) => {
  const storeDomain = req.headers["x-shopify-shop-domain"];
  const orderData = req.body;
  // console.log(orderData)
  // return false;
  const order = new Order({
    storeDomain: storeDomain,
    mkpOrderId: orderData.id,
    consumerPrice: orderData.total_price,
    // products: orderData.line_items,
    orderSerial: orderData.order_number,
    // customer: orderData.customer,
    createdAt: new Date(orderData.created_at).toISOString(),
    // fulfillmentStatus: orderData.fulfillment_status,
    shippingLines: orderData.shipping_lines,
    // discountCodes: orderData.discount_applications,
    paymentDetails: orderData.payment_details,
    // billingAddress: orderData.billing_address,
    // shippingAddress: orderData.shipping_address,
    taxLines: orderData.tax_lines,
    // note: orderData.note ? orderData.note : "",
    paymentMethod: orderData.payment_gateway_names,
    pStatus: orderData.financial_status,
  });

  order
    .save()
    .then((order) => {
      res.sendStatus(200);
    })
    .catch((err) => {
      res.sendStatus(200);
    });
};
exports.webhookUpdate = (req, res) => {
  return res.sendStatus(200);
};
exports.OrderShopify = async (req, res) => {
  // const ProductsubscribeData = await Productsubscribe.find({ retailer : req.body.user });

  try {
    return res.status(200).json(
      await Order.countDocuments({
        fulfillmentStatus: null,
        merchantId: req.params.merchantId,
        created_on: {
          $gte: new Date(req.params.start),
          $lt: new Date(req.params.end),
        },
      })
    );
  } catch (err) {
    let result = { error: 1, response: err.toString() };
    return res.status(500).json(result);
  }
};

exports.DashboardOrder = async (req, res) => {
  //6650320ec2269f9c3937e8ad

  try {
    return res.status(200).json(
      await Order.countDocuments({
        merchantId: req.params.merchantId,
        updatedAt: {
          $gte: new Date(req.params.start + "T00:00:00.000Z"),
          $lt: new Date(req.params.end + "T23:59:59Z"),
        },
      })
    );
  } catch (err) {
    let result = { error: 1, response: err.toString() };
    res.status(500).json(result);
  }
};

exports.TopProducts = async (req, res) => {
  try {
    await Order.find({ merchantId: req.params.merchantId }, { products: 1 })
      .limit(20)
      .sort({ _id: -1 })
      .then((data) => {
        if (data.length > 0) {
          let products = data.map((item) => {
            return item.products;
          });
          let prod = products.flatMap((product) => {
            return product;
          });
          let flags = [];
          let uniqueProduct = [];
          let l = prod.length;
          let i;
          for (i = 0; i < l; i++) {
            if (flags[prod[i].sku]) continue;
            flags[prod[i].sku] = true;
            uniqueProduct.push({
              name: prod[i].name,
              sku: prod[i].sku,
              price: parseInt(prod[i].price),
            });
          }
          let top5 = uniqueProduct.slice(0, 5);
          res.status(200).json(top5);
        } else {
          res.status(500).json({ status: 1, response: "No data found." });
        }
      });
  } catch (err) {
    let result = { error: 1, response: err.toString() };
    res.status(500).json(result);
  }
};

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

// 	try{
// 		return res.status(200).json(await Order.find({
// 			merchantId : req.params.merchantId ,
// 			createdAt: { $gte: new Date(req.params.start+'T00:00:00.000Z'), $lt: new Date(req.params.end+'T23:59:59Z'), } } , { orderId : 1 , price : 1 , createdAt : 1 }
// 		).then((data) => {
// 			var holder = {};
// 			data.forEach(function (d) {
// 				if (holder.hasOwnProperty(moment(d.createdAt).format("MMM Do YY"))) {
// 					holder[moment(d.createdAt).format("MMM Do YY")] = holder[moment(d.createdAt).format("MMM Do YY")] + d.price;
// 				} else {
// 					holder[moment(d.createdAt).format("MMM Do YY")] = d.price;
// 				}
// 			})
// 			let dateArray = [];
// 			let revenueArray = [];
// 			for (var prop in holder) {
// 				dateArray.push(prop)
// 				revenueArray.push(holder[prop])
// 			}

// 			return {
// 				date: dateArray,
// 				revenue: revenueArray,
// 			};
// 		}))
// 	} catch (err) {
//         let result = {'error' : 1 , 'response' : err.toString() }
//         return res.status(500).json(result);
//     }

// };

exports.TotalRevenue = async (req, res) => {
  try {
    return res.status(200).json(
      await Order.find(
        {
          merchantId: req.params.merchantId,
          createdAt: {
            $gte: new Date(req.params.start + "T00:00:00.000Z"),
            $lt: new Date(req.params.end + "T23:59:59Z"),
          },
        },
        { orderId: 1, orderDetails: 1, createdAt: 1 }
      ).then(async (data) => {
        let spPrice = 0;

        let orderData = await Promise.all(
          data.map(async (item) => {
            // Use Promise.all to wait for all products within the current item
            let products_data = await Promise.all(
              item.orderDetails.map(async (product) => {
                const productSp = await Product.findOne(
                  { code: product.sku },
                  { sp: 1 }
                );
                if (productSp) {
                  spPrice += productSp.sp; // Accumulate spPrice for each product
                }

                // Return individual product data
                return {
                  spPrice: spPrice,
                };
              })
            );

            // Return the complete product data for this item
            return products_data;
          })
        );

        // console.log(orderData);  // Logs the accumulated data after all promises resolve
        // console.log("Total spPrice:", spPrice.toFixed(2));
        // console.log(spPrice)

        return {
          revenue: spPrice.toFixed(2),
        };
      })
    );
  } catch (err) {
    let result = { error: 1, response: err.toString() };
    return res.status(500).json(result);
  }
};

exports.ProductsData = async (req, res) => {
  try {
    const temp = await Promise.all(
      res.paginatedResults.results.map((item) => {
        return new Promise(async (resolve, reject) => {
          return resolve({
            _id: item._id,
            image: _.isEmpty(item.imgUrl) ? "" : item.imgUrl[0].src,
            supplierName: await getSupplierName(item.supplier_id),
            name: item.name,
            code: item.code,
            category: item.category,
            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,
          });
        });
      })
    )
      .then((data) => data)
      .catch((err) => {
        throw err;
      });
    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.OrderList = async (req, res) => {
  const merchantId = req.query.merchantId;
  // const storeDomain = req.query.store
  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 = { isDelete: false, merchantId };
  if (req.query.fromDate && req.query.toDate) {
    query.createdAt = {
      $gte: new Date(req.query.fromDate),
      $lt: new Date(req.query.toDate),
    };
  }

  if (req.query.text) {
    query.orderSerial = req.query.text;
  }

  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,
    };
  }

  let query1 = {
    isDelete: false,
    merchantId,
    oStatus: ["OS", "OB"],
    pStatus: "PU",
    dStatus: ["DN", "AD", "DD"],
  };
  if (req.query.fromDate && req.query.toDate) {
    query1.createdAt = {
      $gte: new Date(req.query.fromDate),
      $lt: new Date(req.query.toDate),
    };
  }
  const awaitingPayCount = await Order.countDocuments(query1).exec();

  let query2 = {
    isDelete: false,
    merchantId,
    oStatus: ["OS", "OB"],
    pStatus: "PD",
    dStatus: ["DN"],
  };
  if (req.query.fromDate && req.query.toDate) {
    query2.createdAt = {
      $gte: new Date(req.query.fromDate),
      $lt: new Date(req.query.toDate),
    };
  }
  const processingPayCount = await Order.countDocuments(query2).exec();

  let query3 = {
    isDelete: false,
    merchantId,
    oStatus: ["OS", "OB"],
    sStatus: "SS",
    pStatus: "PD",
    dStatus: ["DN"],
  };
  if (req.query.fromDate && req.query.toDate) {
    query3.createdAt = {
      $gte: new Date(req.query.fromDate),
      $lt: new Date(req.query.toDate),
    };
  }
  const shippedCount = await Order.countDocuments(query3).exec();

  let query4 = {
    isDelete: false,
    merchantId,
    rStatus: ["RN"],
    dStatus: ["DP", "DD"],
  };
  if (req.query.fromDate && req.query.toDate) {
    query4.createdAt = {
      $gte: new Date(req.query.fromDate),
      $lt: new Date(req.query.toDate),
    };
  }
  const tickedCount = await Order.countDocuments(query4).exec();

  let query5 = { isDelete: false, merchantId, oStatus: ["OC"] };
  if (req.query.fromDate && req.query.toDate) {
    query5.createdAt = {
      $gte: new Date(req.query.fromDate),
      $lt: new Date(req.query.toDate),
    };
  }
  const cancelCount = await Order.countDocuments(query5).exec();

  let query6 = {
    isDelete: false,
    merchantId,
    recipientName: { $eq: "" },
    shippingPhoneNumber: { $eq: null },
    shippingPostalCode: { $eq: "" },
  };
  if (req.query.fromDate && req.query.toDate) {
    query6.createdAt = {
      $gte: new Date(req.query.fromDate),
      $lt: new Date(req.query.toDate),
    };
  }
  const abnormalCount = await Order.countDocuments(query6).exec();

  results.awaitingPayCount = awaitingPayCount;
  results.processingCount = processingPayCount;
  results.shippedCount = shippedCount;
  results.tickedCount = tickedCount;
  results.cancelCount = cancelCount;
  results.abnormalCount = abnormalCount;

  // console.log(query)

  if (req.query.status) {
    if (req.query.status == 2) {
      query = {
        isDelete: false,
        merchantId,
        recipientName: { $eq: "" },
        shippingPhoneNumber: { $eq: null },
        shippingPostalCode: { $eq: "" },
      };
      // query = { "customer.first_name": { $eq: "Malak" }, "customer.phone": { $eq: "9876767656" }, "shippingAddress.phone": { $eq: "9876767656" }, "shippingAddress.zip": { $eq: "110070" } }
    } else if (req.query.status == 3) {
      query.oStatus = ["OS", "OB"];
      query.pStatus = ["PU"];
      query.dStatus = ["DN", "AD", "DD"];
    } else if (req.query.status == 4) {
      query.oStatus = ["OS", "OB"];
      query.pStatus = "PD";
      query.dStatus = ["DN"];
    } else if (req.query.status == 5) {
      query.oStatus = ["OS", "OB"];
      query.pStatus = "PD";
      query.sStatus = "SS";
      query.dStatus = ["DN"];
    } else if (req.query.status == 6) {
      query.rStatus = ["RN"];
      query.dStatus = ["DP", "DD"];
    } else if (req.query.status == 7) {
      query.oStatus = ["OC"];
    }
  }
  // console.log(query);

  const resultCount = await Order.countDocuments(query).exec();
  results.resultCount = resultCount;

  try {
    // results.results = await Order.find(query,{merchantId:1,created_on:1,orderNumber:1,"customer.first_name":1,"customer.last_name":1,price:1,poProcess:1,"products.name":1,"products.sku":1,"resellerPrice":1,"marketPlace":1,orderSerial:1,orderId:1})
    results.results = await Order.find(query)
      .sort({ _id: -1 })
      .limit(limit)
      .skip(startIndex)
      .exec();
    res.send(results);
  } catch (e) {
    res.status(500).json({ message: e.message });
  }
};
exports.merchantOrderDetail = async (req, res) => {
  let productArr = [];
  let productNameArr = [];
  let calItem = 0;
  let calPrice = 0;

  // console.log(JSON.stringify(req.params.merchantId))

  // return false;
  const data = await Order.find();
  // console.log(data);
  const productData = await Product.find();
  // console.log(productData)
  // return true;
  let itemArray = [];
  data.forEach((item, i) => {
    item.products.forEach((sss, i) => {
      if (sss.sku !== undefined) {
        itemArray.push({
          name: sss.name,
          sku: sss.sku,
          price: sss.price,
          store: sss.store.toLowerCase(),
        });
      }
    });
  });

  let makeTempArray = [];

  itemArray.forEach((product, i) => {
    if (product.store == req.params.store) {
      const productObj = {
        name: product.name,
        sku: product.sku,
        price: parseInt(product.price),
        store: product.store,
        count: 1,
      };
      makeTempArray.push(productObj);
      productNameArr.push(product.sku);
    }
  });

  makeTempArray.forEach((item, i) => {
    productData.forEach((product, j) => {
      if (product.varientArray.length != 0) {
        product.varientArray.forEach((vArr, l) => {
          if (vArr.sku === item.sku) {
            productArr.push(makeTempArray[i]);
          }
        });
      } else if (product.code === item.sku) {
        productArr.push(makeTempArray[i]);
      }
    });
  });

  var finalArr = [];

  var holder = {};

  productArr.forEach(function (d) {
    if (holder.hasOwnProperty(d.sku)) {
      holder[d.sku] = holder[d.sku] + d.price;
    } else {
      holder[d.sku] = d.price;
    }
  });

  var obj = [];

  for (var prop in holder) {
    obj.push({ sku: prop, price: holder[prop] });
  }

  var holder1 = {};

  productArr.forEach(function (d) {
    if (holder1.hasOwnProperty(d.sku)) {
      holder1[d.sku] = holder1[d.sku] + d.count;
    } else {
      holder1[d.sku] = d.count;
    }
  });

  var obj2 = [];

  for (var prop in holder1) {
    obj2.push({ sku: prop, count: holder1[prop] });
  }

  let newArray = [];
  obj.forEach((item, i) => {
    obj2.forEach((test, i) => {
      if (item.sku === test.sku) {
        const newObject = {
          name: "",
          sku: test.sku,
          count: test.count,
          price: item.price,
        };
        newArray.push(newObject);

        store: req.params.store;
      }
      //  newArray.push(newObject)
    });
  });

  newArray.forEach((Arr, i) => {
    itemArray.forEach((item, index) => {
      if (newArray[i].sku === itemArray[index].sku) {
        newArray[i].name = itemArray[index].name;
      }
    });
  });
  return res.send(newArray);
};

exports.merchant = async (req, res) => {
  try {
    const merchant = await User.findOne(
      { _id: req.params.id },
      { email: 1, fName: 1, lName: 1, phoneNo: 1,company:1, gstNumber: 1, address: 1,balance:1 }
    );

    if (!merchant) {
      return res.status(404).json({ message: "Merchant not found" });
    }
    const orders = await Order.find(
      { merchantId: req.params.id },
      {    
        orderSerial: 1,
        storeDomain: 1,
        mkpOrderId: 1,
        consumerPrice: 1,
        orderDetails: {
          sku: 1,
          sellerSku: 1,
          quantity: 1,
          quantityShipped: 1,
          consumerPrice: 1,
          title: 1,
          recipientName: 1,
          finalPrice:1
        }
      }
    ).lean();

    return res.json({ merchant, orders });
  } catch (error) {
    return res.status(500).json({ message: error.toString() });
  }
};

exports.customers = async (req, res) => {
  const storeDomain = req.query.store;
  const userId = req.query.merchantId;

  const data = await Customer.find({ merchantId: userId });

  res.send(data);
};

exports.SingleOrder = async (req, res) => {
  const id = req.params.id;
  let orderStatusView = "";
  let preView = [];
  let orderDetails = [];
  let orderDetailsData = [];

  orderShippingID = 0;

  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 Product.find(
            { code: sku },
            { imgUrl: 1, price: 1, name: 1, sp: 1 }
          );

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

          // orderDetails.push('orderDetails', item.orderDetails);
          // orderDetails.push('sku', item.sku);
          // orderDetails.push('sellerSku', item.sellerSku);
          // orderDetails.push('quantity', item.quantity);
          // orderDetails.push('quantityShipped', item.quantityShipped);
          // orderDetails.push('consumerPrice', item.consumerPrice);
          // orderDetails.push('title', item.title);
          // orderDetails.push('_id', item._id);

          orderDetails = {
            sku: item.sku,
            sellerSku: item.sellerSku,
            quantity: item.quantity,
            quantityShipped: item.quantityShipped,
            consumerPrice: item.consumerPrice,
            title: item.title,
            _id: item._id,
          };

          order.order_shipping.map(async (item1, index) => {
            if (item1.sku === sku) {
              // orderDetails.push('os_tracking_no', item1.os_tracking_no);
              orderDetails.os_tracking_no = item1.os_tracking_no;
              orderDetails.shipping_method = item1.shipping_method;
            }
          });

          orderDetailsData.push(orderDetails);
          // console.log(add(order.order_shipping, '64020011'));

          return products_data[0];
        })
      );

      if (
        (order.oStatus == "OS" || order.oStatus == "OB") &&
        order.pStatus == "PU" &&
        (order.dStatus == "DN" ||
          order.dStatus == "AD" ||
          order.dStatus == "DD") &&
        order.rStatus == "RN"
      ) {
        orderStatusView = "Ordered";
      } else if (
        (order.oStatus == "OS" || order.oStatus == "OB") &&
        order.pStatus == "PS" &&
        (order.dStatus == "DN" ||
          order.dStatus == "AD" ||
          order.dStatus == "DD") &&
        order.rStatus == "RN"
      ) {
        orderStatusView = "Payment in process";
      } else if (
        (order.oStatus == "OS" || order.oStatus == "OB") &&
        (order.pStatus == "PD" || order.pStatus == "PP") &&
        (order.dStatus == "DN" ||
          order.dStatus == "AD" ||
          order.dStatus == "DD") &&
        order.sStatus == "SU"
      ) {
        orderStatusView = "Paid";
      } else if (
        (order.oStatus == "OS" || order.oStatus == "OB") &&
        (order.pStatus == "PD" || order.pStatus == "PP") &&
        (order.dStatus == "DN" ||
          order.dStatus == "AD" ||
          order.dStatus == "DD") &&
        order.sStatus == "SS"
      ) {
        orderStatusView = "Shipping";
      } else if (
        order.oStatus == "OD" &&
        order.pStatus == "PB" &&
        (order.dStatus == "DN" ||
          order.dStatus == "AD" ||
          order.dStatus == "DD")
      ) {
        orderStatusView = "Fulfilled";
      } else if (
        order.dStatus == "DP" ||
        order.dStatus == "AA" ||
        order.dStatus == "AP"
      ) {
        orderStatusView = "Dispute";
      } else if (
        (order.rStatus == "RA" ||
          order.rStatus == "RR" ||
          order.rStatus == "RC" ||
          order.rStatus == "RS" ||
          order.rStatus == "RD") &&
        order.oStatus !== "OC"
      ) {
        orderStatusView = "Return";
      } else if (order.oStatus == "OC") {
        orderStatusView = "Cancelled";
      } else {
        orderStatusView = "";
      }

      if (
        order.pStatus == "PU" &&
        order.oStatus !== "OC" &&
        order.oStatus !== "OD"
      ) {
        preView.push({
          desc: "cancelOrderDesc",
          name: "cancelOrder",
          // url: '/order/order/cancelOrder/orderId/'+id
        });

        preView.push({
          desc: "payNowDesc",
          name: "payNow",
          // url: '/order/buyer/showPayInfo/orderId/'+id
        });
      }
      if (
        order.pStatus == "PD" &&
        order.oStatus !== "OC" &&
        order.oStatus !== "OD" &&
        order.dStatus == "DN"
      ) {
        preView.push({
          desc: "openATicket",
          name: "openTicket",
          url: "/order/buyer/showPayInfo/orderId/" + id,
        });
      }

      if (order.dStatus == "DP" && order.oStatus !== "OC") {
        preView.push({
          desc: "disputeInformationDesc",
          name: "disputeInformation",
          url: "/dispute/common/dispute/orderId/" + id + "/",
        });
      }

      let condition = {
        code: order.orderDetails[0].sku,
      };
      Product.find(condition).then((poData) => {
        //
        res.status(200).send({
          order,
          poData,
          orderData,
          orderDetailsData,
          orderStatusView,
          preView,
          src: process.env.S3_BUCKET_FILE_URL,
        });
      });
    })
    .catch((err) => {
      res.send({ err });
    });
};
const formatDate = (timestamp) => {
  const date = new Date(timestamp);
  return date.toISOString().split("T")[0]; // 'YYYY-MM-DD' format
};

exports.DownloadOrderCsv = async (req, res) => {
  try {
    const merchantId = req.query.merchantId;

    if (!merchantId) {
      return res
        .status(400)
        .send({ error: 1, message: "MerchantId is required" });
    }

    const query = {
      isDelete: false,
      merchantId: mongoose.Types.ObjectId(merchantId),
    };
    // console.log(query);

    if (req.query.fromDate && req.query.toDate) {
      console.log("Date Range:", { fromDate, toDate });
      query.created_on = {
        $gte: new Date(req.query.fromDate).toISOString(),
        $lt: new Date(req.query.toDate).toISOString(),
      };
    }
    console.log(query.created_on);
    const orders = await Order.find(query).sort({ _id: -1 }).exec();
    console.log(orders);
    if (!orders || orders.length === 0) {
      return res.status(404).send({ error: 1, message: "No orders found" });
    }

    const csvData = await Promise.all(
      orders.map(async (order) => {
        const getOrderStatus =
          order.oStatus === "OC"
            ? "Cancelled"
            : order.rStatus !== "RN"
            ? "Refund"
            : order.dStatus === "DP" && order.disputeRole === 0
            ? "Action needed"
            : order.dStatus === "DP" && order.disputeRole === 1
            ? "Awaiting response"
            : order.dStatus === "DD" && order.disputeRole === 3
            ? "Refused"
            : order.pStatus === "PU" && order.sStatus === "SU"
            ? "Awaiting Payment"
            : order.pStatus === "PD" && order.sStatus === "SU"
            ? "Processing"
            : order.pStatus === "PD" && order.sStatus === "SS"
            ? "Shipped"
            : order.pStatus === "PP"
            ? "Refunded"
            : ""; // Default case

        return {
          "Order Number": order.orderSerial,
          "Marketplace Order ID": order.mkpOrderId,
          Recipient: order.recipientName,
          Amount: order.consumerPrice,
          Marketplace: order.storeDomain,
          "Order Date": formatDate(order.paidDate),
          "Paid Date": formatDate(order.paidDate),
          "Shipped Date": formatDate(order.paidDate),
          "Shipper Phone-Number": order.shippingPhoneNumber,
          "Tracking Number": order.order_shipping[0].os_tracking_no,
          "API ReturnReason": order.api_return_reseaon,
          "API ReturnStatus": order.api_return_status,
          Status: getOrderStatus,
          OrderBillingFirstName: order.billingAddress
            ? order.billingAddress.first_name
            : "",
        };
      })
    );

    const csv = new ObjectsToCsv(csvData);
    // const filePath = `../uploads/${merchantId}_orders.csv`;
    await csv.toDisk("./" + merchantId + ".csv");

    const d = new Date();
    const s3dir = `merchantOrder/${d.getFullYear()}/${d.getMonth() + 1}/`;
    const filename = `${Date.now()}_${merchantId}_orders.csv`;
    const fullPath = `${s3dir}${filename}`;
    const fileContent = fs.readFileSync("./" + merchantId + ".csv");

    await uploadExcel(fileContent, fullPath);

    const fileUrl = `${process.env.S3_BUCKET_FILE_URL}/${fullPath}`;

    const csvUpload = new CsvUpload({
      type: 12,
      cond: [{ mId: mongoose.Types.ObjectId(merchantId) }],
      mId: mongoose.Types.ObjectId(merchantId),
      url: fileUrl,
      date: new Date(),
    });

    await csvUpload.save();

    fs.unlink("./" + merchantId + ".csv", (err) => {
      if (err) throw err;
    });

    res.send({ error: 0, response: fileUrl });
  } catch (err) {
    console.error(err);
    res.status(500).send({ error: 1, message: "Internal Server Error" });
  }
};

exports.GetCsvByMerchant = async (req, res) => {
  let merchantId = mongoose.Types.ObjectId(req.body.merchantId);
  let csvType = req.body.csvType;
  await CsvUpload.find({ mId: merchantId, type: { $in: csvType } })
    .sort({ _id: -1 })
    .limit(50)
    .then((result) => {
      let finalObject = { error: 0, data: result };
      return res.status(200).send(finalObject);
    })
    .catch(() => {
      return res.status(400).send("error");
    });
};

exports.BulkUploadOrder1 = async (req, res) => {
  if (req.files != null) {
    var fileContent = req.files.file.data;

    var merchantID = req.body.merchantId;
    // var csvType = req.body.csvType
    // var d = new Date();
    // const s3dir = "merchantOrder/" + d.getFullYear().toString() + "/" + (d.getMonth() + 1).toString() + "/";
    // var filename = 'upload_' + makeid(6) + '_' + merchantId + '.csv';
    // var fullPath = s3dir + filename;

    // await uploadExcel(fileContent, s3dir + filename).then(async () => {
    //     var url = process.env.S3_BUCKET_FILE_URL
    //     const csvUpload = await new CsvUpload({
    //         type: csvType,
    //         cond: [{ 'mId': mongoose.Types.ObjectId(merchantId) }],
    //         mId: mongoose.Types.ObjectId(merchantId),
    //         url: url + '/' + s3dir + filename,
    //         date: new Date()
    //     });

    // 	await csvUpload.save();

    var limit = 1;
    var error_messages = [];
    // var csvRequest = await CsvUpload.find({ $and: [{ "status": 0 }, { "type": 13 }, { '_id': mongoose.Types.ObjectId(merchantId) }] }).limit(parseInt(limit)).sort({ '_id': -1 });
    // var csvRequest = await CsvUpload.find({ "status": 0, "type": 13, 'mId': mongoose.Types.ObjectId(merchantId) }).limit(parseInt(limit)).sort({ '_id': -1 });

    // if (csvRequest.length > 0) {
    // 	if (csvRequest[0].mId) {
    // let merchantID = csvRequest[0].mId
    // console.log("inside csvRequest.length > 0");

    // var obj = {
    // 	status: 2
    // }

    let merchantData = await User.findOne({
      _id: mongoose.Types.ObjectId(merchantID),
    });
    // // console.log(merchantData);
    let supplierdata = await User.find({}, { _id: 1, price_algo: 1 });
    let storeDomain =
      merchantData.storeData.length > 0
        ? merchantData.storeData[0].storeDomain
        : "shopper.in";
    // let options = {
    // 	uri: csvRequest[0].url,
    // 	encoding: null
    // };

    //request(options, async function (error, response, body) {
    // if (error || response.statusCode !== 200) {
    // 	console.log(error);
    // } else {
    // let csv_data = await csv().fromString(body.toString());
    let csv_data = await csv().fromString(fileContent.toString());
    let orderData = {};
    let orderDataList = {};

    // console.log(csv_data)
    // return false;

    let i = 0;

    await Promise.all(
      csv_data.map(async (item) => {
        i++;

        // const randomString = generateRandomString(15);
        // let orders_serial='100'+randomString+'00'+i;
        let newSku = item.sku.replace(/\D/g, "");

        let condition = {
          code: newSku,
        };
        // console.log(condition)
        let resultProducts = await Product.findOne(condition);

        if (!resultProducts) {
          error_messages.push("Product not found- " + item.orderId);
        } else if (resultProducts.quantity <= 0) {
          error_messages.push("out of stock- " + item.orderId);
        } else {
          // 	orderDataList[item.orderId] = orderDataList[item.orderId] ? orderDataList[item.orderId] : {};
          // 	if (item.multipleProduct == 0) {
          // 		orderDataList[item.orderId] = {
          // 			// ...item,
          // 			order_serial: orders_serial,
          // 			newSku: newSku,
          // 			orderId: item.orderId,
          // 			shipPhoneNumber: item.shipPhoneNumber,
          // 			sku: item.sku,
          // 			quantityPurchased: item.quantityPurchased,
          // 			recipientName: item.recipientName,
          // 			shipAddress1: item.shipAddress1,
          // 			shipAddress2: item.shipAddress2,
          // 			shipAddress3: item.shipAddress3,
          // 			shipCity: item.shipCity,
          // 			shipState: item.shipState,
          // 			shipPostalCode: item.shipPostalCode,
          // 			consumerPrice: item.consumerPrice,
          // 			multipleProduct: item.orderId,
          // 			marketPlace: item.orderId,
          // 			OrderItemId: item.orderId
          // 		};
          // 	}else{
          // 		// orderDataList[item.orderId] = {
          // 		// 	...item,
          // 		// 	order_serial: orders_serial,
          // 		// 	newSku: newSku
          // 		// };
          // 		console.log(orderDataList)
          // 		console.log(orderDataList[item.orderId].sku +"!=="+ item.sku)
          // 		// If orderId exists and newSku is different, create a new array
          // 		if (orderDataList[item.orderId].newSku !== newSku) {
          // 			console.log('New SKU detected, creating new array');
          // 			orderDataList[item.orderId] = {
          // 				order_serial: orders_serial,
          // 				newSku: newSku,
          // 				orderId: item.orderId,
          // 				shipPhoneNumber: item.shipPhoneNumber,
          // 				sku: item.sku,
          // 				quantityPurchased: item.quantityPurchased,
          // 				recipientName: item.recipientName,
          // 				shipAddress1: item.shipAddress1,
          // 				shipAddress2: item.shipAddress2,
          // 				shipAddress3: item.shipAddress3,
          // 				shipCity: item.shipCity,
          // 				shipState: item.shipState,
          // 				shipPostalCode: item.shipPostalCode,
          // 				consumerPrice: item.consumerPrice,
          // 				multipleProduct: item.orderId,
          // 				marketPlace: item.orderId,
          // 				OrderItemId: item.orderId
          // 			};
          // 		} else {
          // 			console.log('Same SKU, updating existing array');
          // 			// If orderId exists and newSku is the same, update the existing array with new values
          // 			const updatedOrderData = orderDataList[item.orderId].orderData.map(orderItem => {
          // 				if (orderItem.orderId === item.orderId) {
          // 					return {
          // 						...orderItem,
          // 						...item,
          // 						order_serial: orders_serial,
          // 						newSku: newSku
          // 					};
          // 				}
          // 				return orderItem;
          // 			});
          // 			orderDataList[item.orderId].orderData = updatedOrderData;
          // 		}
          // 		// if ((orderDataList[item.orderId] && orderDataList[item.orderId].orderId === item.orderId) && (orderDataList[item.orderId].sku !== item.sku)) {
          // 		// 	console.log('New SKU detected, creating new array');
          // 		// 	orderDataList[item.orderId] = {
          // 		// 		// ...orderDataList[item.orderId],
          // 		// 		// orderData: [orderDataList[item.orderId], {
          // 		// 			...item,
          // 		// 			order_serial: orders_serial,
          // 		// 			newSku: newSku
          // 		// 		//}]
          // 		// 	};
          // 		// } else {
          // 		// 	console.log('Same SKU, updating existing array');
          // 		// 	// If orderId exists and newSku is the same, update the existing array
          // 		// 	orderDataList[item.orderId].orderData = orderDataList[item.orderId].orderData || [];
          // 		// 	orderDataList[item.orderId].orderData.push(item);
          // 		// }
          // 	}
          // 	// console.log(item);
          // 	// if (item.multipleProduct == 0) {
          // 	// 	// if (orderDataList[item.orderId].sku === item.sku) {
          // 	// 	// 	console.log(item.sku)
          // 	// 	// }
          // 	// 	// if (orderDataList[item.orderId] && orderDataList[item.orderId].orderId === item.orderId) {
          // 	// 	// 	console.log('already exist')
          // 	// 	// 	console.log('Order ID:', item.orderId);
          // 	// 	// 	// If orderId already exists, create a new array orderData if it doesn't exist
          // 	// 	// 	orderDataList[item.orderId].orderData = orderDataList[item.orderId].orderData || [];
          // 	// 	// 	// Push the item to the orderData array
          // 	// 	// 	orderDataList[item.orderId].orderData.push(item);
          // 	// 	// } else{
          // 	// 		// console.log('new');
          // 	// 		// console.log('Order ID:', item.orderId);
          // 	// 		orderDataList[item.orderId] = {
          // 	// 			...item,
          // 	// 			order_serial: orders_serial,
          // 	// 			newSku: newSku
          // 	// 		};
          // 	// 		// console.log(orderDataList)
          // 	// 	// }
          // 	// } else {
          // 	// 	// if (orderDataList[item.orderId] && orderDataList[item.orderId].orderId == item.orderId) {
          // 	// 	// 	orderDataList[item.orderId].orderData = orderDataList[item.orderId].orderData ? orderDataList[item.orderId].orderData : [];
          // 	// 	// 	orderDataList[item.orderId].orderData.push(item);
          // 	// 	// }
          // 	// 	if (orderDataList[item.orderId] && orderDataList[item.orderId].orderId === item.orderId) {
          // 	// 		console.log("first if"+item.sku)
          // 	// 		// If orderId already exists, create a new array orderData if it doesn't exist
          // 	// 		orderDataList[item.orderId].orderData = orderDataList[item.orderId].orderData || [];
          // 	// 		// Push the item to the orderData array
          // 	// 		orderDataList[item.orderId].orderData.push(item);
          // 	// 	} else {
          // 	// 		console.log("first else"+item.sku)
          // 	// 		// If orderId doesn't exist, create a new entry in orderDataList
          // 	// 		orderDataList[item.orderId] = {
          // 	// 			...item, // Create a new array containing the item
          // 	// 			order_serial: orders_serial,
          // 	// 			newSku: newSku
          // 	// 		};
          // 	// 	}
          // 	// }
        }
      })
    );

    // console.log(csv_data);

    // orderDataList.map((order) => {
    // 	console.log(order)

    // });
    // return false;

    if (Object.values(csv_data).length > 0) {
      let uploadRes = await Promise.all(
        Object.values(csv_data).map((order, index) => {
          return new Promise(async (resolve, reject) => {
            index++;

            const randomString = generateRandomString(15);
            let orders_serial = "100" + randomString + "00" + index;
            let newSku = order.sku.replace(/\D/g, "");

            let orderId = order.orderId;
            let sku = newSku;
            let productCond = {
              $or: [{ code: sku }, { "varientArray.sku": sku }],
            };
            let productData = await getProductData(productCond);

            // console.log(orderDataList);
            // return false;

            let products = [];
            let priceAlgo = supplierdata.find(
              (o) => o._id == productData.supplier_id
            );
            let suppllierOrigin = priceAlgo.price_algo;
            let fp = productData.price ? productData.price : 0;
            let pw = productData.weight ? productData.weight : 0;
            let pbcd = productData.bcd ? productData.bcd : 10;
            let pigst = productData.igst ? productData.igst : 18;
            let pswc = productData.swcOnBcd ? productData.swcOnBcd : 10;
            let length = productData.length ? productData.length : 0;
            let width = productData.width ? productData.width : 0;
            let height = productData.height ? productData.height : 0;
            let mrps = 0;
            let margin = productData.productMargin
              ? productData.productMargin
              : 40;
            let sp = await updateShopperrPriceAlgo(
              Number(fp),
              Number(pw),
              suppllierOrigin,
              pbcd,
              pigst,
              pswc,
              length,
              width,
              height,
              mrps,
              margin
            );
            let totalPrice = "";
            totalPrice = sp.airPrice.price * order.quantityPurchased;
            // let product = {
            // 	id: productData._id,
            // 	name: productData.name,
            // 	price: sp.airPrice.price,
            // 	price_set: {
            // 		shop_money: {
            // 			amount: sp.airPrice.price,
            // 			currency_code: "INR"
            // 		}
            // 	},
            // 	quantity: order.quantityPurchased,
            // 	sku: order.sku,
            // 	title: productData.name,
            // 	total_discount: 0,
            // 	total_discount_set: {
            // 		shop_money: {
            // 			amount: null,
            // 			currency_code: "INR"
            // 		}
            // 	},
            // 	total_gst: "",
            // 	total_gst_set: {
            // 		shop_money: {
            // 			amount: null,
            // 			currency_code: "INR"
            // 		}
            // 	},
            // 	total_shipping_cost_set: {
            // 		shop_money: {
            // 			amount: null,
            // 			currency_code: "INR"
            // 		}
            // 	}
            // }

            // products.push(product)

            // if (order.orderData) {
            // 	for (let i = 0; i < (order.orderData).length; i++) {
            // 		let singleOrderData = order.orderData[i]
            // 		let productCond1 = { $or: [{ code: singleOrderData.sku }, { 'varientArray.sku': singleOrderData.sku }] }
            // 		let productData1 = await getProductData(productCond1)
            // 		let priceAlgo1 = supplierdata.find(o => o._id == productData1.supplier_id)
            // 		let suppllierOrigin1 = priceAlgo1.price_algo
            // 		let vfp = productData1.price ? productData1.price : 0
            // 		let vpw = productData1.weight ? productData1.weight : 0
            // 		let vpbcd = productData1.bcd ? productData1.bcd : 10
            // 		let vpigst = productData1.igst ? productData1.igst : 18
            // 		let vpswc = productData1.swcOnBcd ? productData1.swcOnBcd : 10
            // 		let vlength = productData1.length ? productData1.length : 0
            // 		let vwidth = productData1.width ? productData1.width : 0
            // 		let vheight = productData1.height ? productData1.height : 0
            // 		let vmrps = 0
            // 		let vmargin = productData1.productMargin ? productData1.productMargin : 40
            // 		let vsp = await updateShopperrPriceAlgo(Number(vfp), Number(vpw), suppllierOrigin1, vpbcd, vpigst, vpswc, vlength, vwidth, vheight, vmrps, vmargin);
            // 		totalPrice = (parseFloat(totalPrice) + parseFloat((vsp.airPrice.price * singleOrderData.quantityPurchased)))
            // 		let product1 = {
            // 			id: productData1._id,
            // 			name: productData1.name,
            // 			price: vsp.airPrice.price,
            // 			price_set: {
            // 				shop_money: {
            // 					amount: vsp.airPrice.price,
            // 					currency_code: "INR"
            // 				}
            // 			},
            // 			quantity: singleOrderData.quantityPurchased,
            // 			sku: singleOrderData.sku,
            // 			title: productData1.name,
            // 			total_discount: 0,
            // 			total_discount_set: {
            // 				shop_money: {
            // 					amount: null,
            // 					currency_code: "INR"
            // 				}
            // 			},
            // 			total_gst: "",
            // 			total_gst_set: {
            // 				shop_money: {
            // 					amount: null,
            // 					currency_code: "INR"
            // 				}
            // 			},
            // 			total_shipping_cost_set: {
            // 				shop_money: {
            // 					amount: null,
            // 					currency_code: "INR"
            // 				}
            // 			}
            // 		}
            // 		products.push(product1);
            // 	}
            // }
            let first_name = "";
            let last_name = "";
            if (order.recipientName.includes(" ")) {
              first_name = order.recipientName
                .split(" ")
                .slice(0, -1)
                .join(" ");
              last_name = order.recipientName
                ? order.recipientName.split(" ").slice(1).join(" ")
                : "";
            } else {
              first_name = order.recipientName;
              last_name = "";
            }

            let address2 = order.shipAddress2 ? order.shipAddress2 : "";
            let address3 = order.shipAddress3 ? order.shipAddress3 : "";
            // let shippingAddress = {
            // 	"address1": order.shipAddress1 ? order.shipAddress1 : '',
            // 	"phone": order.shipPhoneNumber,
            // 	"city": order.shipCity,
            // 	"zip": order.shipPostalCode,
            // 	"province": order.shipState,
            // 	"country": "India",
            // 	"address2": address2 + ' ' + address3,
            // 	"company": "",
            // 	"latitude": null,
            // 	"longitude": null,
            // 	"country_code": "99",
            // 	"first_name": first_name,
            // 	"last_name": last_name,
            // 	"name": order.recipientName
            // }

            // let customer = {
            // 	"email": "",
            // 	"first_name": first_name,
            // 	"accepts_marketing": false,
            // 	"currency": "INR",
            // 	"verified_email": false,
            // 	"tax_exempt": false,
            // 	"phone": order.shipPhoneNumber,
            // 	"default_address": {
            // 		"address1": order.shipAddress1 ? order.shipAddress1 : '',
            // 		"phone": order.shipPhoneNumber,
            // 		"city": order.shipCity,
            // 		"zip": order.shipPostalCode,
            // 		"province": order.shipState,
            // 		"country": "India",
            // 		"address2": address2 + ' ' + address3,
            // 		"company": "",
            // 		"latitude": null,
            // 		"longitude": null,
            // 		"country_code": "99",
            // 		"first_name": first_name,
            // 		"last_name": last_name,
            // 		"name": order.recipientName
            // 	},
            // 	"total_spent": totalPrice,
            // 	"total_gst": "0.000000",
            // 	"total_shipping_cost": "0.000000",
            // 	"price": totalPrice,
            // 	"total_price_of_products": totalPrice,
            // 	"total_discount_amount": "0.000"
            // }

            // let merchantFirstName = merchantData.firstName ? merchantData.firstName : ''
            // let merchantLastName = merchantData.lastName ? merchantData.lastName : ''
            // let billingAddress = {
            // 	"address1": merchantData.address ? merchantData.address : '',
            // 	"phone": merchantData.phoneNo ? merchantData.phoneNo : '',
            // 	"city": merchantData.city ? merchantData.city : '',
            // 	"zip": merchantData.pincode ? merchantData.pincode : '',
            // 	"province": merchantData.district ? merchantData.district : '',
            // 	"country": merchantData.country ? merchantData.country : '',
            // 	"address2": " ",
            // 	"company": merchantData.companyName ? merchantData.companyName : '',
            // 	"latitude": null,
            // 	"longitude": null,
            // 	"first_name": merchantFirstName,
            // 	"last_name": merchantFirstName,
            // 	"name": merchantFirstName + ' ' + merchantLastName
            // }
            console.log("newsku " + order.newSku);
            let orderDetails = {
              orderItemId: order.OrderItemId,
              sku: newSku,
              sellerSku: order.sku,
              quantity: order.quantityPurchased,
              quantityShipped: 0,
              consumerPrice: totalPrice,
              title: productData.name,
            };

            const orders = new Order({
              merchantId: merchantID,
              storeDomain: storeDomain,
              mkpOrderId: order.orderId,
              consumerPrice: totalPrice,
              // currency: 'INR',
              createdAt: new Date(),
              // products: products,
              // orderNumber: order.orderId,
              storeDomain: order.marketPlace,
              // customer: customer,
              fulfillmentStatus: null,
              // pStatus: 'unpaid',
              updatedAt: new Date(),
              // paymentDetails: '',
              // billingAddress: billingAddress,
              // shippingAddress: shippingAddress,
              // resellerPrice:order.consumerPrice,
              // productOrderDate:order.orderDate,
              orderSerial: orders_serial,
              recipientName: first_name,
              recipientEmail: "",
              shippingPhoneNumber: order.shipPhoneNumber,
              shippingAddress1: order.shipAddress1 ? order.shipAddress1 : "",
              shippingCity: order.shipCity,
              shippingAddress2: address2,
              shippingAddress3: address3,
              shippingPostalCode: order.shipPostalCode,
              shippingState: order.shipState,
              orderDetails: orderDetails,
            });
            console.log(orders.mkpOrderId);

            // return false;
            let ordersData = await Order.find({
              mkpOrderId: orders.mkpOrderId,
            });
            // console.log(ordersData)

            // return false;
            if (ordersData.length > 0) {
              console.log("ordersData");
              return false;
              // console.log("update"+orders.mkpOrderId);
              // var obj1 = {
              // 	storeDomain: storeDomain,
              // 	consumerPrice: totalPrice,
              // 	currency: 'INR',
              // 	products: products,
              // 	orderNumber: order.orderId,
              // 	marketPlace:order.marketPlace,
              // 	customer: customer,
              // 	fulfillmentStatus: null,
              // 	updated_on: new Date(),
              // 	paymentDetails: '',
              // 	billingAddress: billingAddress,
              // 	shippingAddress: shippingAddress,
              // 	resellerPrice:order.consumerPrice,
              // 	productOrderDate:order.orderDate,
              // }
              var obj1 = {
                storeDomain: storeDomain,
                consumerPrice: totalPrice,
                currency: "INR",
                mkpOrderId: order.orderId,
                fulfillmentStatus: null,
                updatedAt: new Date(),
                recipientName: first_name,
                recipientEmail: "",
                shippingPhoneNumber: order.shipPhoneNumber,
                shippingAddress1: order.shipAddress1 ? order.shipAddress1 : "",
                shippingCity: order.shipCity,
                shippingAddress2: address2,
                shippingAddress3: address3,
                shippingPostalCode: order.shipPostalCode,
                shippingState: order.shipState,
                // orderDetails:orderDetails
              };

              console.log("mkpOrderId " + orders.mkpOrderId);
              console.log("orderDetails.sku " + order.newSku);
              let ordersDetailsData = await Order.find({
                mkpOrderId: orders.mkpOrderId,
                "orderDetails.sku": order.newSku,
              });
              console.log(ordersDetailsData);
              if (ordersDetailsData.length > 0) {
                var obj2 = {
                  orderDetails: orderDetails,
                };
                console.log(obj2);
                Order.updateOne(
                  { mkpOrderId: orders.mkpOrderId },
                  { $set: obj2 },
                  { upsert: false }
                ).then(() => {
                  console.log("second update");
                });
              }

              Order.updateOne(
                { mkpOrderId: orders.mkpOrderId },
                { $set: obj1 },
                { upsert: false }
              )
                .then(() => {
                  // resolve({ 'error': 0, 'response': 'Order Successfully Updated.' })
                  console.log("inside update");

                  return res.status(200).send({
                    error: 0,
                    response: "Order Successfully Updated." + error_messages,
                  });
                })
                .catch((e) => {
                  console.log(e);
                  // resolve({ 'error': 0, 'response': 'Something Went Wrong.' })
                  return res
                    .status(200)
                    .send({ error: 1, response: "Something Went Wrong." });
                });
            } else {
              console.log("order");
              // console.log(orders)
              // return false;
              orders
                .save()
                .then((data) => {
                  // resolve({ 'error': 0, 'response': 'Order Successfully Saved.' });
                  // return res.status(200).send({'error' : 0 , 'response' : 'Order Successfully Saved.'+error_messages})
                })
                .catch((e) => {
                  console.log(e);
                  // resolve({ 'error': 0, 'response': 'Something Went Wrong.' })
                  // return res.status(200).send({'error' : 1 , 'response' : 'Something Went Wrong.'})
                });
            }

            var obj = {
              status: 1,
            };

            // CsvUpload.updateOne({ "_id": csvRequest['0']._id }, { $set: obj }, { upsert: false }).then(() => {

            // })
          });
        })
      )
        .then((data) => data)
        .catch((err) => err);
    } else {
      if (error_messages.length > 0) {
        return res.status(200).send({ error: 1, response: error_messages });
      }
    }

    //}
    // 		});

    // 	}
    // }

    // return res.status(200).send({'error' : 0 , 'response' : 'Csv upload successfully.'})
    // }).catch(err=>{
    // 	return res.status(200).send({'error' : 1 , 'response' : 'Something went wrong.'})
    // });
  } else {
    return res.send({
      error: 1,
      response: "Select a csv file for uploaddddd.",
    });
  }
};

exports.BulkUploadOrder = async (req, res) => {
  if (req.files != null) {
    var fileContent = req.files.file.data;
    var merchantID = req.body.merchantId;
    var limit = 1;
    let merchantData = await User.findOne({
      _id: mongoose.Types.ObjectId(merchantID),
    });
    let storeDomain =
      merchantData.storeData.length > 0
        ? merchantData.storeData[0].storeDomain
        : "shopper.in";

    let csv_data = await csv().fromString(fileContent.toString());
    let orderDataList = {};
    let i = 0;
    let error_messages = [];

    const orderprioritys = await Orderprioritys.find({});
    // console.log(orderprioritys);
    var ind = 0;
    var ch = 0;
    var blk = 0;
    var china_process_opt = 0;
    var india_process_opt = 0;
    var bulk_process_opt = 0;
    const priorityMap = [1, 2, 3];
    if (orderprioritys.length > 0) {
      orderprioritys.forEach((item) => {
        ind = priorityMap[item.india];
        ch = priorityMap[item.china];
        blk = priorityMap[item.bulk];
      });
    }
    // console.log(`India: ${ind}, China: ${ch}, Bulk: ${blk}`);
    // // console.log(ind)

    // return false;
    await Promise.all(
      csv_data.map(async (item) => {
        try {
          i++;
          const randomString = generateRandomString(15);
          let orders_serial = "100" + randomString + "00" + i;
          let newSku = item.sku.replace(/\D/g, "");
          var china_process = 0;

          let china_process_values = [];
          let china1 = 0;
          let china2 = 0;
          let china3 = 0;
          //item.orderId

          const existOrder = await Order.find({ mkpOrderId : item.orderId })
          

          let condition = {
            code: item.sku,
          };
          let resultProducts = await Product.findOne(condition);
          // console.log(resultProducts.stock);

          if(existOrder.length>0){

            // resolve({
            //   error: 1,
            //   response: "Order already existed.",
            // });
            error_messages.push("Order already existed." + item.orderId);
          }else if (!resultProducts) {
            error_messages.push("Product not found - " + item.orderId);
          } 
          // else if (resultProducts.quantity <= 0) {
          //   error_messages.push("Out of stock - " + item.orderId);
          // } 
          else {
            if (ind == 1) {
              
              if (resultProducts.stock.in_qty > 0) {
                china_process = 0;
              } else {
                if (blk == 2 && ch == 3) {
                  // china_process = 3;
                  if (resultProducts.stock.blk_qty > 0) {
                    china_process = 3;
                  } else {
                    if (resultProducts.stock.china1 == 0) {
                      if (resultProducts.stock.china1 > 0) {
                        china1=1
                      }else if (resultProducts.stock.china2 > 0) {
                        china2=1
                      }else if (resultProducts.stock.china3 > 0) {
                        china3=1
                      }
                      
                      china_process = 1;
                    } else {
                      china_process = 4;
                    }
                  }
                } else if (blk == 3 && ch == 2) {
                  // china_process = 1;
                  if (resultProducts.stock.cn_qty > 0) {
                    if (resultProducts.stock.china1 == 0) {
                      if (resultProducts.stock.china1 > 0) {
                        china1=1
                      }else if (resultProducts.stock.china2 > 0) {
                        china2=1
                      }else if (resultProducts.stock.china3 > 0) {
                        china3=1
                      }
                      
                      china_process = 1;
                    } else {
                      china_process = 4;
                    }
                  } else {
                    if (resultProducts.stock.china1 == 0) {
                      if (resultProducts.stock.china1 > 0) {
                        china1=1
                      }else if (resultProducts.stock.china2 > 0) {
                        china2=1
                      }else if (resultProducts.stock.china3 > 0) {
                        china3=1
                      }
                      
                      china_process = 1;
                    } else {
                      china_process = 4;
                    }
                  }
                } else {
                  if (resultProducts.stock.china1 == 0) {
                    if (resultProducts.stock.china1 > 0) {
                      china1=1
                    }else if (resultProducts.stock.china2 > 0) {
                      china2=1
                    }else if (resultProducts.stock.china3 > 0) {
                      china3=1
                    }
                    
                    china_process = 1;
                  } else {
                    china_process = 4;
                  }
                }
              }
            } else if (blk == 1) {
              resultProducts.stock.blk_qty;
              
              if (resultProducts.stock.blk_qty > 0) {
                china_process = 3;
              } else {
                if (ind == 2 && ch == 3) {
                  // china_process = 0;
                  if (resultProducts.stock.in_qty > 0) {
                    china_process = 0;
                  } else {
                    if (resultProducts.stock.china1 == 0) {
                      if (resultProducts.stock.china1 > 0) {
                        china1=1
                      }else if (resultProducts.stock.china2 > 0) {
                        china2=1
                      }else if (resultProducts.stock.china3 > 0) {
                        china3=1
                      }
                      
                      china_process = 1;
                    } else {
                      china_process = 4;
                    }
                  }
                } else if (ind == 3 && ch == 2) {
                  // china_process = 1;
                  if (resultProducts.stock.in_qty > 0) {
                    china_process = 0;
                  } else {
                    if (resultProducts.stock.china1 == 0) {
                      if (resultProducts.stock.china1 > 0) {
                        china1=1
                      }else if (resultProducts.stock.china2 > 0) {
                        china2=1
                      }else if (resultProducts.stock.china3 > 0) {
                        china3=1
                      }
                      
                      china_process = 1;
                    } else {
                      china_process = 4;
                    }
                  }
                } else {
                  if (resultProducts.stock.china1 == 0) {
                    if (resultProducts.stock.china1 > 0) {
                      china1=1
                    }else if (resultProducts.stock.china2 > 0) {
                      china2=1
                    }else if (resultProducts.stock.china3 > 0) {
                      china3=1
                    }
                    
                    china_process = 1;
                  } else {
                    china_process = 4;
                  }
                }
              }
            } else if (ch == 1) {
              resultProducts.stock.cn_qty;
            
              if (resultProducts.stock.china1 > 0) {
                china1=1
              }else if (resultProducts.stock.china2 > 0) {
                china2=1
              }else if (resultProducts.stock.china3 > 0) {
                china3=1
              }

              if (resultProducts.stock.cn_qty > 0) {
                if (resultProducts.stock.china1 == 0) {
                  china_process = 1;
                } else {
                  china_process = 4;
                }
              } else {
                if (ind == 2 && blk == 3) {
                  // china_process = 0;
                  if (resultProducts.stock.in_qty > 0) {
                    china_process = 0;
                  } else {
                    if (resultProducts.stock.china1 == 0) {
                      china_process = 1;
                    } else {
                      china_process = 4;
                    }
                  }
                } else if (ind == 3 && blk == 2) {
                  // china_process = 1;
                  if (resultProducts.stock.blk_qty > 0) {
                    china_process = 3;
                  } else {
                    if (resultProducts.stock.china1 == 0) {
                      china_process = 1;
                    } else {
                      china_process = 4;
                    }
                  }
                } else {
                  if (resultProducts.stock.china1 == 0) {
                    china_process = 1;
                  } else {
                    china_process = 4;
                  }
                }
              }
            }
            // console.log(china_process)
            // return false;
            china_process_values.push(china_process);

            if (!orderDataList[item.orderId]) {
              orderDataList[item.orderId] = {
                orderId: item.orderId,
                shipPhoneNumber: item.shipPhoneNumber,
                sku: item.sku,
                quantityPurchased: item.quantityPurchased,
                recipientName: item.recipientName,
                shipAddress1: item.shipAddress1,
                shipAddress2: item.shipAddress2,
                shipAddress3: item.shipAddress3,
                shipCity: item.shipCity,
                shipState: item.shipState,
                shipPostalCode: item.shipPostalCode,
                consumerPrice: item.consumerPrice,
                multipleProduct: item.multipleProduct,
                marketPlace: item.marketPlace,
                OrderItemId: item.OrderItemId,
                order_serial: orders_serial,
                newSku: newSku,
                orderData: {},
                china1:china1,
                china2:china2,
                china3:china3,
              };
            }
            // return false;
            let orderData = orderDataList[item.orderId].orderData;

            if (item.multipleProduct == 0) {
              let newOrderId = 1;
              orderData[newOrderId] = [
                {
                  sku: item.sku,
                  consumerPrice: item.consumerPrice,
                  quantityPurchased: item.quantityPurchased,
                  china_process: china_process,
                },
              ];
              orderDataList[item.orderId].china_process = china_process;
            } else {
              let newOrderId = Object.keys(orderData).length + 1;
              if (!orderData[newOrderId]) {
                orderData[newOrderId] = [];
              }
              orderData[newOrderId].push({
                sku: item.sku,
                consumerPrice: item.consumerPrice,
                quantityPurchased: item.quantityPurchased,
                china_process: china_process,
              });
            }

            orderDataList[item.orderId].orderData = orderData;

            if (item.multipleProduct != 0) {
              let uniqueValues = [...new Set(china_process_values)];
              let defaultChinaProcess =
                uniqueValues.length === 1 ? uniqueValues[0] : 1;

              orderDataList[item.orderId].china_process = defaultChinaProcess;
            }
          }
        } catch (error) {
          console.error(
            `Error processing item with orderId ${item.orderId}:`,
            error
          );
          error_messages.push(
            `Error processing item with orderId ${item.orderId}`
          );
        }
      })
    );

    // console.log(orderDataList)
    // return false;
    if (Object.values(orderDataList).length > 0) {
      let uploadRes = await Promise.all(
        Object.values(orderDataList).map((order, index) => {
          return new Promise(async (resolve, reject) => {
            index++;
            const randomString = generateRandomString(15);
            let orders_serial = "100" + randomString + "00" + index;

            let totalPrice = 0;

            let first_name = "";
            let last_name = "";
            if (order.recipientName.includes(" ")) {
              first_name = order.recipientName
                .split(" ")
                .slice(0, -1)
                .join(" ");
              last_name = order.recipientName
                ? order.recipientName.split(" ").slice(1).join(" ")
                : "";
            } else {
              first_name = order.recipientName;
              last_name = "";
            }

            let address2 = order.shipAddress2 ? order.shipAddress2 : "";
            let address3 = order.shipAddress3 ? order.shipAddress3 : "";

            const totalLength = Object.values(order.orderData).reduce(
              (sum, arr) => sum + arr.length,
              0
            );

            let products = [];
            for (const key in order.orderData) {
              if (order.orderData.hasOwnProperty(key)) {
                const skuArray = order.orderData[key];

                for (const skuItem of skuArray) {
                  // console.log(`SKU: ${skuItem.sku}`);
                  let newSku = skuItem.sku.replace(/\D/g, "");

                  let productCond1 = {
                    $or: [
                      { code: skuItem.sku },
                      { "varientArray.sku": skuItem.sku },
                    ],
                  };
                  let productData1 = await getProductData(productCond1);

                  // console.log(productData1);
                  // return false;

                  totalPrice +=
                    skuItem.consumerPrice * skuItem.quantityPurchased;

                  let product1 = {
                    orderItemId: order.OrderItemId,
                    sku: newSku,
                    sellerSku: skuItem.sku,
                    quantity: skuItem.quantityPurchased,
                    quantityShipped: 0,
                    consumerPrice: skuItem.consumerPrice,
                    title: productData1.name,
                    chinaProcess: skuItem.china_process,
                    productPrice: productData1.sp,
                    finalPrice: productData1.sp * skuItem.quantityPurchased,
                  };
                  products.push(product1);
                }
              }
            }

            const newOrder = new Order({
              merchantId: merchantID,
              storeDomain: storeDomain,
              mkpOrderId: order.orderId,
              consumerPrice: totalPrice,
              createdAt: new Date(),
              storeDomain: order.marketPlace,
              fulfillmentStatus: null,
              updatedAt: new Date(),
              orderSerial: orders_serial,
              recipientName: first_name,
              recipientEmail: "",
              shippingPhoneNumber: order.shipPhoneNumber,
              shippingAddress1: order.shipAddress1 ? order.shipAddress1 : "",
              shippingCity: order.shipCity,
              shippingAddress2: address2,
              shippingAddress3: address3,
              shippingPostalCode: order.shipPostalCode,
              shippingState: order.shipState,
              chinaProcess: order.china_process,
              orderDetails: products,
              china1:order.china1,
              china2:order.china2,
              china3:order.china3
            });


            // console.log(newOrder)

            // return false;

            newOrder
              .save()
              .then((data) => {
                // console.log("order savedddddddd");
                // console.log(data._id);

                data.orderDetails.forEach(async (val) => {
                  let condition = {
                    code: val.sku,
                  };
                  let resultProducts = await Product.findOne(condition);

                  let productObj = { }

                  if(val.chinaProcess==0){
                    productObj = {
                      'stock.in_qty' : resultProducts.stock.in_qty - val.quantity
                    }
                  }else if(val.chinaProcess==1){
                    productObj = {
                      'stock.cn_qty' : resultProducts.stock.cn_qty - val.quantity
                    }
                  }else if(val.chinaProcess==2){
                    productObj = {
                      'stock.in_qty' : resultProducts.stock.in_qty - val.quantity
                    }
                  }else if(val.chinaProcess==3){
                    productObj = {
                      'stock.blk_qty' : resultProducts.stock.blk_qty - val.quantity
                    }
                  }
                  
                  await Product.updateOne(
                    { _id: mongoose.Types.ObjectId(resultProducts._id) },
                    { $set: productObj },
                    { upsert: false }
                  ).exec();

                  let userData = await User.findOne({ _id: data.merchantId });

                  const winward = new WInward({
                    spID: mongoose.Types.ObjectId(resultProducts.supplier_id),
                    orderId: mongoose.Types.ObjectId(data._id),
                    orderSerial: data.orderSerial,
                    s_orderno: data.orderSerial,
                    mkpOrderId: data.mkpOrderId,
                    sku: val.sku,
                    qty: val.quantity,
                    orderUnitPrice: resultProducts.sp,
                    OrderTotalPrice: resultProducts.sp * val.quantity,
                    order_status: 0,
                    created_date: new Date(),
                    account_name: userData.fName + " " + userData.lName,
                    sellerId: data.merchantId,
                    ship_phone: data.shippingPhoneNumber,
                    processBy: data.chinaProcess,
                    orderDate: data.orderDate,
                    china1:data.china1,
                    china2:data.china2,
                    china3:data.china3
                  });

                  await winward.save();
                });

                resolve({
                  error: 0,
                  response: "Order Successfully Saved." + error_messages,
                });
                // return res.status(200).send({'error' : 0 , 'response' : 'Order Successfully Saved.'})
              })
              .catch((e) => {
                console.log("errorrrrrrrrrrrrrr");
                console.log(e);
                resolve({
                  error: 0,
                  response: "Something Went Wrong." + error_messages,
                });
                // return res.status(200).send({'error' : 1 , 'response' : 'Order Successfully Saved.'})
              });
          });
        })
      );

      const hasErrors = uploadRes.some((res) => res.error === 1);
      if (hasErrors) {
        return res
          .status(200)
          .send({ error: 1, response: "Some orders failed to save." });
      } else {
        return res
          .status(200)
          .send({ error: 0, response: "All orders successfully saved." });
      }
    } else {
      if (error_messages.length > 0) {
        return res.status(200).send({ error: 1, response: error_messages });
      }
    }
  }
};

exports.SubscribedProduct = async (req, res) => {
  const page = parseInt(req.query.page);
  const limit = parseInt(req.query.limit);
  const startIndex = (page - 1) * limit;
  let results = {};
  const res1 = {};
  let totalCount = await MarketplaceSubscribes.countDocuments({
    mId: mongoose.Types.ObjectId(req.query.id),
  }).exec();
  let marketplaceProduct = await MarketplaceSubscribes.find(
    { mId: mongoose.Types.ObjectId(req.query.id) },
    { pId: 1, margin: 1 }
  );

  if (marketplaceProduct.length > 0) {
    try {
      const productPromises = marketplaceProduct.map(async (item) => {
        const product = await Product.findOne(
          { _id: mongoose.Types.ObjectId(item.pId) },
          {
            imgUrl: 1,
            supplier_id: 1,
            name: 1,
            varientArray: 1,
            invoicedesc: 1,
            code: 1,
            category: 1,
            price: 1,
            sp: 1,
            handle: 1,
          }
        )
          .sort({ _id: -1 })
          .limit(limit)
          .skip(startIndex)
          .exec();

        if (product) {
          // Create a new object to avoid modifying the retrieved product directly
          const productWithMargin = {
            ...product.toObject(), // Convert Mongoose document to plain JavaScript object
            margin: item.margin,
          };

          return productWithMargin;
        } else {
          return null; // Return null for products not found
        }

        // return product;
      });

      const products = await Promise.all(productPromises);

      const validProducts = products.filter(
        (product) => product !== null && product !== undefined
      );

      const results = {
        results: validProducts,
        count: validProducts.length,
        startIndex: startIndex,
      };

      const data = { url: process.env.S3_BUCKET_FILE_URL, item: results };

      res.json(data);
    } catch (error) {
      console.error("Error fetching product details:", error);
      res.status(500).json({ error: "Internal Server Error" });
    }
  } else {
    const data = { url: "", item: [] };
    res.json(data);
  }
};

exports.UnSubscribProduct = async (req, res) => {
  const {
    customerEmail = "",
    ids = "",
    getDetail = 0,
    unsubscribe = 0,
    margin = 75,
    is_draft = 0,
    merchantId = null,
    channel = "",
  } = req.body;
  if ((!customerEmail && !merchantId) || !ids || margin < 30 || margin > 400) {
    return res.send({ error: 1, message: "Invalid Params" });
  }
  try {
    let merchant = null;
    if (merchantId) {
      merchant = await User.findOne({
        _id: mongoose.Types.ObjectId(merchantId),
      });
    } else {
      merchant = await User.findOne({ email: customerEmail });
    }
    if (!merchant) {
      return res.send({ error: 1, message: "Merchant did not find" });
    }

    let mIds = [...ids.map((x) => mongoose.Types.ObjectId(x))];
    // let subscribeProducts = await MarketplaceSubscribes.find({ '_id': { $in: mIds } }, { code: 1 });

    let subscribeProducts = await MarketplaceSubscribes.find(
      { pId: { $in: mIds }, mId: mongoose.Types.ObjectId(merchantId) },
      { code: 1 }
    );

    if (!subscribeProducts || subscribeProducts.length === 0) {
      return res.send({ error: 1, message: "Products not found" });
    }

    let removeSubscribe = await MarketplaceSubscribes.remove({
      pId: { $in: mIds },
      mId: mongoose.Types.ObjectId(merchantId),
    });

    return res.send({
      error: 0,
      message:
        unsubscribe == 1
          ? "Product Unsubscribed Successfully."
          : "Product Subscribed Successfully.",
    });
  } catch (err) {
    return res.send({ error: 1, message: err.toString() });
  }
};

exports.SebscribeExcelMerchant = async (req, res) => {
  try {
    let supplierId = mongoose.Types.ObjectId(req.params.id);
    let data = await CsvUpload.find({
      mId: supplierId,
      type: { $in: [3, 4] },
    }).sort({ _id: -1 });
    let count = await CsvUpload.countDocuments({
      mId: supplierId,
      type: { $in: [3, 4] },
    });

    let finalData = [];
    data.forEach((item) => {
      try {
        let formattedDate = moment(item.date)
          .tz("Asia/Kolkata")
          .format("DD/MM/YYYY HH:mm:ss");

        let singleData = {
          supplierId: item.mId,
          status: item.status == 1 ? "Success" : "Pending",
          url: item.url || "#",
          resUrl: item.resUrl || "#",
          date: formattedDate,
        };

        finalData.push(singleData);
      } catch (error) {
        console.error("Error processing data for item:", item._id, error);
      }
    });

    let finalObject = { count: count, data: finalData };

    res.send(finalObject);
  } catch (error) {
    console.error("Error fetching and processing data:", error);
    res.status(500).send({ error: "Internal Server Error" });
  }
};

exports.UploadSubscribeProduct = async (req, res) => {
  var fileContent = req.files.file.data;
  var d = new Date();
  var merchantId = req.body.merchant_id;
  const s3dir =
    "merchantSubscribeList/" +
    d.getFullYear().toString() +
    "/" +
    (d.getMonth() + 1).toString() +
    "/";
  var filename = "upload_" + makeid(6) + "_" + merchantId + ".csv";
  var fullPath = s3dir + filename;
  await uploadExcel(fileContent, s3dir + filename).then(async () => {
    var url = process.env.S3_BUCKET_FILE_URL;
    const csvUpload = await new CsvUpload({
      type: 3,
      cond: [{ mId: mongoose.Types.ObjectId(merchantId) }],
      mId: mongoose.Types.ObjectId(merchantId),
      url: url + "/" + fullPath,
      date: new Date(),
    });
    try {
      const saveProduct = await csvUpload.save();

      res.send("success");
    } catch (err) {
      res.send("something went wrong");
    }
  });
};

exports.UploadAmazonCsv = async (req, res) => {
  var fileContent = req.files.file.data;
  var d = new Date();
  var merchantId = req.body.merchant_id;
  let isUploaded = req.body.is_uploaded;
  const s3dir =
    "merchantSubscribeList/" +
    d.getFullYear().toString() +
    "/" +
    (d.getMonth() + 1).toString() +
    "/";
  var filename = "upload_" + makeid(6) + "_" + merchantId + ".csv";
  // console.log(s3dir); return false;
  // return res.send(await uploadExcel(fileContent , s3dir + filename).then(async() => {
  // 	var url = process.env.S3_BUCKET_FILE_URL;
  // 	const csvUpload = await new CsvUpload({
  // 		type : 4,
  // 		cond : [{'mId' : mongoose.Types.ObjectId(merchantId)}],
  // 		mId : mongoose.Types.ObjectId(merchantId),
  // 		url  :  url+'/'+ s3dir + filename,
  // 		date : new Date(),
  // 		[mongooseConstantValues.IS_AMAZON_PRODUCT_UPLOADED]: (isUploaded ? 1 : 0)
  // 	});
  // 	await csvUpload.save();
  // 	return 'success';
  // }).catch(()=>"something went wrong"));

  await uploadExcel(fileContent, s3dir + filename).then(async () => {
    var url = process.env.S3_BUCKET_FILE_URL;
    const csvUpload = await new CsvUpload({
      type: 4,
      cond: [{ mId: mongoose.Types.ObjectId(merchantId) }],
      mId: mongoose.Types.ObjectId(merchantId),
      url: url + "/" + s3dir + filename,
      date: new Date(),
      [mongooseConstantValues.IS_AMAZON_PRODUCT_UPLOADED]: isUploaded ? 1 : 0,
    });
    try {
      const saveProduct = await csvUpload.save();

      res.send("success");
    } catch (err) {
      res.send("something went wrong");
    }
  });
};

exports.OrderCancel = async (req, res) => {
  // console.log(req.params.id);

  try {
    await Order.find({ _id: mongoose.Types.ObjectId(req.params.id) }).then(
      async (data) => {
        if (data.length > 0) {
          var obj = {
            oStatus: "OC",
            dStatus: "DN",
            cancelDate: new Date(),
          };

          try {
            await Order.updateOne(
              { _id: data[0]._id },
              { $set: obj },
              { upsert: false }
            )
              .exec()
              .then(() => {
                res.send({
                  error: 0,
                  response: "Order Cancelled successfully.",
                });
              });
          } catch (err) {
            res.send({ error: 1, response: "Something went wrong." });
          }
        } else {
          res.status(500).json({ status: 1, response: "No data found." });
        }
      }
    );
  } catch (err) {
    let result = { error: 1, response: err.toString() };
    res.status(500).json(result);
  }
};

exports.GetPayInfo = async (req, res) => {
  // console.log(req.body.user)
  // console.log(req.body.orderId)
  try {
    await Order.find(
      { _id: mongoose.Types.ObjectId(req.body.orderId) },
      {
        orderSerial: 1,
        oStatus: 1,
        pStatus: 1,
        consumerPrice: 1,
        "orderDetails.consumerPrice": 1,
      }
    ).then(async (data) => {
      if (data.length > 0) {
        const userWallet = await BillHistory.find(
          { merchantId: mongoose.Types.ObjectId(req.body.user) },
          { billType: 1, billAmt: 1, beforeAmt: 1, afterAmt: 1 }
        )
          .limit(1)
          .sort({ _id: -1 });

        // console.log(userWallet)

        res.status(200).json({ error: 0, response: data, balance: userWallet });
      } else {
        res.status(500).json({ error: 1, response: "No data found." });
      }
    });
  } catch (err) {
    let result = { error: 1, response: err.toString() };
    res.status(500).json(result);
  }
};
exports.ConfirmPayment = async (req, res) => {
  try {
    // console.log(req.body.orderId)
    // console.log(req.body.totalPrice)
    // console.log(req.body.user)

    const orderData = await Order.find({
      _id: mongoose.Types.ObjectId(req.body.orderId),
    });
    if (orderData.length > 0) {
      let orderSerial = orderData[0].orderSerial;

      const userWallet = await BillHistory.find({
        merchantId: mongoose.Types.ObjectId(req.body.user),
      })
        .sort({ crDate: -1 })
        .limit(1);
      if (userWallet.length > 0) {
        let afterAmt = userWallet[0].afterAmt;
        let beforeAmt = userWallet[0].beforeAmt;

        let final_amt = afterAmt - req.body.totalPrice;

        var obj = {
          pStatus: "PD",
          paidDate: new Date(),
        };
        // console.log(obj)
        await Order.updateOne(
          { _id: mongoose.Types.ObjectId(req.body.orderId) },
          { $set: obj },
          { upsert: false }
        ).exec();

        let balanceObj = {
          balance: final_amt,
        };
        await User.updateOne(
          { _id: mongoose.Types.ObjectId(req.body.user) },
          { $set: balanceObj },
          { upsert: false }
        );

        const billHistory = await new BillHistory({
          merchantId: req.body.user,
          pgOrderId: orderSerial,
          billType: 2,
          billAmt: req.body.totalPrice,
          beforeAmt: afterAmt,
          afterAmt: final_amt,
          crDate: new Date(),
          modDate: new Date(),
          comment: "Order Payment",
        });

        try {
          const saveBill = await billHistory.save().then(() => {
            res.send({ error: 0, response: "Confirm" });
          });
        } catch (err) {
          res.send({ error: 1, response: err.toString() });
        }
      }
    }
  } catch (err) {
    let result = { error: 1, response: err.toString() };
    res.status(500).json(result);
  }
};

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 {
    }
  });
}

exports.customersMerchantProfile = async (req, res) => {
  // console.log(req)
  let mer = await User.findOne({ _id: req.params.userId });
  // console.log(mer)
  return res.send(mer);
};
exports.customersMerchantSettingUpdate = (req, res) => {
  let _id = req.body._id;
  // console.log(req.body._id)
  let updateObj = {
    address: req.body.address,
    city: req.body.city,
    company: req.body.company,
    email: req.body.email,
    fName: req.body.firstName,
    gstNumber: req.body.gstNumber,
    lName: req.body.lastName,
    phoneNo: req.body.phoneNo,
    pincode: req.body.pincode,
    state: req.body.state,
  };
  try {
    User.updateOne(
      { _id: mongoose.Types.ObjectId(_id) },
      { $set: updateObj },
      { upsert: false }
    )
      .exec()
      .then(() => {
        res.send({ error: 0, response: "Record updated successfully." });
      });
  } catch (err) {
    res.send({ error: 1, response: "Something went wrong." });
  }
};
exports.getMerchant = async (req, res) => {
  // console.log(req.body.id)
  await User.findOne(
    { _id: mongoose.Types.ObjectId(req.body._id) },
    { balance: 1 }
  )
    .then((balance) => {
      res.send({ error: 0, response: balance });
    })
    .catch((e) => {
      res.send({ error: 1, response: "Something went wrong." });
    });
};

exports.MerchantPaynow = async (req, res) => {
  // await PgOrderId.find({} , {id : 1}).sort({'_id' : -1}).limit(1).then((data) => {

  let transaction = new Transaction({
    orderId: shortid.generate(),
    pmethod: "cashfree",
    supplier_id: req.body.id,
    amount_paid: req.body.balance,
  });

  transaction
    .save()
    .then(async (data) => {
      let cashfreeAppId = process.env.CASHFREE_APP_ID;
      let cashfreeSecrateKey = process.env.CASHFREE_SECRATEKEY;
      let apiEndpoint = process.env.API_END_POINT;
      let httpUrl = process.env.HTTP_URL;
      let merchantId = req.body.id;
      let orderAmount = req.body.balance;
      let merchnatinfo = await User.findOne({
        _id: mongoose.Types.ObjectId(req.body.id),
      });

      let orderId = data.orderId;
      let orderCurrency = "INR";
      let orderNote = "Payment From Seller central.";
      let customerName = merchnatinfo.fName + " " + merchnatinfo.lName;
      let customerPhone = merchnatinfo.phoneNo;
      let customerEmail = merchnatinfo.email;

      let opUrl = apiEndpoint + "/api/v1/order/create";
      let returnUrl = httpUrl + "/shopperrds/cashfree";
      let notifyUrl = httpUrl + "/shopperrds/cashfreeNotify";
      let cf_request = {};

      cf_request["checkoutAction"] = apiEndpoint + "/checkout/post/submit";
      cf_request["appId"] = cashfreeAppId;
      cf_request["orderId"] = orderId;
      cf_request["orderAmount"] = orderAmount;
      cf_request["orderCurrency"] = orderCurrency;
      cf_request["orderNote"] = orderNote;
      cf_request["customerName"] = customerName;
      cf_request["customerPhone"] = customerPhone;
      cf_request["customerEmail"] = customerEmail;
      cf_request["notifyUrl"] = notifyUrl;
      cf_request["returnUrl"] = returnUrl;
      let postData = {
        appId: cashfreeAppId,
        customerName: customerName,
        customerPhone: customerPhone,
        customerEmail: customerEmail,
        notifyUrl: notifyUrl,
        orderId: orderId,
        orderAmount: orderAmount,
        orderCurrency: orderCurrency,
        orderNote: orderNote,
        returnUrl: returnUrl,
      };

      let signatureDatas = signatureData(postData, cashfreeSecrateKey);
      cf_request["signature"] = signatureDatas;
      res.send({ error: 0, response: cf_request });
    })
    .catch((e) => {
      res.send({ error: 1, response: "Something went wrong1." });
    });
  // }).catch((e) => {
  // 	res.send({'error' : 1 , 'response' : 'Something went wrong2.' })
  // })
};

exports.MerchantCashfree = async (req, res) => {
  let cashfreeAppId = process.env.CASHFREE_APP_ID;
  let cashfreeSecrateKey = process.env.CASHFREE_SECRATEKEY;
  let apiEndpoint = process.env.API_END_POINT;
  let httpUrl = process.env.HTTP_URL;
  let globalUrl = process.env.GLOBAL_PRODUCT_URL;
  let orderId = req.body.orderId;
  let orderAmount = req.body.orderAmount;
  let referenceId = req.body.referenceId;
  let txStatus = req.body.txStatus;
  let paymentMode = req.body.paymentMode;
  let txMsg = req.body.txMsg;
  let txTime = req.body.txTime;
  let signature = req.body.signature;
  let signatureData =
    req.body["orderId"] +
    req.body["orderAmount"] +
    req.body["referenceId"] +
    req.body["txStatus"] +
    req.body["paymentMode"] +
    req.body["txMsg"] +
    req.body["txTime"];
  let finalSignature = crypto
    .createHmac("sha256", cashfreeSecrateKey)
    .update(signatureData)
    .digest("base64");
  let responseData = {
    finalSignature: finalSignature,
    signatureData: signatureData,
  };
  if (txStatus == "SUCCESS") {
    if (signature == finalSignature) {
      await Transaction.findOne({ orderId: orderId }).then(
        async (transaction) => {
          await User.findOne(
            { _id: mongoose.Types.ObjectId(transaction.supplier_id) },
            { balance: 1 }
          ).then(async (merchantinfo) => {
            let balance = merchantinfo.balance;
            let updatedBalance = parseFloat(orderAmount) + parseFloat(balance);
            let balanceObj = {
              balance: updatedBalance,
            };
            User.updateOne(
              { _id: mongoose.Types.ObjectId(transaction.supplier_id) },
              { $set: balanceObj },
              { upsert: false }
            ).then(async (updata) => {
              let billHistory = new BillHistory({
                merchantId: transaction.supplier_id,
                pgOrderId: orderId,
                billType: 1,
                billAmt: orderAmount,
                beforeAmt: balance,
                afterAmt: updatedBalance,
                crDate: new Date(),
                modDate: new Date(),
                comment: "Recharge from Seller-central",
              });
              billHistory.save().then(async (billHistory) => {
                let obj = {
                  response: req.body,
                  status: 1,
                };
                Transaction.updateOne(
                  { orderId: orderId },
                  { $set: obj },
                  { upsert: false }
                ).then((data) => {
                  // res.send({'error' : 0 , 'response' : 'Payment Success.' })
                  res.redirect(globalUrl + "/merchant/payment-success");
                });
              });
            });
          });
        }
      );
    }
  } else {
    let obj = {
      response: req.body,
      status: 2,
    };
    Transaction.updateOne(
      { orderId: orderId },
      { $set: obj },
      { upsert: false }
    ).then((data) => {
      res.redirect(httpUrl + "/merchant/fail");
    });
  }
};

function signatureData(data, secretKey) {
  //for checkout
  var keys = Object.keys(data);
  keys.sort();
  let signatureData = "";
  keys.forEach((key) => {
    signatureData += key + data[key];
  });
  return crypto
    .createHmac("sha256", secretKey)
    .update(signatureData)
    .digest("base64");
}

exports.MerchantPaymentHistory = async (req, res) => {
  const page = parseInt(req.query.page);
  const limit = parseInt(req.query.limit);
  const startIndex = (page - 1) * limit;
  let totalCount = await BillHistory.countDocuments({
    merchantId: req.query.id,
  }).exec();
  await BillHistory.find(
    { merchantId: mongoose.Types.ObjectId(req.query.id) },
    {
      merchantId: 1,
      pgOrderId: 1,
      systemId: 1,
      billType: 1,
      billAmt: 1,
      beforeAmt: 1,
      afterAmt: 1,
      crDate: 1,
      comment: 1,
    }
  )
    .sort({ crDate: -1 })
    .limit(limit)
    .skip(startIndex)
    .exec()
    .then((results) => {
      return res
        .status(200)
        .send({ error: 0, items: results, totalCount: totalCount });
    })
    .catch((err) => {
      return res
        .status(200)
        .send({ error: 1, response: "Something went wrong." });
    });
};

exports.MerchantAddMargin = async (req, res) => {
  const { id, spm, maxP, minP, domain } = req.body;
  if (!domain || !id || !spm || !maxP) {
    return res.status(400).json({ message: "Invalid Input Params" });
  }
  let merchant = await User.findOne({ _id: mongoose.Types.ObjectId(id) });
  if (!merchant) {
    return res.status(400).json({ message: "Merchant Not found" });
  }
  try {
    switch (req.body.domain) {
      case "amazon":
        let amazonStoreData = merchant.amazonStoreData[0] ?? {};
        amazonStoreData.spm = spm;
        amazonStoreData.maxP = maxP;
        amazonStoreData.minP = minP;
        await User.updateOne(
          { _id: mongoose.Types.ObjectId(id) },
          { $set: { amazonStoreData: amazonStoreData } }
        );
        break;
      case "shopify":
        let storeData = merchant.storeData[0] ?? {};
        storeData.spm = spm;
        storeData.maxP = maxP;
        storeData.minP = minP ?? 20;

        let obj = {
          spm: spm,
          maxP: maxP,
          minP: minP ?? 20,
        };

        console.log(obj);
        console.log(storeData);
        //   return false;
        //   await User.updateOne({_id:mongoose.Types.ObjectId(id), "storeData.storeDomain": '87f0cf-5f.myshopify.com'},{$push:{priceConfiguration:obj}});
        await User.updateOne(
          {
            _id: mongoose.Types.ObjectId(id),
            "storeData.storeDomain": "87f0cf-5f.myshopify.com",
          },
          { $push: { storeData: obj } }
        );
        break;
      default:
    }
    return res.status(200).json({ message: "Detail updated Successfully." });
  } catch (e) {
    return res.status(500).json({ message: e.toString() });
  }
};

exports.StoreData = async (req, res) => {
  const storeData = req.user.storeData;
  const amazonStoreData = req.user.amazonStoreData;

  res.send({ shopify: storeData, amazon: amazonStoreData, user: req.user._id });
  // res.send({ shopify:req.user })
};

exports.StoreDataUpdate = async (req, res) => {
  const { _id, shopifyApiKey, shopifySecretKey, storeDomain } = req.body;

  if (req.body.type == "shopify") {
    User.findByIdAndUpdate(
      { _id: mongoose.Types.ObjectId(req.body.user) },
      { $pull: { storeData: { _id: _id } } },
      { new: true, runValidators: true }
    )
      .then((shopData) => {
        //amazonStoreData
        // User.updateOne({ storeDomain: storeDomain }, { isDelete: true, storeDomain: storeDomain + ' - deleted' }, { multi: true })
        //   .then(data => {
        //   Order.update({ storeDomain: storeDomain }, { isDelete: true }, { multi: true })
        //   .then(deletedData => {

        // code for deleting webhooks
        /*axios.get(`https://${shopifyApiKey}:${shopifySecretKey}@${storeDomain}/admin/api/2024-04/webhooks.json`)
                        .then(webhooks => {
                            // console.log('webhooks')
							if (webhooks.data) {
                                
                                const webhookData = webhooks.data.webhooks
                                webhookData.map((webhook, i)=> {
                                    setTimeout(()=> {
                                        // console.log(webhook)
										axios.delete(`https://${shopifyApiKey}:${shopifySecretKey}@${storeDomain}/admin/api/2024-04/webhooks/${webhook.id}.json`)
                                            .then(data => {
                                                
                                                res.send(shopData)
                                            })
                                            .catch(err => {
                                                
                                            })
                                    },500*i)
                                } )
                            }
                        })
                        .catch(err => {
                            console.log(err)
                            res.send(err)
                        })*/

        //   })

        //   })

        return res.status(200).json({ message: "Deleted successfully" });
      })
      .catch((err) => {
        res.send({ error: err });
      });
  }

  if (req.body.type == "amazon") {
    User.findByIdAndUpdate(
      { _id: mongoose.Types.ObjectId(req.body.user) },
      { $pull: { amazonStoreData: { _id: _id } } },
      { new: true, runValidators: true }
    )
      .then((shopData) => {
        //amazonStoreData
        // User.updateOne({ storeDomain: storeDomain }, { isDelete: true, storeDomain: storeDomain + ' - deleted' }, { multi: true })
        //   .then(data => {
        //   Order.update({ storeDomain: storeDomain }, { isDelete: true }, { multi: true })
        //   .then(deletedData => {
        // code for deleting webhooks
        /*axios.get(`https://${shopifyApiKey}:${shopifySecretKey}@${storeDomain}/admin/api/2020-07/webhooks.json`)
                        .then(webhooks => {
                            if (webhooks.data) {
                                
                                const webhookData = webhooks.data.webhooks
                                webhookData.map((webhook, i)=> {
                                    setTimeout(()=> {
                                        axios.delete(`https://${shopifyApiKey}:${shopifySecretKey}@${storeDomain}/admin/api/2020-07/webhooks/${webhook.id}.json`)
                                            .then(data => {
                                                
                                                res.send(shopData)
                                            })
                                            .catch(err => {
                                                
                                            })
                                    },500*i)
                                } )
                            }
                        })
                        .catch(err => {
                            
                            res.send(err)
                        })*/
        //   })
        //   })
      })
      .catch((err) => {
        res.send({ error: err });
      });
  }
};

exports.OrderDispute = async (req, res) => {
  // console.log(req)
  let disputeHead = req.body.disputeHead;
  let reason = req.body.reason;
  let orderId = req.body.orderId;
  let userId = req.body.userId;
  const imgUrls = [];

  const combinedImageUrlObject = [];
  const combinedImageUrlObject1 = [];

  if (req.body.fileLength > 0) {
    const uploadedFiles = req.files;

    // Iterate through each file
    const imageUrlArray = await Promise.all(
      Object.keys(uploadedFiles).map(async (key, index) => {
        const file = uploadedFiles[key];
        //   console.log('Name:', file.name);
        //   console.log('Size:', file.size);
        //   console.log('Mimetype:', file.mimetype);

        //   var fileContent = req.files.file1.data;
        var fileContent = file.data;

        const originalFileName = file.name;
        const fileExtension = path.extname(originalFileName);

        var d = new Date();
        const s3dir =
          "dispute/" +
          d.getFullYear().toString() +
          "/" +
          (d.getMonth() + 1).toString() +
          "/";
        var filename = "upload_" + makeid(6) + "_" + orderId + fileExtension;

        //   console.log(filename);
        //   return false;

        const imageUrl = await uploadExcel(fileContent, s3dir + filename).then(
          async () => {
            var url = process.env.S3_BUCKET_FILE_URL;
            // console.log(url+'/'+ s3dir + filename)

            // imgUrls.push(url+'/'+ s3dir + filename);

            return url + s3dir + filename;
          }
        );
        combinedImageUrlObject1.push(imageUrl);
        return { [index]: imageUrl };
        // return imageUrl;
      })
    );

    // combinedImageUrlObject = imageUrlArray.reduce((acc, obj) => Object.assign(acc, obj), {});
  }

  // console.log(combinedImageUrlObject);

  // return false;
  let order_dispute = {
    userId: userId,
    disputeHead: disputeHead,
    reason: reason,
    img_url: combinedImageUrlObject1,
    dispute_date: new Date(),
  };

  var obj1 = {
    updatedAt: new Date(),
    order_dispute: order_dispute,
    dStatus: "DP",
  };

  Order.updateOne(
    { _id: mongoose.Types.ObjectId(orderId) },
    { $set: obj1 },
    { upsert: false }
  )
    .then(async () => {
      // resolve({ 'error': 0, 'response': 'Order Successfully Updated.' })

      const user = await User.find(
        { _id: mongoose.Types.ObjectId(userId) },
        { fName: 1, lName: 1 }
      );
      // console.log(user)

      // order_dispute.push({'user': user})

      return res.status(200).send({
        error: 0,
        response: "Order Successfully Updated.",
        data: order_dispute,
        user: user,
      });
    })
    .catch((e) => {
      console.log(e);
      // resolve({ 'error': 0, 'response': 'Something Went Wrong.' })
      return res
        .status(200)
        .send({ error: 1, response: "Something Went Wrong." });
    });
};

exports.OrderDisputeMessage = async (req, res) => {
  // console.log(req)
  let disputeHead = req.body.disputeHead;
  let reason = req.body.reason;
  let orderId = req.body.orderId;
  let userId = req.body.userId;
  const imgUrls = [];

  let combinedImageUrlObject = [];
  let combinedImageUrlObject1 = [];

  if (req.body.fileLength > 0) {
    const uploadedFiles = req.files;

    // Iterate through each file
    const imageUrlArray = await Promise.all(
      Object.keys(uploadedFiles).map(async (key, index) => {
        const file = uploadedFiles[key];
        // console.log(index)
        if (key == "DisputeImgDb") {
          return;
        }
        //   console.log('Name:', file.name);
        //   console.log('Size:', file.size);
        //   console.log('Mimetype:', file.mimetype);

        //   var fileContent = req.files.file1.data;
        var fileContent = file.data;

        const originalFileName = file.name;
        const fileExtension = path.extname(originalFileName);

        var d = new Date();
        const s3dir =
          "dispute/" +
          d.getFullYear().toString() +
          "/" +
          (d.getMonth() + 1).toString() +
          "/";
        var filename = "upload_" + makeid(6) + "_" + orderId + fileExtension;

        //   console.log(filename);
        //   return false;

        const imageUrl = await uploadExcel(fileContent, s3dir + filename).then(
          async () => {
            var url = process.env.S3_BUCKET_FILE_URL;
            // console.log(url+'/'+ s3dir + filename)

            // imgUrls.push(url+'/'+ s3dir + filename);

            return url + "/" + s3dir + filename;
          }
        );
        // console.log({ [index]: imageUrl })
        combinedImageUrlObject1.push(imageUrl);
        return { [index]: imageUrl };
        // return imageUrl;
      })
    );
    // console.log(imageUrlArray)
    // combinedImageUrlObject = imageUrlArray.reduce((acc, obj) => Object.assign(acc, obj), {});
  }

  // console.log(combinedImageUrlObject1);

  // return false;
  let order_dispute = {
    userId: userId,
    // "disputeHead": disputeHead,
    reason: reason,
    img_url: combinedImageUrlObject1,
    dispute_date: new Date(),
  };

  var obj1 = {
    updatedAt: new Date(),
    dStatus: "DP",
  };
  var obj2 = {
    order_dispute: order_dispute,
  };
  // console.log(obj2)
  Order.updateOne(
    { _id: mongoose.Types.ObjectId(orderId) },
    { $push: obj2 },
    { upsert: false }
  )
    .then(async () => {
      // resolve({ 'error': 0, 'response': 'Order Successfully Updated.' })
      Order.updateOne(
        { _id: mongoose.Types.ObjectId(orderId) },
        { $set: obj1 },
        { upsert: false }
      );
      const user = await User.find(
        { _id: mongoose.Types.ObjectId(userId) },
        { fName: 1, lName: 1 }
      );
      // console.log(user)

      // order_dispute.push({'user': user})

      const disputeData = await Order.find(
        { _id: mongoose.Types.ObjectId(orderId) },
        { order_dispute: 1 }
      );

      return res.status(200).send({
        error: 0,
        response: "Order Successfully Updated.",
        data: disputeData,
        user: user,
      });
    })
    .catch((e) => {
      console.log(e);
      // resolve({ 'error': 0, 'response': 'Something Went Wrong.' })
      return res
        .status(200)
        .send({ error: 1, response: "Something Went Wrong." });
    });
};

exports.CreateShopifyApi = async (req, res) => {
  var count = 0;
  const userData = req.user;

  const body = req.body;
  const { storeDomain, shopifyApiKey, shopifySecretKey } = req.body;
  const isStore = userData.storeData.find(
    (store) =>
      store.storeDomain == storeDomain && store.shopifyApiKey == shopifyApiKey
  );
  if (isStore) {
    return res.json({ error: "Store data already exists !!!" });
  } else {
    /**
     * We need to delete all customers which might pre-exists for this domain
     *
     */

    // let allOldCustomers = await Customer.find({storeDomain: storeDomain})

    // let deleteAllOldCustomers = await Customer.update({ storeDomain: storeDomain }, { isDelete: true, storeDomain: storeDomain + ' - deleted' }, { multi: true });

    // getAllCustomers(shopifyApiKey,shopifySecretKey,storeDomain)
    //     .then(customers => {
    //         if (customers) {

    // for (let i = 0; i < customers.length; i++) {

    //     if (customers[i].note) {
    //         const noteFieldArray = customers[i].note.split('\n').join(':').toLowerCase().replace(/\s/g, "").split(':');
    //         if ( noteFieldArray.includes('mobilenumber') && noteFieldArray.includes('gstno.') && noteFieldArray.includes('company') ) {
    //             count++
    //              var mobileNumber = noteFieldArray[noteFieldArray.indexOf('mobilenumber') + 1].replace(/\s/g, "");
    //              var gstNumber = noteFieldArray[noteFieldArray.indexOf('gstno.') + 1].replace(/\s/g, ""); // to remove white space
    //              var companyName = noteFieldArray[noteFieldArray.indexOf('company') + 1].replace(/\s/g, "");
    //             const customer = new Customer({
    //                 merchantId: userData._id,
    //                 storeDomain: storeDomain,
    //                 customerId: customers[i].id,
    //                 email: customers[i].email,
    //                 firstName: customers[i].first_name,
    //                 lastName: customers[i].last_name,
    //                 note: customers[i].note,
    //                 phone: customers[i].phone,
    //                 companyName: companyName,
    //                 gstNumber: gstNumber,
    //                 mobileNumber: mobileNumber
    //             })
    //             customer.save()
    //             .then(data => {
    //                 if (data.storeDomain == "shopperr2.myshopify.com") {
    //                     if (data.firstName && data.mobileNumber) {
    //                         bcryptjs.genSalt(10)
    //                         .then(salt => {
    //                             bcryptjs.hash(data.firstName, salt)
    //                              .then(encryptedPassword => {

    //                                  const user = new MerchantUser({
    //                                     firstName: data.firstName,
    //                                     lastName: data.lastName,
    //                                     email: data.email,
    //                                     password: encryptedPassword,
    //                                     phoneNo: data.mobileNumber,
    //                                     joiningDate: new Date,
    //                                     store: data.storeDomain,
    //                                     customerId: mongoose.Types.ObjectId(data._id)
    //                                 })
    //                                 user.save()
    //                                 .then()
    //                                 .catch(err => {

    //                                 })
    //                              })
    //                          })
    //                     } else {

    //                     }
    //                 }
    //             })
    //             .catch()
    //         } else {
    //             const customer = new Customer({
    //                 merchantId: userData._id,
    //                 storeDomain: storeDomain,
    //                 customerId: customers[i].id,
    //                 email: customers[i].email,
    //                 firstName: customers[i].first_name,
    //                 lastName: customers[i].last_name,
    //                 note: customers[i].note,
    //                 phone: customers[i].phone,
    //             })
    //             customer.save()
    //             .then()
    //             .catch()
    //         }

    //     } else {
    //         const customer = new Customer({
    //             merchantId: userData._id,
    //             storeDomain: storeDomain,
    //             customerId: customers[i].id,
    //             email: customers[i].email,
    //             firstName: customers[i].first_name,
    //             lastName: customers[i].last_name,
    //             note: customers[i].note,
    //             phone: customers[i].phone,
    //         })
    //         customer.save()
    //         .then()
    //         .catch()
    //     }

    // }

    User.findById(req.user._id)
      .then((user) => {
        user.storeData = [{ storeDomain, shopifyApiKey, shopifySecretKey }];
        user
          .save()
          .then((user) => {
            registerWebhooks(shopifyApiKey, shopifySecretKey, storeDomain)
              .then((response) => {
                res.send(user).status(200);
              })
              .catch((err) => {});
          })
          .catch((err) => {
            res.send(err);
          });
      })
      .catch((err) => {
        return res.send(err);
      });
    // } else {

    //     return res.json({ error: "Invalid API key or secret key" }).status(401)
    // }
    // })
    // .catch(err => {

    //     return res.json({err, error: "Invalid API key or secret key" }).status(401)
    // })
  }
};

exports.TicketInfo = async (req, res) => {
  let orderId = req.body.orderId;
  let userId = req.body.userId;

  //dStatus : 'DP'

  const mongoose = require("mongoose");

  const orderData = await Order.find(
    {
      _id: mongoose.Types.ObjectId(orderId),
      merchantId: userId,
      dStatus: ["DP", "DD"],
    },
    { order_dispute: 1, dStatus: 1 }
  )
    .then(async (dData) => {
      let results = [];
      let disputeHead = "";

      for (let item of dData) {
        // console.log(item.dStatus);
        // return false;
        disputeHead = item.order_dispute[0].disputeHead;
        dStatus = item.dStatus;
        let disputes = await Promise.all(
          item.order_dispute.map(async (data) => {
            // console.log(data)
            let username = "";
            if (data.type == "admin") {
              const user = await Adminuser.find(
                { _id: mongoose.Types.ObjectId(data.userId) },
                { name: 1 }
              );
              username = user[0].name;
            } else {
              const user = await User.find(
                { _id: mongoose.Types.ObjectId(data.userId) },
                { fName: 1, lName: 1 }
              );
              username = user[0].fName;
            }

            // if(item.order_dispute[0].disputeHead == 'Ticket Close'){return false;}

            return {
              user: username,
              disputeHead: data.disputeHead,
              reason: data.reason,
              dispute_date: data.dispute_date,
              img_url: data.img_url,
            };
          })
        );

        results.push(disputes.reverse());
      }

      // console.log(results);

      return res.status(200).send({
        error: 0,
        response: "Dispute Information.",
        data: results,
        disputeHead: disputeHead,
        dStatus: dStatus,
      });
    })
    .catch((e) => {
      console.log(e);
      return res.status(200).send({
        error: 1,
        response: "Something Went Wrong.",
      });
    });

  // console.log(orderData)
};

exports.TicketClose = async (req, res) => {
  let orderId = req.body.orderId;
  let userId = req.body.userId;

  let order_dispute = {
    userId: userId,
    reason: "Ticket Close",
    dispute_date: new Date(),
    type: "user",
  };

  var obj1 = {
    updatedAt: new Date(),
    dStatus: "DD",
  };
  var obj2 = {
    order_dispute: order_dispute,
  };

  Order.updateOne(
    { _id: mongoose.Types.ObjectId(orderId) },
    { $push: obj2 },
    { upsert: false }
  )
    .then(async () => {
      Order.updateOne(
        { _id: mongoose.Types.ObjectId(orderId) },
        { $set: obj1 },
        { upsert: false }
      )
        .then(async () => {
          return res.status(200).send({
            error: 0,
            response: "Ticket closed Successfully",
          });
        })
        .catch((e) => {
          console.log(e);
          return res.status(200).send({
            error: 1,
            response: "Data not updated",
          });
        });
    })
    .catch((e) => {
      console.log(e);
      return res.status(200).send({
        error: 1,
        response: "Something Went Wrong.",
      });
    });
};

exports.RazorPayVerification = async (req, res) => {
  const secret = process.env.RAZORPAY_SECRET;
  // console.log('verification============================')
  // console.log(req.body)
  // console.log(req.body.event)
  // console.log(req.body.payload.payment.entity.status)
  // console.log(req.body.payload.payment.entity.card)
  // console.log(req.body.payload.payment.entity)
  // console.log(req.body.payload.payment.entity.order_id)

  const crypto = require("crypto");

  const shasum = crypto.createHmac("sha256", secret);
  shasum.update(JSON.stringify(req.body));
  const digest = shasum.digest("hex");

  console.log(digest, req.headers["x-razorpay-signature"]);

  if (digest === req.headers["x-razorpay-signature"]) {
    console.log("request is legit");
    // console.log('process it')
    require("fs").writeFileSync(
      "payment1.json",
      JSON.stringify(req.body, null, 4)
    );

    const obj2 = {
      // amount_paid: req.body.payload.payment.entity.amount,
      orderId: req.body.payload.payment.entity.order_id,
      response: req.body.payload.payment.entity,
      paymentStatus: req.body.payload.payment.entity.status,
    };

    Transaction.updateOne(
      { orderId: req.body.payload.payment.entity.order_id },
      { $set: obj2 },
      { upsert: false }
    ).then(() => {
      // console.log("second update")
    });
  } else {
    // console.log('pass it')
  }
  res.json({ status: "ok" });
};
exports.MerchantRazorPay = async (req, res) => {
  const payment_capture = 1;
  // const amount = 1
  const currency = "INR";

  // console.log(req);
  // return false;
  const options = {
    amount: req.body.amount * 100,
    currency,
    receipt: shortid.generate(),
    payment_capture,
  };
  console.log(req.body.id);

  try {
    const response = await razorpay.orders.create(options);
    // console.log('razorpay============================')
    // console.log(response)

    //Transaction

    const transaction = new Transaction({
      supplier_id: req.body.id,
      orderId: response.id,
      pmethod: "RazorPay",
      amount_paid: req.body.amount,
    });

    transaction
      .save()
      .then((order) => {
        // res.sendStatus(200)
      })
      .catch((err) => {
        // res.sendStatus(200)
      });

    res.json({
      id: response.id,
      currency: response.currency,
      amount: response.amount,
    });
  } catch (error) {
    console.log(error);
  }
};

exports.RazorpaySuccess = async (req, res) => {
  try {
    await Transaction.findOne({ orderId: req.body.razorpay_order_id }).then(
      async (transactionData) => {
        const orderAmount = transactionData.amount_paid;

        await User.findOne(
          { _id: mongoose.Types.ObjectId(transactionData.supplier_id) },
          { balance: 1 }
        ).then(async (merchantinfo) => {
          let balance = merchantinfo.balance;
          let updatedBalance = parseFloat(orderAmount) + parseFloat(balance);
          let balanceObj = {
            balance: updatedBalance,
          };
          User.updateOne(
            { _id: mongoose.Types.ObjectId(transactionData.supplier_id) },
            { $set: balanceObj },
            { upsert: false }
          ).then(async (updata) => {
            let billHistory = new BillHistory({
              merchantId: transactionData.supplier_id,
              pgOrderId: req.body.razorpay_order_id,
              billType: 1,
              billAmt: orderAmount,
              beforeAmt: balance,
              afterAmt: updatedBalance,
              crDate: new Date(),
              modDate: new Date(),
              comment: "Recharge from Seller-central",
            });
            billHistory.save().then(async (billHistory) => {
              let obj = {
                paymentStatus: "Success",
              };
              Transaction.updateOne(
                { orderId: req.body.razorpay_order_id },
                { $set: obj },
                { upsert: false }
              ).then((data) => {
                // res.send({'error' : 0 , 'response' : 'Payment Success.' })
                res.redirect(
                  process.env.GLOBAL_PRODUCT_URL + "/merchant/payment-success"
                );
              });
            });
          });
        });
      }
    );

    const razorpay_payment_id = req.body.razorpay_payment_id;
    const razorpay_order_id = req.body.razorpay_order_id;
    const razorpay_signature = req.body.razorpay_signature;
    res.redirect(process.env.GLOBAL_PRODUCT_URL + "/merchant/payment-success");
    // res.json({
    // 	razorpay_payment_id: razorpay_payment_id,
    // 	razorpay_order_id: razorpay_order_id,
    // 	razorpay_signature: razorpay_signature
    // })
  } catch (error) {
    console.log(error);
  }
};

exports.FulfillmentLeftOrders = async (req, res) => {
  //6650320ec2269f9c3937e8ad
  //req.params.merchantId

  try {
    return res.status(200).json(
      await Order.countDocuments({
        merchantId: req.params.merchantId,
        oStatus: ["OB", "OS"],
        pStatus: ["PP", "PD"],
        sStatus: { $ne: "SS" },
        createdAt: {
          $gte: new Date(req.params.start + "T00:00:00.000Z"),
          $lt: new Date(req.params.end + "T23:59:59Z"),
        },
      })
    );
  } catch (err) {
    let result = { error: 1, response: err.toString() };
    return res.status(500).json(result);
  }
};

exports.ShippedOrders = async (req, res) => {
  //6650320ec2269f9c3937e8ad
  //req.params.merchantId

  try {
    return res.status(200).json(
      await Order.countDocuments({
        merchantId: req.params.merchantId,
        sStatus: ["SS"],
        createdAt: {
          $gte: new Date(req.params.start + "T00:00:00.000Z"),
          $lt: new Date(req.params.end + "T23:59:59Z"),
        },
      })
    );
  } catch (err) {
    let result = { error: 1, response: err.toString() };
    return res.status(500).json(result);
  }
};

exports.CancelledOrders = async (req, res) => {
  //6650320ec2269f9c3937e8ad
  //req.params.merchantId

  try {
    return res.status(200).json(
      await Order.countDocuments({
        merchantId: req.params.merchantId,
        oStatus: ["OC"],
        createdAt: {
          $gte: new Date(req.params.start + "T00:00:00.000Z"),
          $lt: new Date(req.params.end + "T23:59:59Z"),
        },
      })
    );
  } catch (err) {
    let result = { error: 1, response: err.toString() };
    return res.status(500).json(result);
  }
};

function getProductData(cond) {
  return new Promise((resolve, reject) => {
    try {
      let pData = Product.findOne(cond);
      resolve(pData);
    } catch (err) {
      console.log("error");
    }
  });
}

/************** */
const chars =
  "100XAXPMNO2IDDEWLZBTEVHV6OG1RDT6XQJX3MVF4AMADQ9TUVHGJFDBODLLLPTNNUUW";
const charsLength = chars.length;

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function generateRandomString(length) {
  let randStr = "";
  for (let i = 0; i < length; i++) {
    const idx = getRandomInt(0, charsLength - 1);
    randStr += chars.charAt(idx);
  }
  return randStr;
}

/************** */

// exports.customershow = async(req,res) => {
//     const id = req.params.id
//     Customer.findById(id)
//         .then(customer => {
//             res.send(customer)
//             console.log(customer)
//         })
//         .catch(err => {
//             res.send({ message: "Can't get customer data", error: err })
//         })
//     }
// exports.customergst = async(req,res) => {
//     const id = req.params.id
//     const {companyName, gstNumber, mobileNumber} = req.body
//     Customer.findOne({_id: "64f850d4de11fc697f1e5159", gstNumber: "28NQGBU7384K5y4"})
//     // const s =
//         .then(customer => {
//             if (customer && customer.isGstVerified) {
//                 Customer.findByIdAndUpdate(id, { companyName,mobileNumber }, {new: true, runValidators: true})
//                 .then(newData => {
//                     res.send({"newData": newData, message: "Your data has been edited successfully and GST No. is already verified" })
//                 })
//                 .catch(err => {
//                     res.send(err)
//                 })
//             } else {
//                 getGstData(gstNumber)
//                 .then(gstInfo => {
//                     // console.log("Inside Then Gst data", gstInfo)
//                     const gstData = gstInfo.data
//                     Customer.findByIdAndUpdate(id, { companyName,gstNumber,mobileNumber,gstData, isGstVerified: true }, {new: true, runValidators: true})
//                     .then(newData => {
//                         res.send({"newData": newData, message: "You have successfully verified you GST" })
//                     })
//                     .catch(err => {
//                         res.send(err)
//                     })
//                 })
//                 .catch(err => {
//                     res.send(err.msg)
//                 })
//             }
//         })
//         .catch(err => {
//             res.send({ "message": "Unable to find" })
//         })

// }

exports.PaymentOfOrder = async (req, res) => {
  try {
    const { orderIds } = req.query; // Should be an array
    if (!orderIds || orderIds.length === 0) {
      return res.status(400).json({ message: "No orders selected." });
    }
    const orders = await orders.find({ _id: { $in: orderIds } });
    const totalAmount = orders.reduce(
      (sum, order) => sum + order.consumerPrice,
      0
    );
    res.json({ totalAmount, orders });
  } catch (err) {
    console.error("Error in payment API:", err);
    res.status(500).json({ err });
  }
};

exports.updateBalance = async (req, res) => {
  try {
    const { userId, newBalance, orderData } = req.body;
    if (!userId || newBalance === undefined || !orderData || orderData.length === 0) {
      return res.status(400).json({ error: 1, message: "Invalid input data" });
    }

    let currentBalance = (
      await User.findOne({ _id: mongoose.Types.ObjectId(userId) })
    ).balance;

    currentBalance = parseFloat(currentBalance.toFixed()); // Ensure 2 decimal precision

    for (const order of orderData) {
      // console.log(order)
      const amtArray = order.amount;
      for (const amt1 of amtArray) {
        const amount = parseFloat(amt1.amt.toFixed()); 
        currentBalance -= amount;
        currentBalance = parseFloat(currentBalance.toFixed());  
        await User.findByIdAndUpdate(
          userId,
          { balance: currentBalance },
          { new: true }
        );
        const billarrData = new BillHistory({
          merchantId: userId,
          pgOrderId: order.orderSerial,
          systemId:order.systemId,
          billType: 1,
          billAmt: amount,
          beforeAmt: parseFloat((currentBalance + amount).toFixed()),
          afterAmt: currentBalance,
          comment: `Paid for order ${order.orderSerial}`,
          crDate: new Date(),
          modDate: new Date(),
        });

        await billarrData.save();
      }
      const currentOrder = await Order.findOne({ orderSerial: order.orderSerial });

      if (currentOrder) {
        const totalOrderAmount = parseFloat(
          currentOrder.orderDetails.reduce(
            (sum, detail) => sum + detail.finalPrice,
            0
          ).toFixed() 
        );

        // Update payment status if the balance covers the order amount
        if (newBalance >= totalOrderAmount) {
          currentOrder.pStatus = "PD"; // Payment Done
          currentOrder.modDate = new Date();
          await currentOrder.save();
          // console.log(`Order ${order.orderSerial} marked as Paid.`);
        } else {
          // console.log(`Order ${order.orderSerial} not marked as Paid. Insufficient balance.`);
        }
      } else {
        // console.log(`Order not found for Serial: ${order.orderSerial}`);
      }
    }

    res.status(200).json({
      error: 0,
      message: "Balance and orders updated successfully",
      response: [],
    });
  } catch (err) {
    // console.error(err);
    res.status(500).json({ error: 1, message: "Internal server error" });
  }
};
