const mongoose = require("mongoose");
const request = require('request-promise');
const CsvUpload = mongoose.model("CsvUpload");
const MarketplaceSubscribes = mongoose.model("MarketplaceSubscribes");
const User = mongoose.model("User");
const Products = mongoose.model("Products");
const Order = mongoose.model("Orders");
const WInward = mongoose.model("WInward");
const OrderReturn = mongoose.model("OrderReturn");
const OrderReturnAts = mongoose.model("OrderReturnAts");
const { constantValues, mongooseConstantValues, channelCodes } = require("../../apps/common/systemConstents")
const { updateShopperrPriceAlgo, getMsrp } = require("../../apps/middlewares/priceAlgo")
const moment = require('moment');
const xlsx = require('xlsx');

var fs = require('fs');
const AWS = require('aws-sdk');
const csv = require('csvtojson');
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',
});
 
exports.SubscribeProductCron = async (req,res) => {
    var limit = 1;
    var csvRequest = await CsvUpload.findOne({ "status": 0, "type": 3 });
    
    if (csvRequest) {
        
        var obj = {
            status: 1
        }
        
        try {
            // const data = await CsvUpload.updateOne({ "_id": csvRequest._id }, { $set: obj }, { upsert: false });
        } catch (err) {

        }
        var options = {
            uri: csvRequest.url,
            encoding: null
        };
        
        var merchantId = csvRequest.mId;
        let merCond = { '_id': merchantId }
        let merchantData = await getmerchantData(merCond);
        let shopifyKey = (merchantData && merchantData.storeData && merchantData.storeData.length != 0) ? merchantData.storeData[0].shopifyApiKey ? 1 : 0 : 0
        //let amazonKey = (merchantData.amazonStoreData.length != 0 ) ? merchantData.amazonStoreData[0].MWSAuthToken ? 1 : 0 : 0
        
        request(options, async function (error, response, body) {
            
            if (error || response.statusCode !== 200) {
                return false;
            } else {
                let csvData = await csv().fromString(body.toString());
                csvData = JSON.stringify(csvData);
                csvData = JSON.parse(csvData);
                
                let upStatus = await merchantSubscribeList(csvData, merchantId, shopifyKey, csvRequest);
                
                return true;
            }
        });
    } else {

        return true;
    }
};

exports.AmazonSubscribeProductCron = async (req,res) => {
    var type = 4;
    var limit = 1;

    var csvRequest = await CsvUpload.find({ $and: [{"status": 0} , {"type" : type}]}).limit(parseInt(limit)).sort({'_id' :-1 }); 
    if(csvRequest.length > 0){ 
        var obj = {  
            status: 1 
        }  
        try { 
            const data = await CsvUpload.updateOne({"_id" : csvRequest['0']._id },{ $set: obj } , {upsert: false}); 
        } catch (err) { 
            
        } 
        var options = {
            uri: csvRequest[0].url,
            encoding: null
        };
        var merchantId = csvRequest[0].mId;
        request(options, async function(error, response, body) {
            if (error || response.statusCode !== 200) { 
                
                
            } else { 
                let csvData = await csv().fromString(body.toString());
                csvData = JSON.stringify(csvData);
                csvData = JSON.parse(csvData);
                let upStatus = await amazonMerchantSubscribeList(MarketplaceSubscribes,csvData , merchantId);
                
            }
        });
    }else{
        
    }
};

