const mongoose = require("mongoose");
const User = mongoose.model("User");
const Adminuser = mongoose.model("Adminuser");
// const Transaction = mongoose.model("transaction");
const Orders = mongoose.model("Orders");
const Customer = mongoose.model("Customer");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcryptjs");
const request = require("request-promise");
var nodemailer = require("nodemailer");
const { userValidation } = require("../handlers/validation");
const emailConfig = {
  user: "AKIAZQ3DPSAOYA5MLJP6",
  password: "BKBPmyvQm3tYE73s7SLwXt3ZTPiJCUTz4fAMNPJker5h",
  host: "email-smtp.us-east-1.amazonaws.com",
};

var fs = require("fs");

const net = require("net");

 
const getMonday = (date) => {
  const day = date.getDay() === 0 ? 7 : date.getDay();
  const monday = new Date(date);
  monday.setDate(date.getDate() - day + 1);
  monday.setHours(0, 0, 0, 0); // reset to midnight for accurate comparison
  return monday;
};

// Function to convert IPv6-mapped IPv4 to pure IPv4 if needed
// (This remains if you ever get an address with "::ffff:" – otherwise, Express/IP configuration should prevent it)
const getIPv4 = (ip) => {
  if (net.isIPv4(ip)) return ip;
  if (ip && ip.startsWith("::ffff:")) return ip.slice(7);
  return "127.0.0.1"; // fallback
};

exports.Login = async (req, res) => {
  try {
    const { error } = userValidation(req.body);
    if (error) return res.status(400).send(error.details[0].message);

    const user = await User.findOne({ email: req.body.email });
    if (!user) return res.status(400).send("Wrong Email Entered");

    const validPassword = await bcrypt.compare(
      req.body.password,
      user.password
    );
    if (!validPassword) return res.status(400).send("Invalid Password");

    let ip =
      req.headers["x-forwarded-for"] || req.socket.remoteAddress || req.ip;
    ip = getIPv4(ip);

    let storeDomain =
      user.storeData.length > 0 && user.storeData[0].storeDomain
        ? user.storeData[0].storeDomain
        : "";

    let TokenInfo = {
      id: user._id,
      balance: user.balance,
      phoneNo: user.phoneNo,
      gstNumber: user.gstNumber,
      email: user.email,
      category: user.category,
      store: user.store,
      name: user.fName + " " + user.lName,
      storeDomain: storeDomain,
    };

    let userInfo = {
      id: user._id,
      email: user.email,
      category: user.category,
      name: user.fName,
      origin: user.origin ? user.origin : "india",
    };

    const token = {
      token: jwt.sign(TokenInfo, process.env.TOKEN_SECRET),
      user: userInfo,
    };

    // Calculate the start of the week (Monday)
    const currentDate = new Date();
    const monday = getMonday(currentDate);

    // Optional: Clear out logins from previous weeks (only keep current week's logins)
    user.loginHistory = user.loginHistory.filter(
      (login) => new Date(login.date) >= monday
    );

    // Calculate weekly logins as the current count plus this login
    const weeklyLogins = user.loginHistory.length + 1;

    user.totalLoginCount = (user.totalLoginCount || 0) + 1;
    user.weeklyLoginCount = weeklyLogins;
    user.lastLoginDate = currentDate;
    user.lastLoginIP = ip;
    user.loginHistory.push({ date: currentDate, ip });

    await user.save();

    return res.send(token);
  } catch (error) {
    console.error("Login Error:", error);
    return res.status(500).send("Server error");
  }
};

//Admin Login
exports.AdminLogin = async (req, res) => {
  //console.log(process.env.APP_API_KEY);
  const { error } = userValidation(req.body);
  if (error) return res.status(400).send(error.details[0].message);

  const user = await Adminuser.findOne({ email: req.body.email });
  if (!user) return res.status(400).send("Wrong Email Entered");
  //check password is correct
  const validPassword = await bcrypt.compare(req.body.password, user.password);
  if (!validPassword) return res.status(400).send("Invalid Password");
  //create and assign token

  //create and assign token
  let TokenInfo = {
    id: user._id,
    email: user.email,
    category: user.category,
    name: user.name,
  };

  let userInfo = {
    id: user._id,
    email: user.email,
    category: user.category,
    name: user.fname,
    origin: user.origin ? user.origin : "india",
  };

  const token = {
    token: jwt.sign(TokenInfo, process.env.TOKEN_SECRET),
    user: userInfo,
  };
  return res.send(token);
};

