text: const mongoose = require('mongoose')
  const validator = require('validator')
  const bcrpt = require('bcrypt')
  const jwt = require('jsonwebtoken')
  const Task = require('./task')
  
  const userSchema = new mongoose.Schema(
  	{
  		name: {
  			type: String,
  			required: true,
  			trim: true,
  		},
  		age: {
  			type: Number,
  			default: 0,
  			validate(value) {
  				if (value < 0) {
  					throw new Error('Age must be a positive number')
  				}
  			},
  		},
  		email: {
  			type: String,
  			unique: true,
  			required: true,
  			trim: true,
  			lowercase: true,
  			validate(value) {
  				if (!validator.isEmail(value)) {
  					throw new Error('Email is invalid')
  				}
  			},
  		},
  		password: {
  			type: String,
  			required: true,
  			minlength: 7,
  			trim: true,
  			validate(value) {
  				if (validator.contains(value.toLowerCase(), 'password')) {
  					throw new Error('Password cannnot contain the word "password"')
  				}
  			},
  		},
  		tokens: [
  			{
  				token: {
  					type: String,
  					required: true,
  				},
  			},
  		],
  		avatar: {
  			type: Buffer,
  		},
  	},
  	{
  		timestamps: true,
  	}
  )
  
  userSchema.virtual('tasks', {
  	ref: 'Task',
  	localField: '_id',
  	foreignField: 'owner',
  })
  
  userSchema.methods.toJSON = function () {
  	const user = this
  	const userObject = user.toObject()
  
  	delete userObject.password
  	delete userObject.tokens
  	delete userObject.avatar
  
  	return userObject
  }
  
  userSchema.methods.generateAuthToken = async function () {
  	const user = this
  	const token = jwt.sign({ _id: user._id.toString() }, process.env.JWT_SECRET)
  	user.tokens = user.tokens.concat({ token })
  	await user.save()
  	return token
  }
  
  userSchema.statics.findByCredentials = async (email, password) => {
  	const user = await User.findOne({ email })
  
  	if (!user) {
  		throw new Error('Unable to login')
  	}
  
  	const isMatch = await bcrpt.compare(password, user.password)
  
  	if (!isMatch) {
  		throw new Error('Unable to login')
  	}
  
  	return user
  }
  
  // uses regular fuction for binding
  // Hash the plain password before saving
  userSchema.pre('save', async function (next) {
  	const user = this
  	if (user.isDirectModified('password')) {
  		user.password = await bcrpt.hash(user.password, 8)
  	}
  	next()
  })
  
  // Delete user tasks when user is removed
  
  userSchema.pre('remove', async function (next) {
  	const user = this
  	await Task.deleteMany({ owner: user._id })
  	next()
  })
  const User = mongoose.model('User', userSchema)
  
  module.exports = User
  