exports.bulkUploadOrdersCron = async (req,res) => {
    var limit = 1;
	var csvRequest = await CsvUpload.find({ $and: [{ "status": 0 }, { "type": 13 }] }).limit(parseInt(limit)).sort({ '_id': -1 });
   // console.log(csvRequest); return false;
   let error2 = []; 
	
	if (csvRequest.length > 0) {
		if (csvRequest[0].mId) {
			let merchantID = csvRequest[0].mId
            console.log("inside csvRequest.length > 0");
            
			var obj = {
				status: 2
			}
			// try {
			// 	const data = await CsvUpload.updateOne({ "_id": csvRequest['0']._id }, { $set: obj }, { upsert: false });
			// } catch (err) {
			// 	console.log(err);
			// }
			let merchantData = await User.findOne({ '_id': mongoose.Types.ObjectId(merchantID) })
			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())
					//csv_data = JSON.stringify(csv_data)
                    //console.log(csv_data);return false;
					//csv_data = JSON.parse(csv_data);
                    //console.log(csv_data)
					let orderData = {};
					let orderDataList = {};
                    
                    let i = 0;
                    
					csv_data.forEach(async (item) => {
						i++;
                        //console.log(item);return false;
                        const randomString = generateRandomString(15);
                        let orders_serial='100'+randomString+'00'+i;
                        let newSku = item.sku.replace(/\D/g, "");
                        //console.log(i);
                        
                        //error_messages.push('Product not found')
                        // let resultProducts = await Products.find();
                    //     const resultProducts = await Products.findOne({'code' :newSku}).exec();
                    //    // console.log(resultProducts);
                    //     if(!resultProducts){
                    //        // console.log('Product not found');
                    //         error2.push('Product not found')
                    //     } else if(resultProducts.quantity<=0){
                    //         let singleData = {
                    //             'error': 'out of stock',
                    //             'sku': newSku
                    //          };
            
                    //          error2.push(singleData);
                    //         //error_messages.push('out of stock =>'+newSku)
                    //     } else {
                            orderDataList[item.orderId] = orderDataList[item.orderId] ? orderDataList[item.orderId] : {};
						
                            if (item.multipleProduct == 0) {
                                // orderDataList[item.orderId] = item;
                                orderDataList[item.orderId] = {
                                    ...item,
                                    order_serial: orders_serial
                                };
                            } 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);
                                }
                            }
                        //}
                        //console.log(error2+'00000000000000000000');
                       
					});

                    
					
					if (Object.values(orderDataList).length > 0) {
						let uploadRes = (await Promise.all(Object.values(orderDataList).map((order) => {
							return (new Promise(async (resolve, reject) => {
                                
                                let productCond = { $or: [{ code: order.sku }, { 'varientArray.sku': order.sku }] }
                                let productData = await getProductData(productCond);
                                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 = order.recipientName ? order.recipientName.split(' ').slice(0, -1).join(' ') : '';
                                let last_name = order.recipientName ? order.recipientName.split(' ').slice(1).join(' ') : '';
                                // console.log(first_name);

                                // return false;
								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": order.recipientName ? order.recipientName.split(' ').slice(0, -1).join(' ') : '',
									"last_name": order.recipientName ? order.recipientName.split(' ').slice(1).join(' ') : '',
									"name": order.recipientName
								}
								let customer = {
									"email": "",
									"first_name": order.recipientName ? order.recipientName.split(' ').slice(0, -1).join(' ') : '',
									"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": order.recipientName ? order.recipientName.split(' ').slice(0, -1).join(' ') : '',
										"last_name": order.recipientName ? order.recipientName.split(' ').slice(1).join(' ') : '',
										"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
								}
								
								// const resellerPrice=csv_data.map(item=>item.consumerPrice)
								// const finalResellerPrice = resellerPrice.toString()
								const orders = new Order({
									merchantId: merchantID,
									storeDomain: storeDomain,
									orderId: order.orderId,
									// orderSerial: order.orderId,
									price: totalPrice,
									currency: 'INR',
									created_on: new Date(),
									products: products,
									orderNumber: order.orderId,
									marketPlace:order.marketPlace,
									customer: customer,
									fulfillmentStatus: null,
									pStatus: 'unpaid',
									updated_on: new Date(),
									paymentDetails: '',
									billingAddress: billingAddress,
									shippingAddress: shippingAddress,
									resellerPrice:order.consumerPrice,
									productOrderDate:order.orderDate,
                                    orderSerial:order.order_serial
								})
                                // console.log(order.recipientName ? order.recipientName.split(' ').slice(0, -1).join(' ') : '');
                                // return false;

                                orders.save().then((data) => {
									resolve({ 'error': 0, 'response': 'Order Successfully Saved.' })
								}).catch((e) => {
									console.log(e);
									resolve({ 'error': 0, 'response': 'Something Went Wrong.' })
								})
							}));
						})).then((data) => data).catch((err) => err))
						var obj = {
							status: 1
						}
						CsvUpload.updateOne({ "_id": csvRequest['0']._id }, { $set: obj }, { upsert: false }).then(() => {

						})
					}
				}
			})
		} 
	}
    // console.log(error2); return false;
};

