const express = require('express');
const { body } = require('express-validator');
const { Op } = require('sequelize');
const { validation, isAuth } = require('../../../middlewares');
const { Users } = require('../../../models');
const {
	accountLogin,
	accountCreate,
	getUserById,
	editUserProfile,
	changePassword,
	deleteAccount,
	deactivation,
	getLanguage,
	updateLanguage,
	requestPasswordReset,
	resetPassword,
	resendPasswordResetEmail,
} = require('../../../controllers/users/accounts');
const { jsonParser, deleteFile } = require('../../../helpers');

const router = express.Router();

router.post('/login', [body('emailOrPhone').notEmpty(), body('password').notEmpty()], validation, accountLogin);

router.post(
	'/register',
	[
		body('emailAddress').notEmpty(),
		body('phoneNo').notEmpty(),
		body('firstname').notEmpty(),
		body('lastname').notEmpty(),
		body('password').notEmpty(),
		body('birthdate').optional(),
		body('addressCountry').isString().optional({
			values: 'falsy',
		}),
		body('addressStreet').isString().optional({
			values: 'falsy',
		}),
		body('addressApt').isString().optional({
			values: 'falsy',
		}),
		body('addressCity').isString().optional({
			values: 'falsy',
		}),
		body('addressState').isString().optional({
			values: 'falsy',
		}),
		body('addressZip').isString().optional({
			values: 'falsy',
		}),
	],
	validation,
	accountCreate,
);

router.get('/me', isAuth, getUserById);

router.patch(
	'/update-profile',
	isAuth,
	jsonParser,
	[
		body('data.firstName').optional(),
		body('data.lastName').optional(),
		body('data.phoneNo').optional(),
		body('data.emailAddress')
			.optional()
			.isEmail()
			.custom(async (value, { req }) => {
				if (!value) return Promise.resolve();
				const user = await Users.findOne({
					where: {
						email_address: value,
						id: { [Op.ne]: req.userId },
					},
				});
				if (user) {
					if (req.files && req.files.profileImg) {
						deleteFile(req.files.profileImg[0].filename, 'user-uploads');
					}
					return Promise.reject('Email Address already in use');
				}
			}),
		body('data.data.birthdate').optional(),
		body('data.addressCountry').isString().trim().notEmpty().optional(),
		body('data.addressStreet').isString().trim().notEmpty().optional(),
		body('data.addressApt').isString().trim().notEmpty().optional({
			values: 'falsy',
		}),
		body('data.addressCity').isString().trim().notEmpty().optional(),
		body('data.addressState').isString().trim().notEmpty().optional(),
		body('data.addressZip').isString().trim().notEmpty().optional(),
		body('data.aboutMe').optional(),
		body('data.school').optional(),
		body('data.work').optional(),
		body('data.music').optional({
			values: 'null',
		}),
		body('data.livedIn').optional({
			values: 'null',
		}),
		body('data.languages').isArray().optional({
			values: 'falsy',
		}),
		body('data.pets').optional({
			values: 'null',
		}),
		body('data.hangouts').optional({
			values: 'null',
		}),
		body('data.birthYear').optional({
			values: 'null',
		}),
		body('data.likes').optional({
			values: 'null',
		}),
		body('data.dislikes').optional({
			values: 'null',
		}),
		body('data.interests').isArray().optional({
			values: 'null',
		}),
		body('data.showTravels').optional().isBoolean(),
	],
	validation,
	async (req, res, next) => {
		try {
			const user = await Users.findByPk(req.userId);

			if (!user) {
				return res.status(404).json({ success: false, message: 'User not found' });
			}

			const previousProfileImage = user.image || null;

			await editUserProfile(req, res, next);

			if (req.files && req.files.profileImg && previousProfileImage) {
				deleteFile(previousProfileImage, 'user-uploads');
			}
		} catch (error) {
			return next(error);
		}
	},
	editUserProfile,
);

router.patch('/deactivate-account', isAuth, deactivation);

router.patch(
	'/change-password',
	isAuth,
	[
		body('currentPass').notEmpty().isString(),
		body('newPass').notEmpty().isString(),
		body('confirmPass')
			.notEmpty()
			.isString()
			.custom((value, { req }) => {
				if (value !== req.body.newPass) {
					throw new Error('Passwords do not match!');
				}
				return true;
			}),
	],
	validation,
	changePassword,
);

router.delete('/delete-account', [body('reason').isString().trim().notEmpty()], validation, isAuth, deleteAccount);

router.get('/language', isAuth, getLanguage);

router.patch('/language', isAuth, [body('language').isString().trim().notEmpty()], validation, updateLanguage);

router.post('/password-reset', [body('email').notEmpty()], validation, requestPasswordReset);

router.patch(
	'/password-reset',
	[body('newPass').notEmpty(), body('confirmPass').notEmpty()],
	validation,
	resetPassword,
);

router.post('/password-reset/resend', [body('email').notEmpty()], validation, resendPasswordResetEmail);

module.exports = router;
