const mongoose = require("mongoose");
const Product = mongoose.model("Products");
const Order = mongoose.model("Orders");
const WInward = mongoose.model("WInward");
const User = mongoose.model("User");
// const Transaction = mongoose.model("transaction");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcryptjs");
const moment = require('moment-timezone');
const { webAPiValidation } = require("../handlers/webValidation");
const request = require('request-promise');
var fs = require('fs');
const AWS = require('aws-sdk');
const { result } = require('lodash');
const _ = require("lodash");
ID = 'AKIAZQ3DPSAOW34EMAWP';    
SECRET = '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';
// The name of the bucket that you have created
const BUCKET_NAME = 'test-bucket';
const s3 = new AWS.S3({
    accessKeyId: ID,
    secretAccessKey: SECRET
});
const solr = require("solr-client");
const SolrIndexingLog = mongoose.model("SolrIndexingLog");
const { messageBuilder  } = require("../apps/common/CommonFunctions")
const { SolrGlobalAdd  } = require("../apps/common/SolrGlobalAdd")
const { SolrGlobalAddB2B  } = require("../apps/common/SolrGlobalAddB2B")
var axios = require('axios');
exports.webService = async (req,res) => {
	
	let str =[];
	if(req.body.php == 1){
	   str = JSON.stringify(req.body.paramjson);
	} else {
		 str = req.body.paramjson;
	}
  const requestData = JSON.parse(str);
  if(requestData.HeaderRequest.userkey == process.env.API_KEY && requestData.HeaderRequest.usertoken == process.env.API_TOKEN){
    const getMethod = requestData.HeaderRequest.methodName;
    var getSupplier = requestData.HeaderRequest.userid;
    var suppId = '';
    if(getSupplier == 'Fulfillmen'){
		suppId = '67405479bf97f7739fb486a0';
	}
	else if(getSupplier == 'Footful'){
		suppId = '5ff1fb6cb5a4c4a27a0580dd';
	}
    //var suppId = getSupplierDataID._id;
    if(getMethod == process.env.PRODUCT_UPLOAD){
        this.PRODUCT_UPLOAD(requestData.addProductRequestInfo,suppId,res);
    }
    if(getMethod == process.env.PRODUCT_UPDATE_PRODUCT_INFO){
        this.PRODUCT_UPDATE_PRODUCT_INFO(requestData.productRequestInfo,res);
    }
    if(getMethod == process.env.PRODUCT_UPDATE_PRICE){
        this.PRODUCT_UPDATE_PRICE(requestData.productRequestInfo,res);
    }
    if(getMethod == process.env.ORDER_INF_TO_ISTORE){
        this.ORDER_INF_TO_ISTORE(requestData.data,res);
    }
    if(getMethod == process.env.ORDER_UPDATE_STATUS){
        this.ORDER_UPDATE_STATUS(requestData.data.orders,res);
    }
    if(getMethod == process.env.ORDER_CANCEL_UPDATE_STATUS){
        this.ORDER_CANCEL_UPDATE_STATUS(requestData.data.orders,res);
    }
  }
  
};