exports.bulkUploadProducts = async (req,res) => {
    let limit = 1;
    let csvRequest = await CsvUpload.find({ $and: [{ "status": 0 }, { "type": 14 }] }).limit(parseInt(limit)).sort({ '_id': -1 }); 
    if (csvRequest.length > 0) {
    	let obj = {
            status: 2
        }
        // try {
        //     const data = await CsvUpload.updateOne({ "_id": csvRequest['0']._id }, { $set: obj }, { upsert: false });
        // } catch (err) {
            
        // } 
        let options = {
            uri: csvRequest[0].url,
            encoding: null
        };
        request(options, async function (error, response, body) {
            if (error || response.statusCode !== 200) {
                
                
            } else { 
                let csv_data = await csv().fromString(body.toString())
                let uploadRes = (await Promise.all(csv_data.map((item)=>{ 
                    return new Promise(async (resolve, reject) => {
                        try {
                            // Assuming item.orderId is already a valid ObjectId string
                            let orderId = mongoose.Types.ObjectId(item.orderId); 
                    
                            // Find the order with the given orderId
                            let orderData = await Order.findOne({ '_id': orderId }, { shippingAddress: 1, customer: 1 });
                    
                            if (orderData) {
                                // Extract necessary data
                                let shippingAddress = orderData.shippingAddress;
                                let customer = orderData.customer;
                                let default_address = customer.default_address;
                    
                                // Update customer's default address
                                default_address.address1 = item.OrderCustomerAddress1;
                                default_address.phone = item.OrderCustomerPhone;
                                default_address.city = item.OrderCustomerCity;
                                default_address.zip = item.OrderCustomerZip;
                                default_address.province = item.OrderCustomerProvince;
                                default_address.country = item.OrderCustomerCountry;
                                default_address.address2 = item.OrderCustomerAddress2;
                                default_address.country_code = item.OrderCustomerCountryCode;
                                default_address.first_name = item.OrderCustomerFirstName;
                                default_address.last_name = item.OrderCustomerLastName;
                                default_address.name = item.OrderCustomerName;
                    
                                // Update shipping address
                                shippingAddress.address1 = item.OrderShippingAddress1;
                                shippingAddress.address2 = item.OrderShippingAddress2;
                                shippingAddress.city = item.OrderShippingCity;
                                shippingAddress.company = item.OrderShippingCompany;
                                shippingAddress.country = item.OrderShippingCountry;
                                shippingAddress.country_code = item.OrderShippingCountryCode;
                                shippingAddress.first_name = item.OrderShippingFirstName;
                                shippingAddress.last_name = item.OrderShippingLastName;
                                shippingAddress.name = item.OrderShippingName;
                                shippingAddress.phone = item.OrderShippingPhone;
                                shippingAddress.province = item.OrderShippingProvince;
                                shippingAddress.zip = item.OrderShippingZip;
                    
                                // Update customer details
                                customer.email = item.OrderCustomerEmail;
                                customer.first_name = item.OrderCustomerFirstName;
                                customer.currency = item.Currency;
                                customer.phone = item.OrderCustomerPhone;
                                customer.default_address = default_address;
                    
                                // Prepare update object
                                let updateObj = {
                                    shippingAddress: shippingAddress,
                                    customer: customer
                                };
                    
                                // Update the order in the database
                                let updateResponse = await Order.updateOne({ '_id': orderId }, { $set: updateObj }, { upsert: false });
                    
                                resolve({ 'error': 0, 'response': 'Order Updated Successfully', 'updateRes': updateResponse });
                            } else {
                                resolve({ 'error': 1, 'response': 'Order data not found.' });
                            }
                        } catch (error) {
                            reject(error); // Forward any error to the caller
                        }
                    });
                    
                })).then((data)=>data).catch((err)=>err)) 
                let obj = {
                    status: 1
                } 
                CsvUpload.updateOne({ "_id": csvRequest['0']._id }, { $set: obj }, { upsert: false }).then((uploadRes) => {
                    
                })
            } 
        })
    	
    }
};

