const bcrypt = require("bcrypt");
const adminModel = require("../models/adminModel");
const shopModel = require("../models/shopModel");
const reviewModel = require("../models/reviews");
const { json } = require("express");

const signup = async (decode) => {
  const hash = await bcrypt.hash(decode.password, 10);
  const newAdmin = new adminModel({
    email: decode.email,
    password: hash,
  });
  newAdmin.password = hash;
  const result = await newAdmin.save();
  return result;
};

const getAdmin = async (req) => {
  const admin = await adminModel.findOne({ email: req.body.email });
  return admin;
};

const getAdminProfile = async (adminId) => {
  const admin = await adminModel.findById({ _id: adminId }).select("-password");
  return admin;
};

const updateAdmin = async (req) => {
  const { adminId } = req.body;
  const updatedData = req.body;
  const { longitude, latitude, locationName } = req.body;
  if (req.file && req.file.filename) {
    updatedData.profileImage = req.file.filename;
  }
  if (longitude && latitude) {
    console.log("first :", longitude);
    console.log("Second :", latitude);
    updatedData.location = {
      type: "Point",
      coordinates: [parseFloat(longitude), parseFloat(latitude)],
      locationName: locationName,
    };
  }
  const result = await adminModel
    .findByIdAndUpdate(
      { _id: adminId },
      { $set: { ...updatedData, profileCreated: true } },
      { new: true }
    )
    .select("-password");
  return result;
};

const forgetPassword = async (req) => {
  const { email } = req.body;
  const admin = await adminModel.findOne({ email: email });
  return admin  
};

const updatePassword = async (req) => {
  const { adminId, password } = req.body;
  const hash = await bcrypt.hash(password, 10);
  const admin = await adminModel.findByIdAndUpdate(
    { _id: adminId },
    { $set: { password: hash } },
    { new: true }
  );
  return admin;
};

const deleteAdmin = async (req) => {
  const { adminId } = req.query;
  const admin = await adminModel.findByIdAndDelete({ _id: adminId });
  return admin;
};

// Shop Functions
const addShop = async (req) => {
  const { adminId } = req.body;
  // console.log("first :", adminId);
  // return
  if(req.body.longitude && req.body.latitude){
    req.body.location = {
    type: "Point",
    coordinates: [
      parseFloat(req.body.longitude),
      parseFloat(req.body.latitude),
    ],
    address: req.body.address,
  };
  }
  if(req.file && req.file.filename){
    const image = req.file.filename;
  
  const newShop = new shopModel({
    ...req.body,
    shopImage: image,
  });
  if(req.body.workingDays){
      const workingDays = JSON.parse(req.body.workingDays);
      newShop.workingDays = workingDays;
  }
  const result = await newShop.save();
  const admin = await adminModel.findByIdAndUpdate(
    { _id: adminId },
    { $set: { shopCreated: true, shopProfilepath: req.body.path } },
    { new: true }
  );
  return result;
  } else {
 
  const newShop = new shopModel({
    ...req.body
  });
  if(req.body.workingDays){
    const workingDays = JSON.parse(req.body.workingDays);
    newShop.workingDays = workingDays;
  }
  const result = await newShop.save();
  const admin = await adminModel.findByIdAndUpdate(
    { _id: adminId },
    { $set: { shopCreated: true, shopProfilepath: req.body.path } },
    { new: true }
  );
  return result;
  }
  
};

const getShopById = async (req) => {
  const { shopId } = req.query;
  const shop = await shopModel.findById({ _id: shopId }).populate({
    path: "adminId",
    select: "longitude latitude postalCode",
  });
  return shop;
};

const updateShopProfilePath = async (req) => {
  const { adminId, path } = req.body;
  const admin = await adminModel.findByIdAndUpdate({_id: adminId},
    { $set: {shopProfilepath: path}}, 
    { new: true});
    return admin
}

const updateShop = async (req) => {
  const { shopId } = req.body;
  const updatedData = req.body;
  if(req.body.workingDays){
    updatedData.workingDays = JSON.parse(req.body.workingDays)
  };
  // console.log("first :", req.file.filename);
  if (req.body.longitude && req.body.latitude && req.body.address) {
    updatedData.location = {
      type: "Point",
      coordinates: [
        parseFloat(req.body.longitude),
        parseFloat(req.body.latitude),
      ],
      address: req.body.address,
    };
  }
  if (req.file && req.file.filename) {
    updatedData.shopImage = req.file.filename;
  }
  const shop = await shopModel.findOneAndUpdate(
    { _id: shopId },
    { $set: updatedData },
    { new: true }
  );
  return shop;
};

const updateRatingInShop = async (data) => {
    const { shopId, avgRating } = data;
    const rating = avgRating.avgRating;
    
    const shop = await shopModel.findByIdAndUpdate({_id: shopId}, {
        $set: { avgRating: rating }
    },
    { new: true});
    return shop
} 

const getShopAdminId = async (req) => {
  const { adminId } = req.query;
  const shop = await shopModel.findOne({ adminId: adminId });
  return shop;
};

const getAllShops = async (req) => {
  const { name, category, barName } = req.query;
  // console.log("first :", barName);
  const filter = {}
  if(category){
    filter.category = category
  }
  if(name){
    filter.barName = { $regex: name, $options: 'i' }
  }
  const shops = await shopModel.find(filter);
  return shops
};

const getNearByShops = async (req) => {
    const { longitude, latitude } = req.query;

    console.log("longitude :", longitude);
    console.log("latitude :", latitude);

    const location = {
        type: "Point",
        coordinates: [
            parseFloat(longitude),
            parseFloat(latitude)
        ]
    }

    const shops = await shopModel.find({
        location:{
            $near:{
                $geometry: {
                    type: "Point",
                    coordinates: location.coordinates
                },
                $maxDistance: 1000
            }
        }
    })
    return shops
};

const deleteShopById = async (req) => {
  const { shopId } = req.query;
  const shop = await shopModel.findByIdAndDelete({ _id: shopId });
  return shop;
};

const updatedShopId = async (adminId, shopId) => {
  const result = await adminModel.findByIdAndUpdate({ _id: adminId}, 
    { $set: { shopId: shopId } },
    { new: true }
  );
  return result;
}

module.exports = {
  signup,
  getAdmin,
  getAdminProfile,
  updateAdmin,
  forgetPassword,
  updatePassword,
  deleteAdmin,
  addShop,
  getShopById,
  updateShop,
  updateRatingInShop,
  getShopAdminId,
  getAllShops,
  getNearByShops,
  deleteShopById,
  updateShopProfilePath,
  updatedShopId
};