exports.ORDER_CANCEL_UPDATE_STATUS = async (data,res) => {
  try {
		//console.log(data);return false;
		var arrayItemsErr = [];
		data.forEach(async function (shipping) {
			try {
				
				var obj = {
					oStatus:'OC',
					remark:'Cancelled By China',
					cancelDate:moment(shipping.created_at).tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss"),
					updatedAt:moment(shipping.created_at).tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss"),
				}
				/*const fetchOrder = await Order.updateOne(
				  { _id: mongoose.Types.ObjectId(shipping.OrderId)  },
				  { $set: obj }
				);*/
				const fetchOrder = await Order.updateOne(
				  { legacyOrderid: shipping.OrderId },
				  { $set: obj }
				);
				var objwin = {
					order_status: 12,
					//cancel_date:moment(shipping.created_at).tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss"),
					cancelled_by_china:Date(),
				}
				var ordSerData = await Order.findOne({legacyOrderid:shipping.OrderId},{}).exec();
				
				const fetchOrderwin = await WInward.updateOne(
				  { orderSerial: ordSerData.orderSerial },
				  { $set: objwin }
				);
				
				var responseData = {};
				if(fetchOrder){
					responseData.ask=1;
					responseData.msg="add success.";
					responseData.data = {
						"1000":data,
						"1001":""
					};
				} else {
					responseData.ask=0;
					responseData.msg="All add failed.failed list below.please check and retry.";
					responseData.data = {
						"1000":"",
						"1001":arrayItemsErr
					};
				}
				res.send(responseData);
			} catch (error) {
				return res.status(200).send({'ask' : 0 , 'msg' : error})
			}	
		});
		
		//console.log(arrayItems);return false;
	} catch (error) {
		
	}
};

exports.ORDER_UPDATE_STATUS = async (data,res) => {
  try {
		//console.log(data);return false;
		var arrayItemsErr = [];
		data.forEach(async function (shipping) {
			try {
				var order_shipping_data = {
					sm_title : shipping.CarrierName,
					os_tracking_no : shipping.TrackingNO,
					os_date_deliver : moment(shipping.created_at).tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss"),
					os_date_add : moment(shipping.created_at).tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss"),
					os_status : 'SS',
					os_apply_status : 'AN',
					os_apply_modi_date : moment(shipping.created_at).tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss"),
					carrier_name : shipping.CarrierName,
					shipping_method : shipping.ShipMethod,
				  };
				var obj = {
					
					order_shipping: order_shipping_data,
					shipDate:moment(shipping.created_at).tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss"),
					updatedAt:moment(shipping.created_at).tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss"),
				}
				/*const fetchOrder = await Order.updateOne(
				  { _id: mongoose.Types.ObjectId(shipping.OrderId)  },
				  { $set: obj }
				);*/
				const fetchOrder = await Order.updateOne(
				  { legacyOrderid: shipping.OrderId },
				  { $set: obj }
				);
				var objwin = {
					order_status: 13,
					trackingId: shipping.TrackingNO,
					courierName:shipping.CarrierName,
					shipDate:moment(shipping.created_at).tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss"),
				}
				var ordSerData = await Order.findOne({legacyOrderid:shipping.OrderId},{}).exec();
				
				const fetchOrderwin = await WInward.updateOne(
				  { orderSerial: ordSerData.orderSerial },
				  { $set: objwin }
				);
				
				var responseData = {};
				if(fetchOrder){
					responseData.ask=1;
					responseData.msg="add success.";
					responseData.data = {
						"1000":data,
						"1001":""
					};
				} else {
					responseData.ask=0;
					responseData.msg="All add failed.failed list below.please check and retry.";
					responseData.data = {
						"1000":"",
						"1001":arrayItemsErr
					};
				}
				res.send(responseData);
			} catch (error) {
				return res.status(200).send({'ask' : 0 , 'msg' : error})
			}	
		});
		
		//console.log(arrayItems);return false;
	} catch (error) {
		
	}
};

