// Zależności
import { AuthenticationError } from 'apollo-server'

// Narzędzia
import { encrypt, isPasswordMatch } from '@contentpi/lib'

// Interfejs
import { IUser, IModels, IAuthPayload } from '../types'

// JWT
import { createToken } from './jwt'

export const getUserBy = async (
  where: any,
  models: IModels
): Promise<IUser> => {
  // Użytkownik znajdowany jest na podstawie warunku WHERE
  const user = await models.User.findOne({
    where,
    raw: true
  })

  return user
}

export const doLogin = async (
  email: string,
  password: string,
  models: IModels
): Promise<IAuthPayload> => {
  // Znajdowanie użytkownika za pomocą adresu e-mail
  const user = await getUserBy({ email }, models)

  // Jeśli użytkownik nie istnieje, zwracany jest komunikat Niepoprawne logowanie.
  if (!user) {
    throw new AuthenticationError('Niepoprawne logowanie.')
  }

  // Sprawdzanie, czy zaszyfrowane hasło jest takie samo jak wartość user.password
  const passwordMatch = isPasswordMatch(encrypt(password), user.password)

  // Sprawdzanie, czy użytkownik jest aktywny
  const isActive = user.active

  // Jeśli hasło nie jest zgodne, zwracany jest komunikat Niepoprawne logowanie.
  if (!passwordMatch) {
    throw new AuthenticationError('Niepoprawne logowanie.')
  }

  // Jeśli konto nie jest aktywne, zwracany jest błąd
  if (!isActive) {
    throw new AuthenticationError('Konto nie zostało jeszcze aktywowane.')
  }

  // Jeśli użytkownik istnieje, hasło jest poprawne, a konto aktywne, tworzony jest token JWT

  const [token] = await createToken(user)

  // Na koniec zwracany jest token do kodu języka GraphQL
  return {
    token
  }
}