//Admin Registration
exports.subAdminSignup = async (req, res) => {
  //let validate the data
  const { error } = userValidation(req.body);
  if (error) return res.status(400).send(error.details[0].message);
  //user email already exists
  const emailExist = await User.findOne({ email: req.body.email });
  if (emailExist) return res.status(400).send("Email Already Exists");
  //hash the password
  const salt = await bcrypt.genSalt(10);
  const hashPassword = await bcrypt.hash(req.body.password, salt);
  const user = new User({
    name: req.body.name,
    email: req.body.email,
    password: hashPassword,
    category: req.body.category,
  });
  try {
    const savedUser = await user.save();
    return res.send(savedUser);
  } catch (err) {
    return res.status(400).send(err);
  }
};
//get SubAdmin by Id
exports.subAdminUser = async (req, res) => {
  try {
    const data = await User.findOne({ _id: req.params.id });
    return res.json(data);
  } catch (error) {
    return res.json({ message: error.toString() });
  }
};

//update SubAdmin credentenials
exports.subAdminAccount = async (req, res) => {
  // const salt = await bcrypt.genSalt(10);
  // const hashPassword = await bcrypt.hash(req.body.password, salt);
  const updateUser = {
    name: req.body.name,
    email: req.body.email,
    phoneNo: req.body.phone,
    username: req.body.name,
  };
  //
  try {
    const data = await User.findOneAndUpdate(
      { _id: req.body.id },
      { $set: updateUser }
    );
    return res.send("success");
  } catch (error) {
    return res.status(500).send(error.toString());
  }
};

//tranaction detail saved
// exports.transactionDetail = async (req, res) => {
//   const transaction = await new transaction({
//     supplier_id: req.body.supplier_id,
//     trans_id: req.body.trans_id,
//     amount_paid: req.body.amount_paid,
//     pmethod: req.body.pmethod,
//     date: req.body.date,
//     time: req.body.time,
//   });
//   try {
//     const saveTransaction = await transaction.save();
//     return res.send("success");
//   } catch (error) {
//     return res.status(500).send(error.toString());
//   }
// }

//get Transaction Details

// exports.getTransaction= async (req, res) => {
//   try {
//     let data = await Transaction.find().sort({ date: -1 });
//     let userData = await User.find();
//     data.forEach((item, i) => {
//       userData.forEach((item, index) => {
//         if (data[i].supplier_id === userData[index]._id.toString()) {
//           data[i].supplier_id = userData[index].supplier_id;
//         }
//       });
//     });
//     return res.send(data);
//   } catch (e) {
//     return res.status(500).send(error.toString());
//   }
// };
exports.CustomerLogin = async (req, res) => {
  const { error } = userValidation(req.body);
  if (error)
    return res
      .status(400)
      .send({ data: { success: false, message: error.details[0].message } });

  // Check if user exists
  const user = await User.findOne({ email: req.body.email });
  if (!user) {
    return res.status(400).send({
      data: {
        success: false,
        email: req.body.email,
        message: "Wrong Email Entered",
      },
    });
  }

  // Check password
  const validPassword = await bcrypt.compare(req.body.password, user.password);
  if (!validPassword) {
    return res.status(400).send({
      data: {
        success: false,
        message: "Invalid Password",
      },
    });
  }

  let orders = [];
  let totalOrders = 0;
  try {
    const foundOrders = await Orders.find({ merchantId: user._id });
    totalOrders = foundOrders.length;
    orders = {
      totalOrders,
      orders: foundOrders,
    };
  } catch (err) {
    console.error("Error fetching orders:", err);
  }

  let userInfo = {
    id: user._id,
    email: user.email,
    category: user.category,
    name: user.firstName,
    origin: user.origin,
  };

  const token = jwt.sign(userInfo, process.env.TOKEN_SECRET);

  const responseData = {
    data: {
      success: true,
      token,
      user_type: user.category,
      userInfo: user,
      orders,
    },
  };

  return res.send(responseData);
};

