text: const passport = require('passport')
  const bcrypt = require('bcryptjs')
  const SHA3 = require('crypto-js/sha3')
  const aes = require('../helpers/aes')
  const ObjectId = require('mongoose').Types.ObjectId
  const User = require('../models/user')
  const createError = require('http-errors')
  const { cookieOptions } = require('../helpers/cookie')
  
  module.exports = router => {
    router.put('/user', async (req, res, next) => {
      if (!req.user) {
        return next(createError(401))
      }
      const body = {
        username: req.body.username
      }
      User.updateOne({ _id: req.user._id }, { ...body }, async (err, response) => {
        if (err || !response.ok) {
          return next(createError(500))
        }
        passport.deserializeUser(req.user._id, (err, user) => {
          if (err) {
            return next(createError(500))
          }
          res.send(user)
        })
      })
    })
  
    router.post('/password', async (req, res, next) => {
      if (!req.body.currentPassword || !req.body.newPassword || !req.body.repeatPassword) {
        return next(createError(400))
      }
      const user = await User.findOne({ _id: req.user._id })
  
      bcrypt.compare(req.body.currentPassword, user.password, async (err, isEquals) => {
        if (err || !isEquals) {
          return next(createError(400, 'wrong_password'))
        }
        if (req.body.newPassword === req.body.currentPassword) {
          return next(createError(400, 'the_same_password'))
        }
        if (req.body.newPassword !== req.body.repeatPassword) {
          return next(createError(400, 'passwords_do_not_match'))
        }
  
        const hashedPassword = await bcrypt.hash(req.body.newPassword, 10)
        User.updateOne({ _id: ObjectId(req.user._id) }, {
          password: hashedPassword,
          passwordUpdated: new Date()
        }, (err, result) => {
          if (err || !result.nModified) {
            return next(createError(500))
          }
          res.send()
        })
      })
    })
  
    router.post('/set-security-code', async (req, res, next) => {
      if (!req.user) {
        return next(createError(401))
      }
  
      if (!req.body.securityCode) {
        return next(createError(400))
      }
  
      const hashedSecurityCode = await bcrypt.hash(req.body.securityCode, 10)
      const encryptedSecurityCode = SHA3(req.body.securityCode).toString()
  
      const decryptionValue = aes.encrypt(encryptedSecurityCode, 'decryptionValue')
  
      User.updateOne({ username: req.user.username }, {
        securityCode: hashedSecurityCode,
        hasSecurityCode: true,
        decryptionValue
      }, err => {
        if (err) throw err
  
        // cypher key setting to client
        res.cookie('decryption-key', encryptedSecurityCode, cookieOptions({ maxAge: 1000 * 60 * 60 })) // 1 hour
  
        res.send()
      })
    })
  
    router.post('/security-code', async (req, res, next) => {
      if (!req.body.currentCode || !req.body.newCode || !req.body.repeatCode) {
        return next(createError(400))
      }
      const user = await User.findOne({ _id: req.user._id })
  
      bcrypt.compare(req.body.currentCode, user.securityCode, async (err, isEquals) => {
        if (err || !isEquals) {
          return next(createError(403, 'wrong_security_code'))
        }
        if (req.body.newCode === req.body.currentCode) {
          return next(createError(400, 'the_same_security_code'))
        }
        if (req.body.newCode !== req.body.repeatCode) {
          return next(createError(400, 'codes_do_not_match'))
        }
  
        const hashedSecurityCode = await bcrypt.hash(req.body.newCode, 10)
        User.updateOne({ _id: ObjectId(req.user._id) }, {
          securityCode: hashedSecurityCode,
          securityCodeUpdated: new Date()
        }, (err, result) => {
          if (err || !result.nModified) {
            return next(createError(500))
          }
          res.send()
        })
      })
    })
  }
  