const Admin = require('../models/admin/Admin')
const {body, validationResult} = require('express-validator')
const dateformat = require('dateformat')
const bcrypt = require('bcryptjs')
const jwt = require('jsonwebtoken')
const config = require('../config')
const v_m = require('../validation_messages')

/////////////////////////////////////////////////////////////////////// register
module.exports.register = [
   [
      body('name')
         .isLength({min: 2}).withMessage(v_m['fa'].min_char.min2),

      body('username')
         .isLength({min: 4}).withMessage(v_m['fa'].min_char.min4)
         .custom((value, {req}) => {
            return Admin.findOne({username: value})
               .then(admin => {
                  if (admin && admin.username === value) return Promise.reject(v_m['fa'].duplicated.username)
                  else return true
               })
         }),

      body('password')
         .isLength({min: 4}).withMessage(v_m['fa'].min_char.min4)
         .custom((value, {req}) => {
            if (value === req.body.password_confirmation) return true
            else return Promise.reject(v_m['fa'].response.passwords_not_match)
         })
   ],
   (req, res) => {
      const errors = validationResult(req)
      if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})

      const data = {}
      data.name = req.body.name
      data.username = req.body.username
      data.created_at = dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')

      bcrypt.genSalt(10, (err, salt) => {
         bcrypt.hash(req.body.password, salt, (err, hash) => {
            if (err) console.log(err)
            data.password = hash

            const admin = new Admin(data)
            admin.save(err => {
               if (err) console.log(err)
               return res.json({message: v_m['fa'].response.success_save})
            })
         })
      })

   }
]

/////////////////////////////////////////////////////////////////////// login
module.exports.login = [
   [
      body('username')
         .isLength({min: 4}).withMessage(v_m['fa'].min_char.min4)
         .bail()
         .if((value, {req}) => {
            return req.body.password && req.body.password.length >= 4
         })
         .custom((value, {req}) => {
            return Admin.findOne({username: value})
               .then(admin => {
                  if (!admin) return Promise.reject(v_m['fa'].not_found.admin_id)
                  else return true
               })
         }),

      body('password')
         .notEmpty().withMessage(v_m['fa'].required.password)
         .bail()
         .isLength({min: 4}).withMessage(v_m['fa'].min_char.min4),

      body('remember_me')
         .exists().withMessage(v_m['fa'].required.remember_me)
         .bail()
         .isBoolean().withMessage('مقدار باید از جنس Boolean باشد.')
   ],
   (req, res) => {
      const errors = validationResult(req)
      if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})

      Admin.findOne({username: req.body.username}, (err, user) => {
         if (err) console.log(err)
         bcrypt.compare(req.body.password, user.password, (err, isMatch) => {
            if (err) console.log(err)
            if (!isMatch) return res.status(422).json({validation: {password: {msg: v_m['fa'].not_found.password}}})

            let token
            if (req.body.remember_me) token = jwt.sign({_id: user._id}, config.secretKey)
            else token = jwt.sign({_id: user._id}, config.secretKey, {expiresIn: '1h'})

            user.token = token
            user.save(err => {
               if (err) console.log(err)
               return res.json({token: token})
            })
         })
      })
   }
]

/////////////////////////////////////////////////////////////////////// logout
module.exports.logout = [
   (req, res) => {
      const token = req.headers.authorization
      if (token) {
         Admin.findOneAndUpdate({token: token}, {token: null}, (err, oldData) => {
            if (err) console.log(err)
            if (oldData) return res.json({message: v_m['fa'].response.logged_out})
            return res.status(401).json({message: v_m['fa'].response.not_logged_in})
         })
      } else {
         return res.status(401).json({message: v_m['fa'].response.not_logged_in})
      }
   }
]

/////////////////////////////////////////////////////////////////////// get user
module.exports.getUser = [
   config.isAdmin,
   (req, res) => {
      const token = req.headers.authorization
      if (token) {
         jwt.verify(token, config.secretKey, (err, decoded) => {
            if (err) return res.status(401).json({message: 'unauthenticated'})
            Admin.findById(decoded._id, (err, data) => {
               if (err) console.log(err)
               return res.json({user: data})
            })
         })
      } else {
         return res.status(401).json({message: 'unauthenticated'})
      }
   }
]

/////////////////////////////////////////////////////////////////////// delete