exports.CustomerSignup = async (req, res) => {
  //let validate the data
  const { error } = userValidation(req.body);
  if (error) return res.status(400).send(error.details[0].message);
  //user email already exists
  const emailExist = await User.findOne({ email: req.body.email });

  const existEmail = {
    data: {
      success: false,
      message: "Email Already Exists",
    },
  };
  if (emailExist) return res.status(400).send(existEmail);
  //hash the password
  const salt = await bcrypt.genSalt(10);
  const hashPassword = await bcrypt.hash(req.body.password, salt);
  const user = new User({
    email: req.body.email,
    password: hashPassword,
    category: "customer",
    phoneNo: req.body.phoneNo,
    fName: req.body.firstName,
    lName: req.body.lastName,
    created_on: new Date(),
    address: req.body.address,
    state: req.body.state,
    city: req.body.city,
    pincode: req.body.pincode,
  });
  const savedUser = await user.save().then(async (savedUser) => {
    return res.send(savedUser);
  });
};

exports.wholesaleSignup = async (req, res) => {
  //let validate the data
  const { error } = userValidation(req.body);
  if (error) return res.status(400).send(error.details[0].message);
  //user email already exists
  const emailExist = await User.findOne({ email: req.body.email });

  const existEmail = {
    data: {
      success: false,
      message: "Email Already Exists",
    },
  };
  if (emailExist) return res.status(400).send(existEmail);
  //hash the password
  const salt = await bcrypt.genSalt(10);
  const hashPassword = await bcrypt.hash(req.body.password, salt);
  const user = new User({
    email: req.body.email,
    password: hashPassword,
    category: "wholesale",
    phoneNo: req.body.phoneNo,
    fName: req.body.firstName,
    lName: req.body.lastName,
    created_on: new Date(),
    address: req.body.address,
    state: req.body.state,
    city: req.body.city,
    pincode: req.body.pincode,
    company: req.body.company,
    gstNumber: req.body.gst,
  });
  const savedUser = await user.save().then(async (savedUser) => {
    return res.send(savedUser);
  });
};

//dont use try catch becaus we set it  in errorhandlers file
exports.SupplierSignUp = async (req, res) => {
  //hash the password
  //  return false;
  const salt = await bcrypt.genSalt(10);
  const hashPassword = await bcrypt.hash(req.body.password, salt);
  const user = await new User({
    supplier_id: req.body.supplierId,
    email: req.body.email,
    password: hashPassword,
    category: "supplier",
    name: req.body.name,
    businessName: req.body.businessName,
    phoneNo: req.body.phoneNo,
    created_on: new Date(),
    pInfo: {
      website: req.body.website,
      vat: req.body.vat,
      warehouse: req.body.warehouse,
      ePacket: req.body.ePacket,
      processingTime: req.body.processingTime,
      nonEpacCountry: req.body.nonEpacCountry,
      epacCountry: req.body.epacCountry,
      fastShipping: req.body.fastShipping,
      invoice: req.body.invoice,
      brandPackage: req.body.brandPackage,
      minOrder: req.body.minOrder,
      returnDetail: req.body.returnDetail,
    },
  });

  const savedUser = await user.save().then(async () => {
    return res.send({ status: 1, message: "User Register successfully" });
  });
};
//merchant sign up
// exports.merchantSignUp =  async (req, res) => {
//   //let validate the data
//   const { error } = userValidation(req.body);
//   if (error) return res.status(400).send(error.details[0].message);

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

//   let merchantStoreData = {
//     storeDomain: req.body.phoneNo + ".shopperr.in",
//   };

//   const currDate = (sep) => {
//     let d = new Date();
//     let DD = d.getDate();
//     let MM = d.getMonth() + 1;
//     let YY = d.getFullYear();
//     return DD + sep + MM + sep + YY;
//   };

//   // const user = new User({
//     const user = new User({
//     name: req.body.firstName +' '+ req.body.lastName,
//     phoneNo: req.body.phoneNo,
//     email: req.body.email,
//     address: req.body.address,
//     company: req.body.company,
//     country: req.body.country,
//     pincode: req.body.pincode,
//     city: req.body.city,
//     state: req.body.state,
//     GstinNumber: req.body.gst,
//     password: hashPassword,
//     joiningDate: new Date(),
//     storeData: req.body.storeData,
//   });

//     const savedUser = await user.save().then(async () => {
//       return res.send({ status: 1, message: "Merchant Register successfully" });
//     })
//     return res.status(400).send(err);

// };

