const logger = require('@pubsweet/logger')

const {
  Team,
  services,
  Collection,
  Invitation,
  authsome: authsomeHelper,
} = require('pubsweet-component-helper-service')

const notifications = require('./emails/notifications')

module.exports = models => async (req, res) => {
  const { email, role } = req.body

  if (!services.checkForUndefinedParams(email, role))
    return res.status(400).json({ error: 'Email and role are required' })

  if (role !== 'handlingEditor')
    return res.status(400).json({
      error: `Role ${role} is invalid. Only handlingEditor is allowed.`,
    })

  const reqUser = await models.User.find(req.user)

  if (email === reqUser.email && !reqUser.admin) {
    logger.error(`${reqUser.email} tried to invite his own email`)
    return res.status(400).json({ error: 'Cannot invite yourself.' })
  }

  const { collectionId } = req.params
  let collection
  try {
    collection = await models.Collection.find(collectionId)
  } catch (e) {
    const notFoundError = await services.handleNotFoundError(e, 'Collection')
    return res.status(notFoundError.status).json({
      error: notFoundError.message,
    })
  }

  const authsome = authsomeHelper.getAuthsome(models)
  const target = {
    collection,
    path: req.route.path,
  }
  const canPost = await authsome.can(req.user, 'POST', target)
  if (!canPost)
    return res.status(403).json({
      error: 'Unauthorized.',
    })

  if (!['submitted', 'heInvited'].includes(collection.status)) {
    return res.status(400).json({
      error: `Cannot invite HE while collection is in the status: ${
        collection.status
      }.`,
    })
  }
  const collectionHelper = new Collection({ collection })

  const teamHelper = new Team({
    TeamModel: models.Team,
    collectionId,
  })
  const invitationHelper = new Invitation({ role })

  try {
    const user = await models.User.findByEmail(email)
    invitationHelper.userId = user.id
    let invitation = invitationHelper.getInvitation({
      invitations: collection.invitations,
    })

    if (invitation) {
      if (invitation.hasAnswer)
        return res
          .status(400)
          .json({ error: 'User has already replied to a previous invitation.' })
      invitation.invitedOn = Date.now()
      await collection.save()
    } else {
      invitation = await invitationHelper.createInvitation({
        parentObject: collection,
      })
    }

    invitation.invitedOn = Date.now()
    await teamHelper.setupTeam({ user, role, objectType: 'collection' })
    await collection.save()
    await collectionHelper.addHandlingEditor({ user, invitation })

    notifications.sendInvitedHEEmail({
      models,
      collection,
      invitedHE: user,
      baseUrl: services.getBaseUrl(req),
    })

    return res.status(200).json(invitation)
  } catch (e) {
    const notFoundError = await services.handleNotFoundError(e, 'User')
    return res.status(notFoundError.status).json({
      error: notFoundError.message,
    })
  }
}