const { Router } = require('express')
const hash = require('pbkdf2-password')()
const { promisify } = require('node:util')
const jwt = require('jsonwebtoken')

const { getAnswer } = require('../../utils/common')

const { SmokeAuthModel } = require('./model/auth')
const { SmokeUserModel } = require('./model/user')
const { SMOKE_TRACKER_TOKEN_KEY } = require('./const')
const { requiredValidate } = require('./utils')

const router = Router()

router.post(
  '/signup',
  requiredValidate('login', 'password'),
  async (req, res, next) => {
    const { login, password } = req.body

    const existing = await SmokeAuthModel.findOne({ login })

    if (existing) {
      throw new Error('Пользователь с таким логином уже существует')
    }

    hash({ password }, async function (err, pass, salt, hashValue) {
      if (err) return next(err)

      const user = await SmokeUserModel.create({ login })
      await SmokeAuthModel.create({ login, hash: hashValue, salt, userId: user.id })

      res.json(getAnswer(null, { ok: true }))
    })
  }
)

function authenticate(login, pass, cb) {
  SmokeAuthModel.findOne({ login })
    .populate('userId')
    .exec()
    .then((user) => {
      if (!user) return cb(null, null)

      hash({ password: pass, salt: user.salt }, function (err, pass, salt, hashValue) {
        if (err) return cb(err)
        if (hashValue === user.hash) return cb(null, user)
        cb(null, null)
      })
    })
    .catch((err) => cb(err))
}

const auth = promisify(authenticate)

router.post(
  '/signin',
  requiredValidate('login', 'password'),
  async (req, res) => {
    const { login, password } = req.body

    const user = await auth(login, password)

    if (!user) {
      throw new Error('Неверный логин или пароль')
    }

    const accessToken = jwt.sign(
      {
        ...JSON.parse(JSON.stringify(user.userId)),
      },
      SMOKE_TRACKER_TOKEN_KEY,
      {
        expiresIn: '12h',
      }
    )

    res.json(
      getAnswer(null, {
        user: user.userId,
        token: accessToken,
      })
    )
  }
)

module.exports = router