exports.ORDER_INF_TO_ISTORE = async (data,res) => {
    //console.log(data);return false;
    try {
        const From_DatePaid = data.condition.From_DatePaid; 
        const To_DatePaid = data.condition.To_DatePaid; 
        const OrderPaymentStatus = data.condition.OrderPaymentStatus; 
        const OrderStatus = data.condition.OrderStatus; 
        const OrderDisputeStatus = data.condition.OrderDisputeStatus; 
        const OrderShipStatus = data.condition.OrderShipStatus; 
        const page = parseInt(data.page);
        const limit = parseInt(data.pageSize);
        const startIndex = (page - 1) * limit
        const endIndex = page * limit
        const results = {}
        const response = {};
        let  query ={ pStatus: OrderPaymentStatus, oStatus:{$in:OrderStatus}, dStatus: {$in:OrderDisputeStatus}, sStatus:{$in:OrderShipStatus} };
        if(From_DatePaid && To_DatePaid){
            query.createdAt = {
                $gte: new Date(From_DatePaid).toISOString(),
                $lt: new Date(To_DatePaid).toISOString()
            }
        }
        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
            }
        }
        try {
            const resultsData = await Order.find(query,{})
            .sort({ _id: -1 })
            .limit(limit)
            .skip(startIndex)
            .exec();
            var mappedData = [];
            var responseData = {};
            var data = [];
            var responseData = {};
            responseData.ask=1;
            responseData.msg="Success";
            if (!_.isEmpty(resultsData)) {
				
				let orders = resultsData.map(async (item) => {
				var userData = await User.findOne({_id:mongoose.Types.ObjectId(item.merchantId)},{}).exec();	
				let productArray=[];
				
				let allProduct = item.orderDetails;
				for(const key of Object.keys(item.orderDetails)){
					let itemRow = item.orderDetails[key];
					var proUnitPrice = await Product.findOne({code:itemRow.sku.replace(/\D/g, '')},{}).exec();
					productArray.push({
						ProductId:itemRow._id,
						ProductName:itemRow.title,
						OrderItemId:itemRow.orderItemId,
						ProductQuantity:itemRow.quantity,
						ProductUnitPrice:proUnitPrice.sp,
						IstoreProductId:itemRow.sku.replace(/\D/g, ''),
					})
				};
				return {
                    OrderId : item._id,
                    OrderCode : item.orderSerial,
					OrderStatus : item.oStatus, 
					OrderPaymentStatus : item.pStatus,
					OrderRefundReason : null,
					OrderShipStatus : item.sStatus,
					OrderReturnStatus : 'RN',
					OrderDisputeStatus : item.dStatus,
					DateCreate : moment(item.createdAt).tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss"),
					DateFinished : null,
					CustomerName : userData.fName+' '+userData.lName,
					CustomerPhoneNum : userData.phoneNo.toString(),
					CustomerEmail : userData.email,
					DeliveryName : item.recipientName,
					DeliveryCompany : null,
					DeliveryStreetAddress1 : item.shippingAddress1,
					DeliveryStreetAddress2 : item.shippingAddress2,
					DeliveryStreetAddress3 : item.shippingAddress3,
					DeliveryCity : item.shippingCity,
					DeliveryPostcode : item.shippingPostalCode,
					DeliveryState : item.shippingState,
					DeliveryPhoneNum : item.shippingPhoneNumber,
					AmazonOrderId : item.mkpOrderId,
					TotalProdutValue : item.consumerPrice,
					ShipFee : '',
					PaidTime : moment(item.paidDate).tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss"),
					TransactionFee : '',
					ShipMethod : 'none',
					SenderCompanyName : userData.businessName,
					SenderGSTcode : userData.gstNumber,
					SalesAmount : item.consumerPrice,
					PlatForm : "3",
					CustomerCountryName : null,
					DeliveryCountryName : item.shippingCountry,
					CustomerZoneName : null,
					TotalValue : item.consumerPrice,
					productInf : productArray,
                };
            });
   
            responseData.data = await Promise.all(orders);
           
            //res.send(responseData);return false;
			   
            }
            
            res.send(responseData)
        } catch (e) {
            res.status(500).json({ message: e.message })
        }  
    } catch (error) {
		
	}
    
};
exports.PRODUCT_UPLOAD = async (data,suppId,res) => {
  try {
    //console.log(data);return false;
    var i=0;var p=0;
    data.forEach(async function (products) {
      var categoryTags = [];
      var titlePD = products.pd_name;
      var dataHandle = titlePD.trim();
      var handle = dataHandle.toLocaleLowerCase().replace(/[^\w-]+/g, "-");
      let factoryPrice = products.prices.STK_Shopperr_price;
      let shippingObj = {
          method: 'freeShipping',
      };
      let stock = {
          "cn_qty": products.stock.cn_quantity,
          "in_qty": 0,
          "blk_qty": 0,
      };
      let prices = {
          "pd_base_price": products.prices.product_base_price,
          "ppm_price_2": products.prices.ppm_price_2,
          "STK_price": products.prices.STK_Shopperr_price
      };
      if (products.tags) {
          var ptags = products.tags;
          categoryTags.push(ptags);
      }
      if (categoryTags.length != 0) {
          var final_tag = await getTagId(categoryTags.toString());
          var tgs = categoryTags.toString();
      } 
      const sp = chinaPriceAlgoSFC(factoryPrice, products.product_weight);
      let mainImage = [];
      let productImage = products.productImages;
      if (productImage && productImage.length > 0) {
          productImage.forEach(function (pimage) {
              var imgData = { 'url': pimage.path, 'handle': handle };
              var imgpath = '';
              var varient_id = '';
              upload_image(imgData, function (result) {
                  imgpath = result;
              });
              var imgres1 = { 'position': (parseInt(pimage.z_status) + 1), 'src': imgpath, 'varient_id': '' }
              mainImage.push(imgres1);
          });
      }
      let mainVariant = [];
      let productVariant = products.variants;
      if (productVariant && productVariant.length > 0) {
          productVariant.forEach(function (pvariants) {
			  const spv = chinaPriceAlgoSFC(pvariants.price, products.product_weight);
              var variantsData = { 
					'vid': pvariants.id,
					'product_id': pvariants.product_id, 
					'price': pvariants.price, 
					'spv': spv.price, 
					'spvmrp': spv.mrp, 
					'sku': pvariants.sku, 
					'specId':pvariants.specId,
					'weight':products.product_weight,
					'compare_at_price': pvariants.compare_at_price, 
					'option1': pvariants.option1
			  };
              
              //var imgres1 = { 'vd': imgpath, 'varient_id': '' }
              mainVariant.push(variantsData);
          });
      }
      
		let mainVariantInfos = [];
		let productInfos = products.productSkuInfos;

		if (productInfos && productInfos.length > 0) {
			productInfos.forEach(function (pskuinfos) {
				// Create a NEW specs array for EACH product
				let mainVariantSpecs = [];

				let productInfosSpecs = pskuinfos.specs;
				if (productInfosSpecs && productInfosSpecs.length > 0) {
					productInfosSpecs.forEach(function (pskuinfosspecs) {
						let variantsSkuInfosSpecsData = { 
							'attributeId': pskuinfosspecs.attributeId,
							'attributeName': pskuinfosspecs.attributeName, 
							'value': pskuinfosspecs.value, 
							'skuImage': pskuinfosspecs.skuImage
						};
						mainVariantSpecs.push(variantsSkuInfosSpecsData);
					});
				}

				let variantsSkuInfosData = { 
					'skuId': pskuinfos.skuId,
					'amountOnSale': pskuinfos.amountOnSale, 
					'price': pskuinfos.price, 
					'specs': mainVariantSpecs  // Unique array per product
				};
				mainVariantInfos.push(variantsSkuInfosData);
			});
		}
      let mainOptions = [];
      let productOptions = products.options;
      if (productOptions && productOptions.length > 0) {
          productOptions.forEach(function (poptions) {
              var optionsData = { 
					'name': poptions.name,
					'values': poptions.values 
				};
              
              //var imgres1 = { 'vd': imgpath, 'varient_id': '' }
              mainOptions.push(optionsData);
          });
      }
      
      //console.log(mainVariant,mainOptions);return false;
      let skus = [];
      skus.push(products.productID);
      
      var sp_id=suppId;
      const data = new Product({
          supplier_id: mongoose.Types.ObjectId(sp_id),
          sid: mongoose.Types.ObjectId(sp_id),
          name: products.pd_name,
          handle: handle,
          price: factoryPrice.toFixed(2),
          mrp: sp.mrp,
          sp: sp.price,
          cogs: sp.cogs,
          quantity: products.stock.cn_quantity,
          weight: products.product_weight,
          description: products.pd_description,
          code: products.productID,
          skus: skus,
          imgUrl: mainImage,
          uploaded_on: Date(),
          size: products.product_height,
          shippingCharge: shippingObj,
          tags: final_tag,
          category: '',
          cat_id: products.category_id,
          pd_model: products.product_model,
          pd_brand: products.brand,
          pd_visible: products.product_visible,
          pd_pack_unit: products.product_pack_unit,
          length: products.product_length,
          width: products.product_width,
          height: products.product_height,
          g_id: products.g_id,
          hsn: products.hsn, 
          gst: products.gst,
          pd_sum: products.product_sum,
          pd_manage_status: products.product_manage_status,
          pd_status: products.product_status,
          pd_location: products.product_location,
          is_display: products.is_display,
          is_delete: products.is_delete,
          stock: stock,
          prices: prices,
          tgs: tgs,
          varients: mainVariant,
          options: mainOptions,
          vd: mainVariant,
          productSkuInfos: mainVariantInfos
      });
        const newProduct = data.save();
		if(newProduct){
			i++;
			const dr = await newProduct;
			let query = {'code': dr.code};
			let productSolr = await Product.find(query)
			  .select("imgUrl name _id tags tgs supplier_id handle price prices mrp sp quantity description code hsn weight uploaded_on cogs subtitle bcd igst swcOnBcd seaPrice invoicedesc cat pd_status pd_manage_status is_display options varientArray length width productMargin height bno channel spData category")
			//console.log("Supp Getting=>"+suppId)
			if(suppId == '67405479bf97f7739fb486a0'){
				//console.log("Supp inside=>"+suppId)
				await SolrGlobalAddB2B(productSolr,'add');
				//console.log("Supp inside after method=>"+suppId)
			}
			else if(suppId == '5ff1fb6cb5a4c4a27a0580dd'){
				//console.log("Supp inside=>"+suppId)
				await SolrGlobalAdd(productSolr,'add');
				//console.log("Supp inside after method=>"+suppId)
			}
			  
			
			
		} else {
			p++;
		}
    });
	} catch (error) {
		
	}
	let result = {'ask' : 0 ,'msg':{'success':i,'error':p},'data' : [] };
	res.send(result)
};

