var loginObj = require('./../../models/login/loginModel.js');
var superAdminObj = require('./../../models/superAdmins/superAdminsModels.js')
var forgotPasswordObj = require('./../../models/forgotPassword/forgotPassword.js');
var emailService = require('./../email/emailService.js');
var constantObj = require('./../../../constants.js');
var jwt = require('jwt-simple');
var moment = require('moment');
var bcrypt = require('bcryptjs');
var mongoose = require('mongoose');
var inspectorDbObj = require('./../../models/inspector/inspectorModel.js');
var employeeDbObj = require('./../../models/employee/employeeModel.js');
var companyDbObj = require('./../../models/company/companyModel.js');
var adminDbObj = require('./../../models/admin/adminModel.js');
var userTokenObj = require('./../../models/users/userTokens.js');

// Method to Render view
exports.render = function(req, res) {
0
	if (req.user) {
		res.redirect('/');
	} else {

		return res.render('login.ejs', {
			message: req.flash('error'),
			success: req.flash('success')
		});
	}

}
exports.forgotPasswordHtml = function(req, res) {
	if (req.isAuthenticated() && req.user) {
		res.redirect('/');
	} else {
		return res.render('forgot-password.ejs');
	}

}

function loadUserData(req, res) {
	var outputJson = {};
	var query = {
		loginId: mongoose.Types.ObjectId(req.user._id),
		isDeleted: false
	}
	delete req.user.password;
	delete req.user.status;
	delete req.user.isDeleted;
	delete req.user.__v;
	var model = req.user.userType == constantObj.userTypes.superAdmin ? superAdminObj : req.user.userType == constantObj.userTypes.masterInspector ? inspectorDbObj : (req.user.userType == constantObj.userTypes.tlc || req.user.userType == constantObj.userTypes.lineman) ? employeeDbObj : req.user.userType == constantObj.userTypes.company ? companyDbObj : req.user.userType == constantObj.userTypes.admin ? adminDbObj : "";
	if (req.user.userType == constantObj.userTypes.superAdmin || req.user.userType == constantObj.userTypes.admin || req.user.userType == constantObj.userTypes.masterInspector || req.user.userType == constantObj.userTypes.company) {
		model.findOne(query).exec(function(err, data) {
			if (err) {
				req.user = {};
				req.logout();
				outputJson = {
					status: 400,
					message: err
				}
				res.status(400).jsonp({})
			} else {

				if (data) {
					req.user.id = data._id
					req.user.firstName = data.firstName != null ? data.firstName : null;
					req.user.lastName = data.lastName != null ? data.lastName : null;
					req.user.companyName = data.cname != null ? data.cname : null;
					req.user.companyId = data.companyId != null ? data.companyId : null;
					req.user.landmark = data.landmark;
					req.user.streetNumber = data.streetNumber;
					req.user.address = data.address;
					req.user.zipCode = data.zipCode;
					req.user.phone = data.phone;
					req.user.profileImage = data.profileImage != null ? data.profileImage : null;
					outputJson = {
						status: 200,
						message: constantObj.messages.userLoggedInOk,
						userInfo: req.user
					}
					res.status(200).jsonp(outputJson);
				} else {
					req.user = {};
					req.logout();
					return res.status(401).jsonp({
						status: 401,
						message: constantObj.messages.noProfileEr
					});

				}

			}

		})
	} else {
		model.findOne(query).populate('companyId').exec(function(err, data) {
			if (err) {
				req.user = {};
				req.logout();
				outputJson = {
					status: 400,
					message: err
				}
				res.status(400).jsonp({})
			} else {

				if (data) {
					req.user.id = data._id
					req.user.firstName = data.firstName;
					req.user.lastName = data.lastName;
					req.user.companyName = data.companyId.cname;
					req.user.companyId = data.companyId != null ? data.companyId._id : null;
					req.user.landmark = data.landmark;
					req.user.streetNumber = data.streetNumber;
					req.user.address = data.address;
					req.user.zipCode = data.zipCode;
					req.user.phone = data.phone;
					req.user.profileImage = data.profileImage != null ? data.profileImage : null;
					outputJson = {
						status: 200,
						message: constantObj.messages.userLoggedInOk,
						userInfo: req.user
					}
					res.status(200).jsonp(outputJson);
				} else {
					req.user = {};
					req.logout();
					return res.status(401).jsonp({
						status: 401,
						message: constantObj.messages.noProfileEr
					});
				}

			}

		})
	}

}
//authentication response functionality
/*Created By: Rajat Goel
 * Date : 19 oct 2016
 */