exports.InwardCron = async (req,res) => {

    var limit = 1;
    var csvRequest = await CsvUpload.find({ $and: [{ "status": 0 }, { "type": 101 }] }).limit(parseInt(limit)).sort({ '_id': -1 });

    if (csvRequest.length > 0) {
        let spID = csvRequest[0].spId;

        let options = {
            uri: csvRequest[0].url,
            encoding: null
        };

        request(options, async function (error, response, body) {
            if (error || response.statusCode !== 200) {
                console.error("Failed to fetch CSV:", error);
            } else {
                return new Promise(async (resolve, reject) => {
                    try {
                        const workbook = xlsx.read(body, { type: 'buffer' });

                        const sheet1 = workbook.Sheets[workbook.SheetNames[0]];
                        const dataFromSheet1 = xlsx.utils.sheet_to_json(sheet1);

                        const sheet2 = workbook.Sheets[workbook.SheetNames[1]];
                        const dataFromSheet2 = xlsx.utils.sheet_to_json(sheet2);

                        // console.log("Data from Sheet 1:", dataFromSheet1);
                        // console.log("Data from Sheet 2:", dataFromSheet2);

                        // console.log(dataFromSheet2.length);

                        // return false;

                        const alreadySubscribedId1 = dataFromSheet2.reduce(async (result, item) => {
                            
                            // if (!result.includes(item['CFF ORDER NO.'])) {
                            //     result.push(item['CFF ORDER NO.']);

                                // console.log(item['CFF ORDER NO.'])

                                const winwardData = new WInward({
                                    spID:spID,
                                    inv_number: item['invoice number'],
                                    cff_orderno: item['CFF ORDER NO.'],
                                    i_orderno: item['ISTORE ORDER NO.'],
                                    s_orderno: item['SHOPPERR ORDER NO.'],
                                    sku: 'STK01'+item.SKU,
                                    code:item.SKU,
                                    description: item.DESCRIPTION,
                                    receiveQty: item.QTY,
                                    unitPrice: item['UNIT PRICE'],
                                    totalPrice:item['TOTAL PRICE'],
                                    rmbPrice: item['TOTAL PRICE(RMB)'],
                                    invoiceDate:item['装袋时间'],
                                    order_status: 0,
                                    created_date: new Date(),
                                    
                                })
    
                                // console.log(winwardData)
    
                                // return false;

                                const checkWinward = await WInward.findOne({ s_orderno: item['SHOPPERR ORDER NO.']})
                                if(checkWinward){
                                    let updateObj = {
                                        spID:spID,
                                        cff_orderno: item['CFF ORDER NO.'],
                                        i_orderno: item['ISTORE ORDER NO.'],
                                        inv_number: item['invoice number'],
                                        sku: 'STK01'+item.SKU,
                                        code:item.SKU,
                                        description: item.DESCRIPTION,
                                        receiveQty: item.QTY,
                                        unitPrice: item['UNIT PRICE'],
                                        totalPrice:item['TOTAL PRICE'],
                                        rmbPrice: item['TOTAL PRICE(RMB)'],
                                        invoiceDate:item['装袋时间'],
                                        order_status: 0,
                                    };

                                    await WInward.updateOne({ "_id": mongoose.Types.ObjectId(checkWinward._id) }, { $set: updateObj }, { upsert: false });
                                    let obj = {
                                        status: 1
                                    } 
                                    CsvUpload.updateOne({ "_id": csvRequest['0']._id }, { $set: obj }, { upsert: false }).then((uploadRes) => {
                            
                                    });
                                    // console.log('update')
                                }else{
                                    winwardData.save().then((data) => {
                                        resolve({ 'error': 0, 'response': 'Inward Successfully Saved.' })
                                        // res.send({ 'error': 0, 'response': 'Inward Successfully Saved.' });
        
                                        let obj = {
                                            status: 1
                                        } 
                                        CsvUpload.updateOne({ "_id": csvRequest['0']._id }, { $set: obj }, { upsert: false }).then((uploadRes) => {
                                
                                        });
                                    }).catch((e) => {
                                        console.log(e);
                                        resolve({ 'error': 1, 'response': 'Something Went Wrong.' })
                                        // res.send({ 'error': 1, 'response': 'Something Went Wrong.' })
                                    })
                                }
    
                                // winwardData.save().then((data) => {
                                //     resolve({ 'error': 0, 'response': 'Inward Successfully Saved.' })
                                //     // res.send({ 'error': 0, 'response': 'Inward Successfully Saved.' });
    
                                //     let obj = {
                                //         status: 1
                                //     } 
                                //     CsvUpload.updateOne({ "_id": csvRequest['0']._id }, { $set: obj }, { upsert: false }).then((uploadRes) => {
                            
                                //     });
                                // }).catch((e) => {
                                //     console.log(e);
                                //     resolve({ 'error': 1, 'response': 'Something Went Wrong.' })
                                //     // res.send({ 'error': 1, 'response': 'Something Went Wrong.' })
                                // })
                            // }
                            
                            return result;
                        }, []);

                    } catch (e) {
                        console.error("Error processing XLS file:", e);
                    }
                });
            }
        });
    }

};
function excelSerialToDate(serial) {
  // Excel's "zero" is January 1, 1900 (but it incorrectly treats 1900 as a leap year)
  const utcDays = Math.floor(serial - 1); // Subtract 1 because Excel starts counting from 1
  const baseDate = new Date(Date.UTC(1900, 0, 1)); // January 1, 1900 (UTC)
  baseDate.setUTCDate(baseDate.getUTCDate() + utcDays);
  return baseDate;
}
exports.ReturnCron = async (req,res) => {

    var limit = 1;
    var csvRequest = await CsvUpload.find({ $and: [{ "status": 0 }, { "type": 102 }] }).limit(parseInt(limit)).sort({ '_id': -1 });

    if (csvRequest.length > 0) {
        let spID = csvRequest[0].spId;

        let options = {
            uri: csvRequest[0].url,
            encoding: null
        };

        request(options, async function (error, response, body) {
            if (error || response.statusCode !== 200) {
                console.error("Failed to fetch CSV:", error);
            } else {
                return new Promise(async (resolve, reject) => {
                    try {
                        const workbook = xlsx.read(body, { type: 'buffer' });

                        const sheet1 = workbook.Sheets[workbook.SheetNames[0]];
                        const dataFromSheet1 = xlsx.utils.sheet_to_json(sheet1);

                        const sheet2 = workbook.Sheets[workbook.SheetNames[1]];
                        const dataFromSheet2 = xlsx.utils.sheet_to_json(sheet2);

                        //console.log("Data from Sheet 1:", dataFromSheet1);
                        // console.log("Data from Sheet 2:", dataFromSheet2);

                        // console.log(dataFromSheet2.length);

                        //return false;

                        const alreadySubscribedId1 = dataFromSheet1.reduce(async (result, item) => {
                           console.log(item['Ordering Order ID'])
                           
                            // if (!result.includes(item['CFF ORDER NO.'])) {
                            //     result.push(item['CFF ORDER NO.']);
								const checkWinwardData = await WInward.findOne({ mkpOrderId: item['Ordering Order ID'] })
                                //console.log(checkWinwardData['code'])
                                //return false;
                                
								const isoDateStr = excelSerialToDate(item['Date']-1);//item['Date']+"T00:00:00.000+00:00";
								//console.log(isoDateStr);return false;
                                const winwardData = new OrderReturn({
                                    awb: item['Tracking ID'],
                                    marketplace_order_id: item['Ordering Order ID'],
                                    sku: checkWinwardData['code'],
                                    return_reason: 'ATS',
                                    quantity: checkWinwardData['qty'],
                                    type:'Returns',
                                    account_name: checkWinwardData['account_name'],
                                    order_date: checkWinwardData['orderDate'],
                                    order_return_date: moment(isoDateStr).toDate(),
                                    scan_status:0
                                    
                                })
                                
                                const winwardDataAts = new OrderReturnAts({
                                    awb: item['Tracking ID'],
                                    marketplace_order_id: item['Ordering Order ID'],
                                    sku: checkWinwardData['code'],
                                    return_reason: 'ATS',
                                    quantity: checkWinwardData['qty'],
                                    type:'Returns',
                                    account_name: checkWinwardData['account_name'],
                                    order_date: checkWinwardData['orderDate'],
                                    order_return_date: moment(isoDateStr).toDate(),
                                    scan_status:0
                                    
                                })
    
                                // console.log(winwardData)
    
                                // return false;

                                const checkWinward = await OrderReturn.findOne({ marketplace_order_id: item['Ordering Order ID'],awb:item['Tracking ID']})
                                if(checkWinward){
                                    
                                    // console.log('update')
                                }else{
                                    winwardData.save().then((data) => {
                                        resolve({ 'error': 0, 'response': 'Inward Successfully Saved.' })
                                        // res.send({ 'error': 0, 'response': 'Inward Successfully Saved.' });
        
                                        let obj = {
                                            status: 1
                                        } 
                                        CsvUpload.updateOne({ "_id": csvRequest['0']._id }, { $set: obj }, { upsert: false }).then((uploadRes) => {
                                
                                        });
                                    }).catch((e) => {
                                        console.log(e);
                                        resolve({ 'error': 1, 'response': 'Something Went Wrong.' })
                                        // res.send({ 'error': 1, 'response': 'Something Went Wrong.' })
                                    })
                                }
                                const checkWinwardats = await OrderReturnAts.findOne({ marketplace_order_id: item['Ordering Order ID'],awb:item['Tracking ID']})
                                if(checkWinwardats){
                                    
                                    // console.log('update')
                                }else{
									winwardDataAts.save().then((data) => {
										resolve({ 'error': 0, 'response': 'Inward Successfully Saved.' })
										// res.send({ 'error': 0, 'response': 'Inward Successfully Saved.' });
		
										let obj = {
											status: 1
										} 
										CsvUpload.updateOne({ "_id": csvRequest['0']._id }, { $set: obj }, { upsert: false }).then((uploadRes) => {
								
										});
									}).catch((e) => {
										console.log(e);
										resolve({ 'error': 1, 'response': 'Something Went Wrong.' })
										// res.send({ 'error': 1, 'response': 'Something Went Wrong.' })
									})
								}
    
                                // winwardData.save().then((data) => {
                                //     resolve({ 'error': 0, 'response': 'Inward Successfully Saved.' })
                                //     // res.send({ 'error': 0, 'response': 'Inward Successfully Saved.' });
    
                                //     let obj = {
                                //         status: 1
                                //     } 
                                //     CsvUpload.updateOne({ "_id": csvRequest['0']._id }, { $set: obj }, { upsert: false }).then((uploadRes) => {
                            
                                //     });
                                // }).catch((e) => {
                                //     console.log(e);
                                //     resolve({ 'error': 1, 'response': 'Something Went Wrong.' })
                                //     // res.send({ 'error': 1, 'response': 'Something Went Wrong.' })
                                // })
                            // }
                            
                            return result;
                        }, []);

                    } catch (e) {
                        console.error("Error processing XLS file:", e);
                    }
                });
            }
        });
    }

};

