const bcrypt = require('bcryptjs')
const jwt = require('jsonwebtoken')
const { body, validationResult } = require('express-validator')
const { secretKey } = require('../authentication')
const { _sr } = require('../plugins/serverResponses')
const { checkValidations } = require('../plugins/controllersHelperFunctions')
const UserGPS = require('../models/GPS.User')
const { generateRandomDigits } = require('../plugins/controllersHelperFunctions')
const sms = require('../plugins/SMS_Module')
module.exports.login_with_pass = [
  [
    body('username')
      .isLength({ min: 4 })
      .withMessage(_sr.fa.min_char.min4)
      .bail()
      .if((value, { req }) => {
        return req.body.password && req.body.password.length >= 4
      })
      .custom((value, { req }) => {
        return UserGPS.findOne({
          $or: [{ national_code: value }, { mobile_number: value }]
        }).then(user => {
          if (!user) return Promise.reject(_sr.fa.not_found.password)
          else return true
        })
      }),
    body('password')
      .notEmpty()
      .withMessage(_sr.fa.required.password)
      .bail()
      .isLength({ min: 4 })
      .withMessage(_sr.fa.min_char.min4),
    body('remember_me')
      .exists()
      .withMessage(_sr.fa.required.remember_me)
      .bail()
      .isBoolean()
      .withMessage(_sr.fa.format.boolean)
  ],
  checkValidations(validationResult),
  async (req, res) => {
    try {
      const { username, password } = req.body
      const user = await UserGPS.findOne({
        $or: [{ national_code: username }, { mobile_number: username }]
      })
      if (!user) throw new Error(_sr.fa.not_found.password)
      const passwordMatch = await bcrypt.compare(password, user.password)
      if (!passwordMatch) throw new Error(_sr.fa.not_found.password)
      if (!user.active) {
        throw new Error('حساب شما هنوز تاییده نشده است')
      }
      const token = await jwt.sign({ _id: user._id }, secretKey, {
        expiresIn: req.body.remember_me ? '30d' : '7d'
      })
      // eslint-disable-next-line eqeqeq
      if (user?.lastIP && user?.lastIP != req.ip) {
        await sms.auth.deviceLogin(user.mobile_number, req.ip)
      }
      user.lastIP = req.ip
      user.token = token
      await user.save()
      return res.status(200).json({ token })
    } catch (err) {
      return res.status(422).json({
        validation: { username: { msg: err.message } }
      })
    }
  }
]

module.exports.login_with_otp = [
  [
    body('mobile_number').notEmpty().withMessage(_sr.fa.required.phone_number),
    body('otp').notEmpty().withMessage(_sr.fa.required.phone_number)
  ],
  checkValidations(validationResult),
  async (req, res) => {
    try {
      const { mobile_number, otp } = req.body
      const user = await UserGPS.findOne({ mobile_number })
      if (!user) throw new Error(_sr.fa.not_found.user_id)
      if (user.otp !== otp) throw new Error('کد اشتباه است')
      if (user.otp === otp) {
        if (!user.active) {
          throw new Error('حساب شما هنوز تاییده نشده است')
        }
        const token = await jwt.sign({ _id: user._id }, secretKey, {
          expiresIn: req.body.remember_me ? '30d' : '7d'
        })
        // eslint-disable-next-line eqeqeq
        if (user?.lastIP && user?.lastIP != req.ip) {
          await sms.auth.deviceLogin(user.mobile_number, req.ip)
        }
        user.otp = generateRandomDigits(6)
        user.lastIP = req.ip
        user.token = token
        user.save()
        return res.status(200).json({ token })
      }
    } catch (err) {
      return res.status(422).json({
        validation: { otp: { msg: err.message } }
      })
    }
  }
]