exports.authenticate = function(req, res, done) {
	var agent = req.header('userAgent');
	if (agent === constantObj.headerConstants.app) {
		if (req.user) {
			if (req.user.status == 401) {
				return res.status(401).jsonp({
					status: 401,
					message: req.user.message
				});
				req.user = {};
				req.logout();
			} else {
				loadUserData(req, res);
			}
		} else {
			return res.status(401).jsonp({
				status: 401,
				message: constantObj.messages.uncaughtErr
			});

		}


	} else {
		return res.redirect("/");
	}

}


exports.getSession = function(req, res, done) {
	if (req.isAuthenticated()) {
		if (req.user) {
			res.status(200).json({
				status: 200,
				msg: constantObj.messages.Authenticated
			})
		} else {

			return res.status(400).render('login.ejs', {
				message: req.flash(constantObj.messages.NotAuthenticated),
				success: req.flash('success')
			});
		}
	} else {
		return res.status(400).render('login.ejs', {
			message: req.flash(constantObj.messages.NotAuthenticated),
			success: req.flash('success')
		});
	}
}

function findUserDetails(req, res, outputJSON, data, emailSubject, resetUrl, token, view, frm, messageText) {
	var model = data.userType == constantObj.userTypes.superAdmin ? superAdminObj : data.userType == constantObj.userTypes.masterInspector ? inspectorDbObj : (data.userType == constantObj.userTypes.tlc || data.userType == constantObj.userTypes.lineman) ? employeeDbObj : data.userType == constantObj.userTypes.company ? companyDbObj : data.userType == constantObj.userTypes.admin ? adminDbObj : "";
	var query = {
		loginId: mongoose.Types.ObjectId(data._id)
	}
	model.findOne(
		query
	).populate('loginId').exec(function(err, result) {
		if (err) {
			// console.log("err in passport of app.js:", err);
			outputJSON = {
				'status': 400,
				'message': err
			}
			return res.status(400).jsonp(outputJSON);
		} else {
			// console.log("data is ", result);
			if (result) {
				if (result.isDeleted == true) {
					outputJSON = {
						'status': 400,
						'message': constantObj.messages.userNotRegErr
					}
					return res.status(400).jsonp(outputJSON);
				} else {
					var sendData = {};
					if (data.userType == constantObj.userTypes.company) {
						sendData.fullName = result.cname;
					} else {
						sendData.fullName = result.firstName + " " + result.lastName;
					}

					sendData.email = result.loginId.email;
					sendResetLinkEmail(sendData, emailSubject, resetUrl, token, view, frm, req, res, messageText);

				}

			} else {
				outputJSON = {
					'status': 400,
					'message': constantObj.messages.uncaughtErr
				}
				return res.status(400).jsonp(outputJSON);
			}
		}
	})
}
/*
    Function: forgot password
    Created: Rajat Goel
*/
exports.forgotPassword = function(req, res) {
	// console.log("in forgot pasword module");
	var outputJson = {};
	if (!req.body.email) {
		outputJson = {
			status: 400,
			message: constantObj.messages.emailRequiredErr
		}
		return res.status(400).jsonp(outputJson);
	}
	var outputJSON = {};
	loginObj.findOne({
		email: req.body.email
	}, function(err, data) {
		if (err) {
			return res.send(err);
		} else {
			if (!data) {
				outputJSON = {
					'status': 400,
					'message': constantObj.messages.emailDoesnotExist
				}
				return res.send(outputJSON);
			} else if (data.isDeleted == true) {
				outputJSON = {
					'status': 400,
					'message': constantObj.messages.userNotRegErr
				}
				return res.send(outputJSON);
			} else {
				var token = createJWT(data);
				var port = "" //process.env.PORT|| 3000 ; 
				var resetUrl = "http://" + req.headers.host + "/reset-password";

				forgotPasswordObj.findOne({
					email: req.body.email
				}, function(err, dataExist) {
					if (err) {
						return res.send(err);
					} else {
						if (dataExist) {

							var updating = {};
							updating = {
								"token": token,
								"expirationPeriod": moment(new Date()).add(1, 'days').format(),
								"tokenUsed": false,
								"createdOn": new Date(),
								"userType": data.userType
							};
							forgotPasswordObj.update({
								"email": req.body.email
							}, {
								$set: updating
							}, function(err, post) {
								if (err) {
									var response = {
										"status": 401,
										"message": err
									};
									return res.status(401).send(response);
								}

								if (post) {
									var response = {
										"status": 200,
										"messageText": "email link sent to " + data.email + " !"
									}
									var view = constantObj.emailTemplates.resetPassword;
									var frm = 'LineGuide app<noreply@kdlineguide.com>';
									var emailSubject = 'LineGuide App - Password reset link';

									findUserDetails(req, res, outputJSON, data, emailSubject, resetUrl, token, view, frm, response.messageText);


								}
							});
						} else {
							// console.log("if data not exist:++++++++++++++");
							var adding = new forgotPasswordObj({
								"userId": data._id,
								"email": data.email,
								"token": token,
								"expirationPeriod": moment(new Date()).add(1, 'days').format(),
								"tokenUsed": false,
								"createdOn": new Date(),
								"userType": data.userType
							});
							// console.log(" input gone for forgot password:",adding);
							adding.save(function(err, post) {
								if (err) {
									var response = {
										"status": 401,
										"message": err
									};
									return res.status(401).send(response);
								}

								if (post) {
									var response = {
										"status": 200,
										"messageText": "email link sent to " + data.email + " !"
									}
									var view = "resetPassword";
									var frm = 'LineGuide app<noreply@kdlineguide.com>';
									var emailSubject = 'LineGuide App - Password reset link';

									findUserDetails(req, res, outputJSON, data, emailSubject, resetUrl, token, view, frm, response.messageText);

								}
							});
						}
					}
				});
			}


		}
	});
}

