text: const mongoose = require("mongoose");
  const validator = require("validator");
  const bcrypt = require("bcryptjs");
  const jwt = require("jsonwebtoken");
  
  const userSchema = new mongoose.Schema(
    {
      name: {
        type: String,
        required: true,
        trim: true,
      },
      username: {
        type: String,
        required: true,
        trim: true,
        unique: true
      },
      // email: {
      //   type: String,
      //   required: true,
      //   unique: true,
      //   trim: true,
      //   lowercase: true,
      //   validate(value) {
      //     if (!validator.isEmail(value)) throw new Error("Invalid Email");
      //   },
      // },
      password: {
        type: String,
        required: true,
        minlength: 6,
        trim: true,
        validate(value) {
          if (value.toLowerCase().includes("password")) throw new Error("Password can't contain 'password'");
        },
      },
      tokens: [
        {
          token: {
            type: String,
            required: true,
          },
        },
      ],
    },
    {
      timestamps: true,
    }
  );
  
  // Functions which runs whenever user object is stringified
  userSchema.methods.toJSON = function () {
    const user = this;
    const userObj = user.toObject();
  
    delete userObj.password;
    delete userObj.tokens;
  
    return userObj;
  };
  
  // Generate a new JWT
  userSchema.methods.generateAuthToken = async function () {
    const user = this;
    const token = jwt.sign({ _id: user._id.toString() }, "thisisjwt");
  
    user.tokens = user.tokens.concat({ token });
    await user.save();
  
    return token;
  };
  
  // Verifying the User Credentials
  userSchema.statics.findByCredentials = async (username, password) => {
    const user = await User.findOne({ username });
  
    if (!user)
      throw new Error();
  
    const isMatch = await bcrypt.compare(password, user.password);
  
    if (!isMatch)
      throw new Error();
  
    return user;
  };
  
  // Hashing the plain text password before storing it
  userSchema.pre("save", async function (next) {
    // Using a standard function because arrow functions don't work well with 'this' bindings
    const user = this;
  
    if (user.isModified("password")) user.password = await bcrypt.hash(user.password, 8);
  
    next();
  });
  
  const User = mongoose.model("User", userSchema);
  
  module.exports = User;
  