const userFunction = require("../function/user");
const validation = require("../function/validate");
const emailFunction = require("../function/sendEmail");
const OTPFunction = require("../function/OTP");
const jwt = require("jsonwebtoken");
require("dotenv").config();

const signup = async (req, res) => {
    try {
        const age = await validation.validateAge(req);
        if(!age){
            return res.status(200).json({
                success: false,
                msg: "Age Must be Above 21!"
            })
        } else {
            // console.log("Controller :", age);
            // return
            const validate = await validation.validateUser(req);
                if(validate){
                return res.status(200).json({
                    success: true,
                    msg: "Email is Already Taken!"
                });
            } else {
                let token = jwt.sign({
                    email: req.body.email,
                    phone: req.body.phone,
                    password: req.body.password,
                    DOB: req.body.DOB
                }, process.env.SECRET_KEY, {expiresIn: "1y"});
                const createOTP = await OTPFunction.generateOTP(req);
                const userData = {
                    email: req.body.email,
                    OTP: createOTP.OTP
                };

                const sendEmail = await emailFunction.sendOTP(userData);
                return res.status(200).json({
                    success: true,
                    msg: "OTP is Sent SuccessFully",
                    data: userData,
                    accessToken: token
                });
            }
        }
    } catch (error) {
        console.log("Having Errors :", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
};

const login = async (req, res) => {
    try {
        const validate = await validation.validateUser(req);
        if(!validate){
            return res.status(200).json({
                success: false,
                msg: "No Account Found!"
            })
        } else {
            const { password } = req.body;
            const user = await userFunction.getUser(req);
            if(user.isDeleted === true){
                return res.status(200).json({
                    success: false,
                    msg: "User Account is Deleted Can Not Login!"
                })
            } else {
                const hash = user.password;
                const verify = await validation.verifyPassword(password, hash);
                if(!verify){
                    return res.status(200).json({
                        success: false,
                        msg: "Incorrect Password"
                    });
                } else {
                    const token = jwt.sign({
                        id: user._id,                
                        email: user.email,
                        phone: user.phone
                    }, process.env.SECRET_KEY, {expiresIn: "1y"});

                     const userId = user._id;
                     const userData = await userFunction.getProfile(userId);
             
                    return res.status(200).json({
                        success: true,
                        msg: "User Logged In Successfully!",
                        data: userData,
                        accessToken: token
                    });
                } 
            }
        }
    } 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) => {
    try {
        const verify = await OTPFunction.verfiyOTP(req);
        if(verify){
            let { signupToken } = req.body;
            const decode = jwt.verify(signupToken, process.env.SECRET_KEY);

            const user = await userFunction.signup(decode);
            
            const token = jwt.sign({
                email: user.email,
                phone: user.phone
            }, process.env.SECRET_KEY, {expiresIn: "1y"});
            return res.status(200).json({
                success: true,
                msg: "OTP is Verified!",
                data: {
                    _id: user._id,
                    email: user.email,
                    phone: user.phone,
                    DOB: user.DOB,
                    profileCreted: user.profileCreted
                },
                accessToken: token
            });
        } else { 
            return res.status(200).json({
                success: false,
                msg: "OTP is Not Verified!"
            })
        }
    } catch (error) {
        console.log("Having Errors :", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
};

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

const getUserProfile = async (req, res) => {
    try {
        const { userId } = req.query;
        const user = await userFunction.getProfile(userId);
        return res.status(200).json({
            success: true,
            msg: "All User Details!",
            data: user
        })
    } catch (error) {
        console.log("Having Errors :", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
};

const addLocation = async (req, res) => {
    try {
        const location = await userFunction.addLocation(req);
        if(location){
            const user = await userFunction.addUserLocation(location);
            return res.status(200).json({
                success: true,
                msg: "Location Added Successfully!",
                data: location
            })
        } else {
            return res.status(200).json({
                success: true,
                msg: "No Location is Added!"
            })
        }
    } catch (error) {
        console.log("Having Errors :", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
};

const selectLocation = async (req, res) => {
    try {
        const location = await userFunction.selectLocation(req);
        if(location.location.isSelected === true){
            const user = await userFunction.addUserLocation(location);
            return res.status(200).json({
                success: true,
                msg: "Location is Selected!",
                data: location
            })
        } else {
            return res.status(200).json({
                success: false,
                msg: "Location is Not Selected"
            });
        }
    } catch (error) {
        console.log("Having Errors :", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
};

const updateLocation = async (req, res) => {
    try {
        const location = await userFunction.updateLocation(req);
        return res.status(200).json({
            success: true,
            msg: "Location is Updated!",
            data: location
        })
    } catch (error) {
        console.log("Having Errors :", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
};



const deleteLocation = async (req, res) => {
    try {
        const location = await userFunction.deleteLocation(req);
        return res.status(200).json({
            success: true,
            msg: "Location is Deleted SuccessFully!"
        })        
    } catch (error) {
        console.log("Having Errors :", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
};

const getAllUserLocations = async (req, res) => {
    try {
        const locations = await userFunction.getAllLocations(req);
        if( locations.length === 0){
            return res.status(200).json({
                success: true,
                msg: "No Location Found By User!"
            })
        } else {
            return res.status(200).json({
                success: true,
                msg: "All Locations By User",
                data: locations
            })
        }
    } catch (error) {
                console.log("Having Errors :", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
}

const ForgetPassword = async (req, res) => {
    try {
        const createOTP = await OTPFunction.generateOTP(req);
        const userData = {
            email: req.body.email,
            OTP: createOTP.OTP
        };

        const sendEmail = await emailFunction.sendOTP(userData);
        return res.status(200).json({
            success: true,
            msg: "OTP Sent For ResetPassword!",
            data: userData 
        })
    } catch (error) {
        console.log("Having Errors :", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
};

const verifyOTPForPassword = async (req, res) => {
    try {
        const verify = await OTPFunction.verfiyOTP(req);
        if(verify){
            const { email } = req.body;
            const user = await userFunction.getUser(req); 
            return res.status(200).json({
                success: true,
                msg: "OTP Verified Successfully!",
                data: {
                    id: user._id,
                    fullName: user.fullName,
                    email: user.email,
                    phone: user.phone
                }
            });
        } else {
            return res.status(200).json({
                success: false,
                msg: "OTP is Not Verified!"
            })
        }
    } catch (error) {
        console.log("Having Errors :", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
};

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

const deleteUser = async (req, res) => {
    try {
        const user = await userFunction.deleteUser(req);
        return res.status(200).json({
            success: true,
            msg: "User is Deleted Successfully!"
        })
    } catch (error) {
        console.log("Having Errors :", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
};

const getAllUsers = async (req, res) => {
    try {
        const users = await userFunction.getAllUsers(req);
        if(users.length === 0){
            return res.status(200).json({
                success: false,
                msg: "Users not Found!"
            })
        } else {
            return res.status(200).json({
                success: true,
                msg: "All Users!",
                data: users 
            })
        }
    } catch (error) {
        console.log("Having Errors :", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })
    }
};

const editLocation = async (req, res) => {
    try {
        const location = await userFunction.editLocation(req);
        if(!location){
            return res.status(200).json({
                success: false,
                msg: "No Location Found to Update!"
            })
        } else {
            return res.status(200).json({
                success: true,
                msg: "Location Updated!",
                data: location
            })
        }
    } catch (error) {
        console.log("Having Errors :", error);
        return res.status(400).json({
            success: false,
            msg: "Having Errors!",
            error: error.message
        })        
    }
};

module.exports = {
 signup,
 login,
 verifyOTP,
 updateUser,
 getUserProfile,
 addLocation,
 updateLocation,
 selectLocation,
 getAllUserLocations,
 deleteLocation,
 ForgetPassword,
 verifyOTPForPassword,
 resetPassword,
 deleteUser,
 getAllUsers,
 editLocation
};