/*
 |--------------------------------------------------------------------------
 | Generate JSON Web Token
 |--------------------------------------------------------------------------
 */
function createJWT(user) {
	var payload = {
		sub: user._id,
		iat: moment().unix(),
		exp: moment(new Date()).add(1, 'days').format()
	};
	// console.log("token", payload, constantObj.facebookCredentials.token_secret);
	return jwt.encode(payload, constantObj.jwtSecret);
}


// reset password from forgot password link email
exports.resetPassword = function(req, res) {
	console.log("in reset-password");
	if (!req.params.token) {
		return res.render('resetPassword.ejs', {
			token: req.params.token,
			message: req.flash(constantObj.messages.resetpasstokenmissing)
		});
	}
	if (!req.body.password) {
		return res.render('resetPassword.ejs', {
			token: req.params.token,
			message: req.flash(constantObj.messages.resetpasspasswordmissing)
		});
	}

	forgotPasswordObj.findOne({
			token: req.params.token
		},
		function(err, data) {

			console.log(" data ", data);

			if (err) {
				return res.render('resetPassword.ejs', {
					token: req.params.token,
					message: constantObj.messages.resetpasserror
				});

			} else {
				console.log("data:", data);
				if (!data) {
					return res.render('resetPassword.ejs', {
						token: req.params.token,
						message: constantObj.messages.resetTokenUnregErr
					});
				}
				if (data.tokenUsed == true) {
					return res.render('resetPassword.ejs', {
						token: req.params.token,
						message: constantObj.messages.resetpasstokenused
					});

				}
				// return false;
				if (moment(data.expirationPeriod).format() < moment().format()) { //if token expire

					forgotPasswordObj.remove({
						"token": req.body.token
					}, function(fgErr, fgData) {
						if (fgErr) {
							return res.render('resetPassword.ejs', {
								token: req.params.token,
								message: "Error Occurred"
							});
							return;
						} else {
							return res.render('resetPassword.ejs', {
								token: req.params.token,
								message: constantObj.messages.resetpasstokenexpire
							});


						}
					})
				} else { // If token is not expired
					var email = data.email;
					var salt = bcrypt.genSaltSync(10);
					var hashPassword = bcrypt.hashSync(req.body.password, salt);
					loginObj.update({
						email: email
					}, {
						$set: {
							"password": hashPassword
						}
					}, function(lgErr, lgData) {
						if (lgErr) {
							return res.render('resetPassword.ejs', {
								token: req.params.token,
								message: lgErr
							});

						}
						if (lgData) {
							// update token used status to true.
							forgotPasswordObj.update({
								email: email
							}, {
								$set: {
									"tokenUsed": true
								}
							}, function(err, data) {
								if (err) {
									return res.render('resetPassword.ejs', {
										token: req.params.token,
										message: constantObj.messages.resetpasstokenupdaterr
									});

								} else {

									req.flash('success', constantObj.messages.resetpasswordsuccess);
									res.redirect("/login");
								}
							})
						}
					})
				}
			}
		})
}