//merchant order from shopify
// exports.leftOrdermerchantShopify = async (req, res) => {
//   const orderData = await orders.find();
//   let newOrderArray = [];
//   orderData.forEach((item, i) => {
//     item.products.forEach((product, j) => {
//       if (product.sku !== undefined) {
//         newOrderArray.push({
//           orderId: item.product_name,
//           total_amount: item.price,
//           date: item.created_on,
//           paymentMode: item.paymentMode,
//           customer_name: item.customer,
//           sku: product.sku,
//           item_price: product.price,
//           quantity: product.quantity,
//           store: product.store,
//           pStatus: item.pStatus,
//         });
//       }
//     });
//   });

//   let checkStore = [];
//   let tempArray = [];
//   newOrderArray.forEach((item, i) => {
//     if (
//       item.store &&
//       req.params &&
//       item.store.toLowerCase() === req.params.store
//     ) {
//       tempArray.push({
//         orderId: item.orderId,
//         total_amount: item.total_amount,
//         date: item.date,
//         paymentMode: item.paymentMode,
//         customer_detail: item.customer_name,
//         item_price: item.item_price,
//         sku: item.sku,
//         productImage: [],
//         quantity: item.quantity,
//         productName: "",
//         shippingCharge: {},
//         store: item.store,
//         pStatus: item.pStatus,
//       });
//     }
//   });

//   let productData = await Products.find();

//   tempArray.forEach((item, i) => {
//     productData.forEach((product, j) => {
//       if (product.varientArray.length != 0) {
//         product.varientArray.forEach((vArr, l) => {
//           if (vArr.sku === item.sku) {
//             checkStore.push({
//               orderId: item.orderId,
//               pStatus: item.pStatus,
//             });
//           }
//         });
//       } else if (product.code === item.sku) {
//         checkStore.push({
//           orderId: item.orderId,
//           pStatus: item.pStatus,
//         });
//       }
//     });
//   });

//   let finalData = [];
//   checkStore.forEach((item, i) => {
//     if (checkStore[i].pStatus === "unpaid") {
//       finalData.push(checkStore[i]);
//     }
//   });

//   return res.send(finalData);
// }

//merchant unfulfilled order from shopify
// exports.merchantShopifyOrdersUnfulfilled= async (req, res) => {
//   const orderData = await orders.find().sort({ created_on: -1 });
//   let newOrderArray = [];
//   orderData.forEach((item, i) => {
//     item.products.forEach((product, j) => {
//       if (product.sku !== undefined) {
//         newOrderArray.push({
//           orderId: item.product_name,
//           total_amount: item.price,
//           date: item.created_on,
//           paymentMode: item.paymentMode,
//           customer_name: item.customer,
//           sku: product.sku,
//           item_price: product.price,
//           quantity: product.quantity,
//           store: product.store,
//           pStatus: item.pStatus,
//           fulfillmentStatus: item.fulfillmentStatus,
//         });
//       }
//     });
//   });

//   let checkStore = [];
//   let tempArray = [];
//   newOrderArray.forEach((item, i) => {
//     if (item.store.toLowerCase() === req.params.store) {
//       tempArray.push({
//         orderId: item.orderId,
//         total_amount: item.total_amount,
//         date: item.date,
//         paymentMode: item.paymentMode,
//         customer_detail: item.customer_name,
//         item_price: item.item_price,
//         sku: item.sku,
//         quantity: item.quantity,
//         store: item.store,
//         pStatus: item.pStatus,
//         fulfillmentStatus: item.fulfillmentStatus,
//       });
//     }
//   });

//   let productData = await Products.find();

//   tempArray.forEach((item, j) => {
//     productData.forEach((product, k) => {
//       if (product.varientArray.length != 0) {
//         product.varientArray.forEach((vArr, l) => {
//           if (vArr.sku === item.sku) {
//             checkStore.push({
//               orderId: item.orderId,
//               total_amount: item.total_amount,
//               date: item.date,
//               paymentMode: item.paymentMode,
//               customer_detail: item.customer_detail,
//               item_price: item.item_price,
//               sku: item.sku,
//               productImage: product.productImage,
//               quantity: item.quantity,
//               productName: vArr.varient,
//               selliingPrice: vArr.selliingPrice,
//               shippingCharge: product.shippingCharge,
//               store: item.store,
//               pStatus: item.pStatus,
//               fulfillmentStatus: item.fulfillmentStatus,
//             });
//           }
//         });
//       } else if (product.code === item.sku) {
//         checkStore.push({
//           orderId: item.orderId,
//           total_amount: item.total_amount,
//           date: item.date,
//           paymentMode: item.paymentMode,
//           customer_detail: item.customer_detail,
//           item_price: item.item_price,
//           sku: item.sku,
//           productImage: product.productImage,
//           quantity: item.quantity,
//           productName: product.name,
//           shippingCharge: product.shippingCharge,
//           selliingPrice: product.selliingPrice,
//           store: item.store,
//           pStatus: item.pStatus,
//           fulfillmentStatus: item.fulfillmentStatus,
//         });
//       }
//     });
//   });

