const mongoose = require("mongoose");
const adminFunction = require("../function/admin");
const reviweFunction = require("../function/review");
const validation = require("../function/validate");
const OTPFunctoin = require("../function/OTP");
const emailFunction = require("../function/sendEmail");
const jwt = require("jsonwebtoken"); 
const adminModel = require("../models/adminModel");
require("dotenv").config();

const signup = async (req, res) => {
    // const session = await mongoose.startSession();
    // session.startTransaction();
    try {
        const validate = await validation.validateAdmin(req);
        if(validate){
            res.status(200).json({
                success: true,
                msg: "Email Already Exist!"
            })
            // await session.abortTransaction();
            // session.endSession();
        } else {
            const token = jwt.sign({
                email: req.body.email,
                password: req.body.password,
            },process.env.SECRET_KEY ,{ expiresIn: "1y"});
            
            const createOTP = await OTPFunctoin.generateOTP(req);
            const userData = {
                email: req.body.email,
                OTP: createOTP.OTP
            };
            const sendEmail = await emailFunction.sendOTP(userData);
            res.status(200).json({
                success: true,
                msg: "OTP is Sent Kindly Verify!",
                data: req.body.email,
                OTP: createOTP.OTP,
                accessToken: token
            });
            // await session.commitTransaction();
            // session.endSession();
            return 
        }
    } catch (error) {
        console.log("Having Errors :", error);
        res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        });
        // await session.abortTransaction();
        // session.endSession();
        return 
    }
};

const login = async (req, res) => {
    try {
        const validate = await validation.validateAdmin(req);
        if(validate){
            const admin = await adminFunction.getAdmin(req);
            const password = req.body.password;
            const hash = admin.password; 
            const verify = await validation.verifyPassword(password, hash);
            if(!verify){
                return res.status(200).json({
                    success: true,
                    msg: "Wrong Password!"
                });
            } else {
                const token = jwt.sign({
                    id: admin._id,                   
                    email: admin.email,
                }, process.env.SECRET_KEY, { expiresIn: "1y"});
                const adminId = admin._id;
                const adminData = await adminFunction.getAdminProfile(adminId);

                return res.status(200).json({
                    success: true,
                    msg: "User Successfully Logged In!",
                    data: adminData,
                    accessToken: token
                });
            }
        } else {
            return res.status(200).json({
                success: true,
                msg: "No Email Found!"
            })
        }
    } catch (error) {
        console.log("Having Errors!", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
};

const verifyOTP = async (req, res) => {
    // const session = await mongoose.startSession();
    // session.startTransaction();
    try {
        const verfiyOTP = await OTPFunctoin.verfiyOTP(req);
        if(verfiyOTP){
            let { signUpToken } = req.body;
            const decode = jwt.verify(signUpToken, process.env.SECRET_KEY);
            const admin = await adminFunction.signup(decode);

            const token = jwt.sign({
                id: admin._id,
                email: admin.email,
                profileCreated: admin.profileCreated
            }, process.env.SECRET_KEY, { expiresIn: "1y"});

            res.status(200).json({
                success: true,
                msg: "Admin Signed Up Successfully!",
                data: {
                    _id: admin._id,
                    email: admin.email
                },
                accessToken: token
            });
            // await session.commitTransaction();
            // session.endSession();
            return
        } else {
            res.status(200).json({
                success: true,
                msg: "Invalid OTP!",
            });
            // await session.abortTransaction();
            // session.endSession();
            return
        }
    } catch (error) {
        console.log("Having Errors!", error);
        res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        });
        // await session.abortTransaction();
        // session.endSession();
        return 
    }
};

