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

const Notification = require('../../notifications/notification')

module.exports = models => async (req, res) => {
  const { collectionId, fragmentId, recommendationId } = req.params
  const userId = req.user
  let collection, fragment
  try {
    collection = await models.Collection.find(collectionId)
    if (!collection.fragments.includes(fragmentId))
      return res.status(400).json({
        error: `Collection and fragment do not match.`,
      })

    fragment = await models.Fragment.find(fragmentId)

    const recommendation = fragment.recommendations.find(
      rec => rec.id === recommendationId,
    )

    if (!recommendation)
      return res.status(404).json({ error: 'Recommendation not found.' })

    if (recommendation.userId !== userId)
      return res.status(403).json({
        error: 'Unauthorized.',
      })

    const authsome = authsomeHelper.getAuthsome(models)
    const target = {
      fragment,
      path: req.route.path,
    }
    const canPatch = await authsome.can(userId, 'PATCH', target)
    if (!canPatch)
      return res.status(403).json({
        error: 'Unauthorized.',
      })

    const UserModel = models.User
    const reviewer = await UserModel.find(userId)

    Object.assign(recommendation, req.body)
    recommendation.updatedOn = Date.now()

    if (req.body.submittedOn) {
      const notification = new Notification({
        fragment,
        UserModel,
        collection,
        baseUrl: services.getBaseUrl(req),
        newRecommendation: recommendation,
      })

      notification.notifyHEWhenReviewerSubmitsReport(reviewer.lastName)

      if (['underReview'].includes(collection.status)) {
        const collectionHelper = new Collection({ collection })
        collectionHelper.updateStatus({ newStatus: 'reviewCompleted' })
      }

      const collectionHelper = new Collection({ collection })
      const FragmentModel = models.Fragment
      const reviewerNumber = await collectionHelper.getReviewerNumber({
        userId: req.authInfo.id,
        FragmentModel,
      })
      find(fragment.invitations, [
        'userId',
        userId,
      ]).reviewerNumber = reviewerNumber
    }

    fragment.save()

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