//   let finalDataUnpiad = [];
//   let finalDataPaid = [];
//   checkStore.forEach((item, i) => {
//     if (checkStore[i].fulfillmentStatus === "Unfulfilled") {
//       finalDataUnpiad.push(checkStore[i]);
//     }
//   });
//   checkStore.forEach((item, i) => {
//     if (checkStore[i].fulfillmentStatus === "Fulfilled") {
//       finalDataPaid.push(checkStore[i]);
//     }
//   });

//   let finalData = {
//     allOrder: checkStore,
//     unfulfilOrder: finalDataUnpiad,
//     fulfilOrder: finalDataPaid,
//   };
//   return res.send(finalData);
// };

//merchant order sent to supplier after payment
// exports.supplierOrderMerchant = async (req, res) => {
//   const orderData = await orders.find();
//   let newOrderArray = [];
//   orderData.forEach((item, i) => {
//     item.products.forEach((product, j) => {
//       if (product.sku !== undefined) {
//         newOrderArray.push({
//           orderId: item.product_name,
//           total_amount: item.price,
//           date: item.created_on,
//           paymentMode: item.paymentMode,
//           customer_name: item.customer,

//           sku: product.sku,
//           item_price: product.price,
//           quantity: product.quantity,
//           store: product.store,
//           pStatus: item.pStatus,
//         });
//       }
//     });
//   });

//   checkStore = [];

//   newOrderArray.forEach((item, i) => {
//     if (item.store.toLowerCase() === req.params.store) {
//       checkStore.push({
//         orderId: item.orderId,
//         total_amount: item.total_amount,
//         date: item.date,
//         paymentMode: item.paymentMode,
//         customer_detail: item.customer_name,
//         item_price: item.item_price,
//         sku: item.sku,
//         productImage: [],
//         quantity: item.quantity,
//         productName: "",
//         shippingCharge: {},
//         store: item.store,
//         pStatus: item.pStatus,
//       });
//     }
//   });

//   let productData = await Products.find();

//   productData.forEach((product, i) => {
//     checkStore.forEach((check, index) => {
//       if (product.varientArray.length != 0) {
//         product.varientArray.forEach((vArr, l) => {
//           if (checkStore[index].sku === vArr.sku) {
//             checkStore[index].productImage = productData[i].productImage;
//             checkStore[index].productName = vArr.name;
//             checkStore[index].shippingCharge = productData[i].shippingCharge;
//           }
//         });
//       } else if (productData[i].code === checkStore[index].sku) {
//         checkStore[index].productImage = productData[i].productImage;
//         checkStore[index].productName = productData[i].name;
//         checkStore[index].shippingCharge = productData[i].shippingCharge;
//       }
//     });
//   });
//   let finalData = [];
//   checkStore.forEach((item, i) => {
//     if (checkStore[i].pStatus === "Paid") {
//       finalData.push(checkStore[i]);
//     }
//   });
//   return res.send(finalData);
// };

//update merchant order status and sent to supplier
// exports.supplierOrderFromMerchant = async (req, res) => {
//   try {
//     const data = await Orders.findOneAndUpdate(
//       { product_name: req.params.orderId },
//       {
//         $set: {
//           pStatus: "Paid",
//           updated_on: new Date(),
//         },
//       },
//       {
//         new: true,
//         // useFindAndModify: false,
//       },
//       (err, result) => {
//         if (!err) {
//           return res.send("success");
//         } else {