const getAdminProfile = async (req, res) => {
    try {
        const { adminId } = req.query;
        const admin = await adminFunction.getAdminProfile(adminId);
        return res.status(200).json({
            success: true,
            msg: "Admin Profile!",
            data: admin
        })
    } catch (error) {
        console.log("Having Errors!", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
};

const updateAdmin = async (req, res) => {
    // const session = await mongoose.startSession();
    // session.startTransaction();
    try {
        const admin = await adminFunction.updateAdmin(req);
        res.status(200).json({
            success: true,
            msg: "Admin Details Updated!",
            data: admin
        });
        // await session.commitTransaction();
        // session.endSession();
        return
    } catch (error) {
        console.log("Having Errors!", error);
        res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
        // await session.abortTransaction();
        // session.endSession();
        return 
    }
};

const forgetPassword = async (req, res) => {
    try {
        const admin = await adminFunction.forgetPassword(req);
        if( admin === null){
            return res.status(200).json({
                success: false,
                msg: "No Admin Profile Found!",
            })
        } else {
            const createOTP = await OTPFunctoin.generateOTP(req);
            const userData = {
                email: req.body.email,
                OTP: createOTP.OTP
            };
            const sendOtp = await emailFunction.sendOTP(userData);  
            return res.status(200).json({
                success: true,
                msg: "Admin Account Found!",
                data: {
                    adminId: admin._id,
                    email: admin.email,
                    OTP: createOTP.OTP
                }
            })
        }
    } catch (error) {
        console.log("Having Errors!", error);
        res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
};

const OTPForPassword = async (req, res) => {
    try {
        const verify = await OTPFunctoin.verfiyOTP(req);
        if(!verify){
            return res.status(200).json({
                success: false,
                msg: "Invalid OTP"
            })
        } else {
            return res.status(200).json({
                success: true,
                msg: "OTP is Verified!"
            })
        }
    } catch (error) {
        console.log("Having Errors!", error);
        res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
}

const resetPassword = async (req, res) => {
    try {
        const admin = await adminFunction.updatePassword(req);
        return res.status(200).json({
            success: true,
            msg: "Password Updated Successfully!",
            data: admin
        })
    } catch (error) {
        console.log("Having Errors!", error);
        res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })        
    }
}

const deleteAdmin = async (req, res) => {
    // const session = await mongoose.startSession();
    // session.startTransaction();
    try {
        const admin = await adminFunction(req);
        res.status(200).json({
            success: true,
            msg: "Admin Deleted Successfully!",
        });
        // await session.commitTransaction();
        // session.endSession();
    } catch (error) {
        console.log("Having Errors!", error);
        res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        });
        // await session.abortTransaction();
        // session.endSession();
        return 
    }
};

//Shop APIS

const addShop = async (req, res) => {
    // const session = await mongoose.startSession();
    // session.startTransaction();
    try {
        const shop = await adminFunction.addShop(req);
        const adminId = req.body.adminId;
        const shopId = shop._id;
        const update = await adminFunction.updatedShopId(adminId, shopId);
        res.status(200).json({
            success: true,
            msg: "Shop is Created Successfully!",
            data: shop
        });
        // await session.commitTransaction();
        // session.endSession();
        return;
    } catch (error) {
        console.log("Having Errors!", error);
        res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        });
        // await session.abortTransaction();
        // session.endSession();
        return 
    };
};

const getShopById = async (req, res) => {
    try {
        const shop = await adminFunction.getShopById(req);
        return res.status(200).json({
            success: true,
            msg: "Shop Details!",
            data: shop,         
        });
    } catch (error) {
        console.log("Having Errors!", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
};

const getShopAdminId = async (req, res) => {
    try {
        const shop = await adminFunction.getShopAdminId(req);
        return res.status(200).json({
            success: true,
            msg: "Shop Details By AdminId",
            data: shop
        })
    } catch (error) {
        console.log("Having Errors!", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
};

const getAllShops = async (req, res) => {
    try {
        const shops = await adminFunction.getAllShops(req);
        return res.status(200).json({
            success: true,
            msg: "All Shops Details!",
            data: shops
        })
    } catch (error) {
        console.log("Having Errors!", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
};

const updateShop = async (req, res) => {
    // const session = await mongoose.startSession(); 
    // session.startTransaction();
    try {
        const shop = await adminFunction.updateShop(req);
        const admin = await adminFunction.updateShopProfilePath(req);
        res.status(200).json({
            success: true,
            msg: "Shop Details Updated!",
            data: shop
        });
        // await session.commitTransaction();
        // session.endSession();
        return
    } catch (error) {
        console.log("Having Errors!", error);
        res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        });
        // await session.abortTransaction();
        // session.endSession();
        return 
    }
};

const nearByShops = async (req, res) => {
    try {
        const shops = await adminFunction.getNearByShops(req);
        if(shops.length === 0){
            return res.status(200).json({
                success: false,
                msg: "No Nearby Shops Found!"
            })
        } else {
                return res.status(200).json({
                success: true,
                msg: "All NearBy Shops!",
                data: shops
            })
        }
    } catch (error) {
        console.log("Having Errors!", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        });
    }
}

const deleteShop = async (req, res) => {
    // const session = await mongoose.startSession();
    // session.startTransaction();
    try {
        const shop = await adminFunction.deleteShopById(req);
        res.status(200).json({
            success: true,
            msg: "Shop is Deleted!"
        });
        // await session.commitTransaction();
        // session.endSession();
        return
    } catch (error) {
        console.log("Having Errors!", error);
        res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        });
        // await session.abortTransaction();
        // session.endSession();
        return
    }
};

module.exports = {
    signup,
    login,
    verifyOTP,
    getAdminProfile,
    updateAdmin,
    forgetPassword,
    OTPForPassword,
    resetPassword,
    deleteAdmin,
    addShop,
    getShopById,
    getShopAdminId,
    getAllShops,
    nearByShops,
    updateShop,
    deleteShop
};