exports.PRODUCT_UPDATE_PRODUCT_INFO = async (data,res) => {
	
    try {
	  let i = 0, p = 0;

	  for (const products of data) {
		const updateStock = {
		  quantity: products.cn_quantity,
		  'stock.cn_qty': products.cn_quantity  // Only update cn_qty inside stock
		};

		const fetchProduct = await Product.findOneAndUpdate(
		  { code: products.productID },
		  { $set: updateStock }
		);

		if (fetchProduct) {
		  i++;
		} else {
		  p++;
		}
	  }

	  let result = { ask: 0, msg: { success: i, error: p }, data: [] };
	  res.send(result);

	} catch (error) {
	  console.error('Error updating stock:', error);
	  res.status(500).send({ ask: 0, msg: 'Internal server error', error: error.message });
	}

    
  };

exports.PRODUCT_UPDATE_PRICE = async (data,res) => {
    var i=0;var p=0;
    try {
		data.forEach(async function (products) {
            let factoryPrice = products.STK_Shopperr_price;
            
            const sp = chinaPriceAlgoSFC(factoryPrice, products.product_weight);
            
            let prices = {
                "pd_base_price": products.product_base_price,
                "ppm_price_2": products.ppm_price_2,
                "STK_price": products.STK_Shopperr_price
            };
            
            const updatePrice = {
                price: factoryPrice.toFixed(2),
                mrp: sp.mrp,
                sp: sp.price,
                cogs: sp.cogs,
                prices: prices,
            };
            //console.log(updatePrice);
            var msg = {};
            const fetchProduct = await Product.findOneAndUpdate(
            { code: products.productID  },
            { $set: updatePrice }
            );
            
            if(fetchProduct){
				i++;
			} else {
				p++;
			}
            
            
             
        });    
    } catch (error) {
		console.log(error);
	}
	let result = {'ask' : 0 ,'msg':{'success':i,'error':p},'data' : [] };
	res.send(result)
};