//         }
//       }
//     );
//   } catch (error) {
//     return res.status(500).send(error.toString());
//   }
// }
//=================================================================
exports.signUpOtp = async (req, res) => {
  let otp = Math.floor(100000 + Math.random() * 900000);
  let transporter = nodemailer.createTransport({
    host: emailConfig.host,
    port: 465,
    secure: true,
    auth: {
      user: emailConfig.user,
      pass: emailConfig.password,
    },
  });
  let subject = "OTP For Account Verififcation";
  var mailerHtml = "";
  try {
    mailerHtml = fs.readFileSync(
      "././emailTemplates/registration-email.html",
      "utf8"
    );
    mailerHtml = mailerHtml.replace("{{otp}}", otp);
    mailerHtml = mailerHtml.replace("{{name}}", req.body.firstName);
  } catch (err) {
    console.log(err);
    return false;
  }
  if (req.body.type != "supplier") {
    //let validate the data
    const { error } = userValidation(req.body);
    if (error) return res.status(400).send(error.details[0].message);
    //user email already exists

    const emailExist = await User.findOne({ email: req.body.email });
    if (emailExist) return res.status(200).send("Email Already Exists");
    const phoneExist = await User.findOne({
      phoneNo: req.body.phoneNo,
    });
    if (phoneExist) {
      return res.status(200).send("PhoneNo already Exist");
    }
    const CustomerlogIdExist = await User.findOne({
      customer_logid: req.body.customer_logid,
    });
    if (CustomerlogIdExist)
      return res.status(200).send("customer_logid Already Exists");
    // const gstExist = await MerchantUser.findOne({ gst: req.body.gst });
    // if (gstExist) return res.status(400).send("Gst Already Exists");
  }
  await transporter.sendMail(
    {
      from: "Shopperr <support@shopperr.in>",
      to: req.body.email,
      subject: subject,
      html: mailerHtml,
    },
    function (error, info) {
      if (error) {
        console.log(error);
        return false;
      } else {
        return res.send({ status: 1, Otp: otp });
      }
    }
  );
};

exports.signUpMerchant = async (req, res) => {
  const { error } = userValidation(req.body);
  if (error) return res.status(400).send(error.details[0].message);

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

  let merchantStoreData = {
    storeDomain: req.body.phoneNo + ".shopperr.in",
  };

  const currDate = (sep) => {
    let d = new Date();
    let DD = d.getDate();
    let MM = d.getMonth() + 1;
    let YY = d.getFullYear();
    return DD + sep + MM + sep + YY;
  };

  const merchantUser = new User({
    fName: req.body.firstName,
    lName: req.body.lastName,
    phoneNo: req.body.phoneNo,
    email: req.body.email,
    address: req.body.address,
    company: req.body.company,
    country: req.body.country,
    pincode: req.body.pincode,
    customer_logid: req.body.customer_logid,
    city: req.body.city,
    state: req.body.state,
    gstNumber: req.body.gst,
    password: hashPassword,
    createdAt: new Date(),
    storeData: merchantStoreData,
  });

  try {
    await merchantUser.save();
    return res.send({ status: 1, message: "User registered successfully" });
  } catch (err) {
    return res.status(400).send(err);
  }
};

//=================================================================

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

exports.resetPassword = async (req, res) => {
  if (req.body.userType == "merchant") {
    let user = await User.findOne({ email: req.body.email }, { firstName: 1 });
    if (user) {
      let url =
        process.env.FORWARD_ADDRESS +
        "/merchant/reset-password?token=" +
        makeid(5) +
        user._id;
      let transporter = nodemailer.createTransport({
        host: emailConfig.host,
        port: 587,
        secure: false,
        auth: {
          user: emailConfig.user,
          pass: emailConfig.password,
        },
      });
      let subject = "Reset your password";
      var mailerHtml = "";
      try {
        mailerHtml = fs.readFileSync(
          "././emailTemplates/forget-password-email.html",
          "utf8"
        );
        mailerHtml = mailerHtml.replace("{{href}}", url);
      } catch (err) {
        res.send("Html template not found.");
        return false;
      }
      await transporter.sendMail(
        {
          from: "Shopperr <support@shopperr.in>",
          to: req.body.email,
          subject: subject,
          html: mailerHtml,
        },
        function (error, info) {
          if (error) {
            return res.send({ status: 1, response: "Something went wrong." });
          } else {
            return res.send({ status: 0, response: "Mail successfully send" });
          }
        }
      );
    } else {
      return res.send({
        status: 1,
        response: "Account not exists with given email.",
      });
    }
  } else if (req.body.userType == "supplier") {
    let user = await User.findOne({ email: req.body.email }, { firstName: 1 });
    if (user) {
      let url =
        process.env.FORWARD_ADDRESS +
        "/supplier/reset-password?token=" +
        makeid(5) +
        user._id;
      let transporter = nodemailer.createTransport({
        host: emailConfig.host,
        port: 587,
        secure: false,
        auth: {
          user: emailConfig.user,
          pass: emailConfig.password,
        },
      });
      let subject = "Reset your password";
      var mailerHtml = "";
      try {
        mailerHtml = fs.readFileSync(
          "././emailTemplates/forget-password-email.html",
          "utf8"
        );
        mailerHtml = mailerHtml.replace("{{href}}", url);
      } catch (err) {
        res.send("Html template not found.");
        return false;
      }
      await transporter.sendMail(
        {
          from: "Shopperr <support@shopperr.in>",
          to: req.body.email,
          subject: subject,
          html: mailerHtml,
        },
        function (error, info) {
          if (error) {
            return res.send({ status: 1, response: "Something went wrong." });
          } else {
            return res.send({ status: 0, response: "Mail successfully send" });
          }
        }
      );
    } else {
      return res.send({
        status: 1,
        response: "Account not exists with given email.",
      });
    }
  } else {
    return res.send({ status: 1, response: "Something went wrong." });
  }
};