async function merchantSubscribeList(skus, merchantId, shopifyKey, csvRequest) {
    return new Promise(async function (resolve, reject) {
        if (skus) {
            var skuArray = skus;
            var itemsProcessed = [];
            let successResult = [];
            let errorCount = 0;
            
            for (const item of skuArray) {
                let result = await addMerchantSubscribedProduct(item, merchantId, shopifyKey);
                console.log("addmerch");
                if (!result.status) {
                    errorCount++;
                }
                successResult.push('' + item.Sku + ' - ' + result.msg)
            }
            successResult.push('-----------------------------------')
            successResult.push('Total SKUs processed = ', skuArray.length)
            successResult.push('Total SKUs error = ', errorCount)
            let resultOutput = await successResult.map((ress) => {
                let result = ress;
                fs.appendFile('./' + csvRequest['_id'] + '.txt', result + '\n', (err) => {
                    if (err) {

                    }
                })
                return result
            });
            var d = new Date();
            const s3dir = "upload_product_res/" + d.getFullYear().toString() + "/" + (d.getMonth() + 1).toString() + "/";
            var filename = makeid(6) + '_' + csvRequest['_id'] + '.txt';
            var fullPath = s3dir + filename;
            await fs.readFile('./' + csvRequest['_id'] + '.txt', function (err, data) {
                if (err) { }
                uploadExcel(data, s3dir + filename).then(async () => {
                    var url = process.env.S3_BUCKET_FILE_URL;
                    var obj = {
                        status: 1,
                        resUrl: url + '/' + fullPath
                    }
                    try {
                        const data = await CsvUpload.updateOne({ "_id": csvRequest._id }, { $set: obj }, { upsert: false });

                    } catch (err) {

                    }
                    // fs.unlink('./' + csvRequest._id + '.txt', (err) => {
                    //     if (err) throw err;
                    // });
                });
            });
            resolve(itemsProcessed);
        }
    })
}