function chinaPriceAlgoSFC (factoryPrice, product_weight) {
	var STK_Shopperr_price 	  = factoryPrice;
	var product_weight 		    = (product_weight/1000)*1.81;
	var ppPrice 			        = STK_Shopperr_price*12*1.22;
	var getDuty 				      = (ppPrice*38/100);
	var getLandedCost 			  = getDuty+ppPrice;
	var getFrieghtCost 		    = (795*product_weight*1.18);
	var chaCost 				      = 0;   
	var processingCost 		    = 12; 
	var lastMileCost 			    = 85;
	var getTotalCOCGS 			  = getLandedCost+getFrieghtCost+chaCost+processingCost+lastMileCost;
	var profitAdd15Percent 	  = (getTotalCOCGS*15/100)+getTotalCOCGS;
	var gstImpact 				    = ((profitAdd15Percent-getTotalCOCGS)*18/100);
	var gst_price 				    = profitAdd15Percent+gstImpact;
	
	var FourPercentAddInPrice = (gst_price*4)/100;
	var finalShopperrPrice 	  = gst_price+FourPercentAddInPrice;
	var product_msrp 			    = finalShopperrPrice*2.5;
	
	var GSTPrice              = finalShopperrPrice.toFixed(2);
  var productPricemrp       = product_msrp.toFixed(2);
  var totalCOCGS            = getTotalCOCGS.toFixed(2);
  var data                  = { 'price': GSTPrice, 'cogs': totalCOCGS, 'mrp': productPricemrp }
  return data;
}
function getProductDataBySku(cond) {
  return new Promise(async (resolve, reject) => {
      try {
          let isMainProduct = true;
          let productData = await Product.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 Product.find({ 'skus': cond });
              if (productData && productData.length > 0) {
                  isMainProduct = false;
              }

          }
          resolve({ productData: productData, isMainProduct: isMainProduct });
      } catch (err) {
          return true;
      }
  })
}
function upload_image(handle, callback) {
  var d = new Date();//
  const imageDir = "images/" + d.getFullYear().toString() + "/" + (d.getMonth() + 1).toString() + "/" + handle.handle + "/";
  var s3dir = `${imageDir}`;
  var filename = Date.now().toString() + makeid(6) + '.png';
  var options = {
      uri: handle.url,
      encoding: null
  };
  request(options, async function (error, response, body) {
      if (error || response.statusCode !== 200) {


      } else {
          var status = uploadFile(body, s3dir + filename);
      }
  });
  callback(s3dir + filename);
}
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 uploadFile(file, key) {
  const params = {
      Bucket: process.env.S3_FILE_BUCKET,
      Key: key, // File name you want to save as in S3
      Body: file,
      ContentType: 'image/jpeg'
  };
  // Uploading files to the bucket
  s3.upload(params, async function (err, data) {
      if (err) {
          throw err;
      }
  });
};
function parseDateString(dateString) {
    // Split the date string into date and time parts
    const [datePart, timePart] = dateString.split(' ');
   
    // Split the date part into year, month, and day
    const [year, month, day] = datePart.split('-');
   
    // Split the time part into hour, minute, and second
    const [hour, minute, second] = timePart.split(':');
 
    // Create a Date object with parsed values
    return new Date(year, month - 1, day, hour, minute, second).toISOString();
}