exports.updatePassword = async (req, res) => {
  if (req.body.userType == "merchant") {
    let mingoId = mongoose.Types.ObjectId(req.body.id.slice(5));
    if (mingoId) {
      let user = await User.findOne({ _id: mingoId }, { firstName: 1 });
      if (user) {
        const salt = await bcrypt.genSalt(10);
        const hashPassword = await bcrypt.hash(req.body.password, salt);
        try {
          User.updateOne(
            { _id: mingoId },
            { $set: { password: hashPassword } },
            { upsert: true }
          ).then(() => {
            res.send({ status: 0, response: "Password update successfully." });
          });
        } catch (err) {
          res.send({ status: 1, response: err.toString() });
        }
      } else {
        res.send({ status: 1, response: "Invalid token" });
      }
    } else {
      res.send({ status: 1, response: "Invalid token" });
    }
  } else if (req.body.userType == "supplier") {
    let mingoId = mongoose.Types.ObjectId(req.body.id.slice(5));
    if (mingoId) {
      let user = await User.findOne({ _id: mingoId }, { firstName: 1 });
      if (user) {
        const salt = await bcrypt.genSalt(10);
        const hashPassword = await bcrypt.hash(req.body.password, salt);
        try {
          User.updateOne(
            { _id: mingoId },
            { $set: { password: hashPassword } },
            { upsert: true }
          ).then(() => {
            res.send({ status: 0, response: "Password update successfully." });
          });
        } catch (err) {
          res.send({ status: 1, response: err.toString() });
        }
      } else {
        res.send({ status: 1, response: "Invalid token" });
      }
    } else {
      res.send({ status: 1, response: "Invalid token" });
    }
  } else {
    return res.send({ status: 1, response: "Something went wrong." });
  }
};

exports.CustomerForgotPassword = async (req, res) => {
  if (req.body.userType == "customer") {
    let user = await User.findOne({ email: req.body.email }, { fName: 1 });
    if (user) {
      let url =
        process.env.CUSTOMERFORWARD_ADDRESS +
        "/customer/reset-password?token=" +
        makeid(5) +
        user._id;
      let transporter = nodemailer.createTransport({  
        host: emailConfig.host,
        port: 587,
        secure: false,
        auth: {
          user: emailConfig.user,
          pass: emailConfig.password,
        },
      });
      let subject = "Reset your password";
      var mailerHtml = "";
      try {
        mailerHtml = fs.readFileSync(
          "././emailTemplates/forget-password-email-b2c.html",
          "utf8"
        );
        mailerHtml = mailerHtml.replace("{{href}}", url);
      } catch (err) {
        res.send("Html template not found.");
        return false;
      }
      await transporter.sendMail(
        {
          from: "Shopperr <support@shopperr.in>",
          to: req.body.email,
          subject: subject,
          html: mailerHtml,
        },
        function (error, info) {
          if (error) {
            return res.send({ status: 1, response: "Something went wrong." });
          } else {
            return res.send({ status: 0, response: "Mail successfully send" });
          }
        }
      );
    } else {
      return res.status(400).send({
        status: 1,
        response: "Account not exists with given email.",
      });
    }
  } 
};