import { Request, Response, NextFunction } from 'express'
import { validate } from 'super-easy-validator'
import constants from '../../utils/constants'

function getUsers(req: Request, res: Response, next: NextFunction) {
	try {
		const rules = {
			limit: 'optional|string|natural',
			page: 'optional|string|natural',
			search: 'optional|string',
			categories: 'optional|string'
		}

		const { errors } = validate(rules, req.query)
		if (errors) {
			return res.status(400).json({ message: errors[0] })
		}

		return next()
	} catch (error) {
		console.log(error)
		return res.status(500).json({ message: 'server error' })
	}
}

function getExploreUsersAndChats(req: Request, res: Response, next: NextFunction) {
	try {
		const rules = {
			limit: 'optional|string|natural',
			search: 'required|string|min:3',
		}

		const { errors } = validate(rules, req.query)
		if (errors) {
			return res.status(400).json({ message: errors[0] })
		}

		return next()
	} catch (error) {
		console.log(error)
		return res.status(500).json({ message: 'server error' })
	}
}

function getMeetmeOnlineUsers(req: Request, res: Response, next: NextFunction) {
	try {
		const rules = {
			limit: 'optional|string|natural',
			page: 'optional|string|natural'
		}

		const { errors } = validate(rules, req.query)
		if (errors) {
			return res.status(400).json({ message: errors[0] })
		}

		return next()
	} catch (error) {
		console.log(error)
		return res.status(500).json({ message: 'server error' })
	}
}

function getUser(req: Request, res: Response, next: NextFunction) {
	try {
		const rules = {
			id: 'mongoid'
		}

		const { errors } = validate(rules, req.params)
		if (errors) {
			return res.status(400).json({ message: errors[0] })
		}

		return next()
	} catch (error) {
		console.log(error)
		return res.status(500).json({ message: 'server error' })
	}
}

function patchUser(req: Request, res: Response, next: NextFunction) {
	try {
		const rules = {
			name: 'optional|string|min:3|max:20',
			username: `optional|${constants.usernameRegex}`,
			bio: 'optional|string|min:5|max:200',
			url: 'optional|nullable|url',
			school: 'optional|string|min:3|max:300',
			courses: 'optional|string|min:5|max:300',
			dob: 'optional|dateonly',
			phone: `optional|${constants.phoneRegex}`,
			twoFactorAuthentication: 'optional|boolean',
			password: 'optional|string|min:8|max:16',
			oldPassword: 'optional|string|min:8|max:16',
			purposes: 'optional|arrayof:object|min:1',
			studies: 'optional|arrayof:object|min:1',
			categories: 'optional|arrayof:string|arrayof:min:3',
			isManuallyOffline: 'optional|boolean',
			platform: 'optional|string|enums:android,ios,web',
			fcmToken: 'optional|string|min:50|max:300',
			locationString: 'optional|string|min:3|max:100',
			latitude: 'optional|number|min:-90|max:90',
			longitude: 'optional|number|min:-180|max:180',
		}

		const { errors } = validate(rules, req.body)
		if (errors) {
			return res.status(400).json({ message: errors[0] })
		}

		const {password, oldPassword, purposes, studies} = req.body
		if(password && !oldPassword) {
			return res.status(400).json({message: 'oldPassword is also required'})
		}

		if (purposes) {
			for (let i = 0; i < purposes.length; i++) {
				const rules = {
					type: `string|enums:short-term,long-term|field:purposes[${i}].type`,
					value: `arrayof:string|min:1|arrayof:min:3|field:purposes[${i}].value`
				}
				const { errors } = validate(rules, req.body.purposes[i])
				if (errors) {
					return res.status(400).json({ message: errors[0] })
				}
			}
		}

		if (studies) {
			for (let i = 0; i < studies.length; i++) {
				const rules = {
					type: `string|min:3|field:studies[${i}].type`,
					value: `arrayof:string|min:1|arrayof:min:3|field:studies[${i}].value`
				}
				const { errors } = validate(rules, req.body.studies[i])
				if (errors) {
					return res.status(400).json({ message: errors[0] })
				}
			}
		}

		return next()
	} catch (error) {
		console.log(error)
		return res.status(500).json({ message: 'server error' })
	}
}

function postCheckUsername(req: Request, res: Response, next: NextFunction) {
	try {
		const rules = {
			username: `optional|${constants.usernameRegex}`,
		}

		const { errors } = validate(rules, req.body)
		if (errors) {
			return res.status(400).json({ message: errors[0] })
		}

		return next()
	} catch (error) {
		console.log(error)
		return res.status(500).json({ message: 'server error' })
	}
}

function putProfilePhoto(req: Request, res: Response, next: NextFunction) {
	try {
		if (!req.file) {
			return res.status(400).json({ message: 'photo is required' })
		}
		return next()
	} catch (error) {
		console.log(error)
		return res.status(500).json({ message: 'server error' })
	}
}

const validations = {
	getUsers,
	getExploreUsersAndChats,
	getMeetmeOnlineUsers,
	getUser,
	patchUser,
	postCheckUsername,
	putProfilePhoto
}

export default validations