async function amazonMerchantSubscribeList(module,items,merchantId){
    if(!items || (items && !items.length))
      return false;
    let skus = items.map((item)=>{
      return item.Sku;
    });
    const products = await Products.find({'code' :{ $in: skus }}).exec();
    const productIds = products.map((produt)=>{
      return produt._id;
    });
    const alreadySubscribed = await module.find({$and:[{pId:{$in:productIds}},{mId:merchantId}]});
    const alreadySubscribedId = alreadySubscribed.map((item)=>{ 
      return item.pId;
    });
    const subscribeProducts = [];
    products.forEach((product)=>{
      const item = items.find((ele)=>ele.Sku == product.code);
      if(alreadySubscribedId.includes(product._id) !== -1 && item){
        subscribeProducts.push({ 
          mId     : merchantId, 
          pId     : product._id,
          margin  : item.Margin,
          dos     :  new Date(),
          dom     :  new Date(),
          am_status : 0,
          [mongooseConstantValues.IS_AMAZON_PRODUCT_UPLOADED]:item[mongooseConstantValues.IS_AMAZON_PRODUCT_UPLOADED]
        });
      }
    });
    const update = await module.insertMany(subscribeProducts);
    return update;
}

function getmerchantData(cond) {
    return new Promise((resolve, reject) => {
        try {
            let merData = User.findOne(cond);
            resolve(merData);
        } catch (err) {
            reject(err);
        }
    })
}

