package com.eddsteel.posts.leastpower
package endpoints

import model._
import services._
import webapp.{Request, Response, NotFoundException}

import scala.concurrent.{ExecutionContext, Future}
import scala.util.Try
import java.time.LocalDate

/** Endpoints for our Web app.
 *
 *  The important feature: given a user ID, will order that user a gift
 *  if it's their birthday.
 *
 */
trait EndpointsV1 {
  this: UserServiceComponent with GiftServiceComponent =>
  import EndpointsV1._

  def postGift(req: Request)(implicit ec: ExecutionContext): Future[Response] = {
    val response = for {
      // extract ID from request path
      userId <- Future.fromTry(WebApp.extractAndValidateUserId(req))
      // retrieve the user
      maybeUser <- userService.getById(userId)
      // bail with 404 if we have no user.
      user = maybeUser.getOrElse(throw NotFoundException(userId))
      // check if it's the user's birthday
      isBirthday = isToday(user.birthday)
      // call gift service if necessary
      gift <- if (isBirthday) giftService.order(userId, user.favoriteThing)
              else Future.successful(("not today", None))
      // build success response
      response <- Future.fromTry(WebApp.mkResponse(gift))
    } yield response

    // build error response
    response.recover(WebApp.mkErrorResponse)
  }
}

object EndpointsV1 {
  private def isToday(birthday: LocalDate): Boolean = {
    // using this utility helps us write tests.
    val today = DateTimeUtils.now.toLocalDate

    today.getDayOfMonth == birthday.getDayOfMonth &&
    today.getMonth == birthday.getMonth
  }

}