// Developer : RaJesh
exports.changePassword = function(req, res) {
	var body = _.pick(req.body, '_id', 'password', 'newpassword');
	var userId = req.user._id;
	if (!req.body.password) {
		return res.status(203).jsonp({
			'status': 203,
			'message': constantObj.messages.currentPasswordErr
		});
	}
	if (!req.body.newpassword) {
		return res.status(203).jsonp({
			'status': 203,
			'message': constantObj.messages.newpasswordErr
		});
	}

	var outputJSON = {};
	var updatePassword = {};
	updatePassword.password = body.newpassword;
	loginObj.findOne({
		_id: userId
	}, function(err, data) {
		if (err) {
			outputJSON = {
				'status': 203,
				'message': constantObj.messages.errorRetreivingData
			};
			return res.jsonp(outputJSON);
		} else {
			if (!isValidPassword(data.password, body.password)) {
				outputJSON = {
					'status': 203,
					'message': constantObj.messages.oldPasswordIncorrect
				};
				return res.status(203).jsonp(outputJSON);
			} else {

				var salt = bcrypt.genSaltSync(10);
				updatePassword.password = bcrypt.hashSync(body.newpassword, salt);

				loginObj.update({
					"_id": userId
				}, {
					$set: updatePassword
				}, function(err, result) {
					outputJSON = {
						'status': 200,
						'message': constantObj.messages.passwordChangedSuccess
					};
					return res.status(200).jsonp(outputJSON);
				});

			}

		}
	});
}

function sendResetLinkEmail(sendData, emailSubject, resetUrl, token, view, frm, req, res, messageText) {
	var userDetails = {};
	userDetails.email = sendData.email;
	userDetails.fullName = sendData.fullName;
	userDetails.appLink = resetUrl + "/" + token;
	// console.log(userDetails)
	var frm = 'LineGuide app<noreply@kdlineguide.com>';
	var emailSubject = 'LineGuide App - Password Reset Link';
	var emailTemplate = 'resetPassword';
	emailService.send(userDetails, emailSubject, resetUrl, token, view, frm, req, res, messageText);
}

function isValidPassword(userPassword, password) {
	return bcrypt.compareSync(password, userPassword);
}

exports.renderPages = function(req, res) {
	if (req.user) {
		var user = req.user;
		if (req.user.userType == constantObj.userTypes.superAdmin) {
			res.render('superAdmin.ejs', {
				user: JSON.stringify(user)

			})
		} else if (req.user.userType == constantObj.userTypes.admin) {
			req.logout();
			return res.render('login.ejs', {
				message: 'Not authorized to login as admin',
				success: ''
			});
		} else if (req.user.userType == constantObj.userTypes.masterInspector) {
			res.render('miTlc.ejs', {
				user: JSON.stringify(user)

			})
		} else if (req.user.userType == constantObj.userTypes.tlc || req.user.userType == constantObj.userTypes.lineman) {

			/* res.redirect('/login');*/
			var userType;
			if (req.user.userType == constantObj.userTypes.tlc) {
				userType = 'TLC.'
			}
			if (req.user.userType == constantObj.userTypes.lineman) {
				userType = 'Lineman.'
			}
			/*req.logout();*/
			/*return res.render('login.ejs', {
				message: 'Not authorized to login as ' + userType,
				success: ''
			});*/
			res.render('miTlc.ejs', {
				user: JSON.stringify(user)

			})
		} else if (req.user.userType == constantObj.userTypes.company) {
			return res.render('login.ejs', {
				message: 'Not authorized to login as company',
				success: ''
			});
		} else {
			req.logout();
			return res.render('login.ejs', {
				message: 'Unauthorized user type to login on web portal',
				success: ''
			});
		}

	} else {
		res.redirect('/login');
	}

}

exports.webLogout = function(req, res) {
	if (req.user) {
		userTokenObj.remove({
			token: req.user.myToken
		}, function(err, data) {
			if (err) {
				console.log("error in removing token:", err);
			}
			req.user = {};
			req.logout();
			res.redirect('/login');

		})

	} else {
		req.logout();
		res.redirect('/login');


	}

}
exports.appLogout = function(req, res) {
	var token = req.header('Authorization');
	var checkToken = token.split(' ');
	if (req.header('Authorization')) {
		userTokenObj.remove({
			token: checkToken[1]
		}, function(err, data) {
			if (err) {
				console.log("error in removing token:", err);
			}
			req.logout();
			res.status(200).jsonp({
				"status": 200,
				"message": "User successfully logged out."
			})
		})
	} else {
		req.logout();
		res.status(200).jsonp({
			"status": 200,
			"message": "User successfully logged out."
		})
	}
}

exports.renderResetPassPage = function(req, res) {
	if (req.isAuthenticated() && req.user) {
		res.redirect('/');
	} else {
		res.render('resetPassword.ejs', {
			token: req.params.token
		});
	}

}