function addMerchantSubscribedProduct(sku, merchantId, shopifyKey) {
    
    let channel = "ds";
    if (channelCodes.includes(sku.Channel)) {
        channel = sku.Channel;
    }
    
    return new Promise(async function (resolve, reject) {
        var isProduct = await getProductDataBySku(sku.Sku);
        if (isProduct.productData && isProduct.productData.length > 0) {
            var product = isProduct.productData[0];
            let getProductCond = {
                pId: product._id,
                mId: merchantId
            };
            
            var shopperrSubProduct = await getShopperSubscribeProductData(getProductCond, 1);
            
            if (shopperrSubProduct && shopperrSubProduct.length == 0 && shopifyKey == 1) {
                if (!shopperrSubProduct) {
                    const shopperrSubscribeProducts = await new MarketplaceSubscribes({
                        mId: merchantId,
                        pId: product._id,
                        dos: new Date(),
                        dom: new Date(),
                        sku: sku.Sku,
                        margin: sku.Margin,
                        [mongooseConstantValues.SUBSCRIBE_AS_DRAFT]: 0,
                        channel
                    });
                    await shopperrSubscribeProducts.save().then((shopperrSubscribe) => {
                        resolve({ msg: `Created Subscribe Products - main product = ${isProduct.isMainProduct}`, status: shopperrSubscribe });
                    });
                }
                resolve({ msg: `Created Subscribe Products - main product = ${isProduct.isMainProduct}`, status: saveStatus });
            } else {
                
                if (!shopperrSubProduct) {
                    const shopperrSubscribeProducts = await new MarketplaceSubscribes({
                        mId: merchantId,
                        pId: product._id,
                        dos: new Date(),
                        dom: new Date(),
                        sku: sku.Sku,
                        margin: sku.Margin,
                        [mongooseConstantValues.SUBSCRIBE_AS_DRAFT]: 0,
                        channel
                    });
                    await shopperrSubscribeProducts.save();
                    
                }
                let upObj = {
                    suv_status: 0,
                    margin: sku.Margin
                }
                let updateSubscribeProductCondition = { pId: product._id, mId: merchantId };
                const data = await updateSubscribeProducts(updateSubscribeProductCondition, upObj);
                resolve({ msg: `Update Subscribe Products - main product = ${isProduct.isMainProduct}`, status: true });
            }
        } else {
            resolve({ msg: 'Merchant Product / Sub product Not found.', status: false });
        }
    })
}
function updateSubscribeProducts(cond, data) {
    return new Promise((resolve, reject) => {
        let productData = MarketplaceSubscribes.updateOne(cond, { $set: data }, { multi: true });
        resolve(productData);
    });
}
function getProductDataBySku(cond) {
    return new Promise(async (resolve, reject) => {
        try {
            let isMainProduct = true;
            let productData = await Products.find({ 'code': cond });
            /**
             * If product is not found by code then check if that product is variant by checking it with skus
             * Checking if it works based on SKU
             */
            if (productData && productData.length == 0) {
                productData = await Products.find({ 'skus': cond });
                if (productData && productData.length > 0) {
                    isMainProduct = false;
                }

            }
            resolve({ productData: productData, isMainProduct: isMainProduct });
        } catch (err) {
            return true;
        }
    })
}
// function getSubscribeProductData(cond, limit) {
//     return new Promise((resolve, reject) => {
//         try {
//             let productData = SubscribeProducts.find(cond).limit(limit);
//             resolve(productData);
//         } catch (err) {
//             return true;
//         }
//     })
// }
function getShopperSubscribeProductData(cond, limit) {
    return new Promise((resolve, reject) => {
        try {
            let productData = MarketplaceSubscribes.findOne(cond);
            resolve(productData);
        } catch (err) {
            return true;
        }
    })
}
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;
}
function getProductData(cond) {
	return new Promise((resolve, reject) => {
		try {
			let pData = Products.findOne(cond);
            resolve(pData);
		} catch (err) {
            console.log("error");
		}
	})
}
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{
			
		}
    });
};

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