<?php

namespace AppBundle\Validator\Constraints;

use AppBundle\Entity\FewoBookingRequest;
use AppBundle\Entity\FewoReservation;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use AppBundle\Validator\Constraints;

/**
 * Class FewoReservationValidator
 * @package AppBundle\Validator
 */
class FewoBookingRequestValidator extends ConstraintValidator
{

    private function withinDates($date, $fromDate, $toDate)
    {
        $result = false;
        if($date >= $fromDate && $date <= $toDate)
        {
            $result = true;
        }
        return $result;
    }

    private function alreadyReserved($fromDate, $toDate, $reservationFromDate, $reservationToDate)
    {
        $result = true;

        if($fromDate >= $reservationToDate || $toDate <= $reservationFromDate)
        {
            $result = false;
        }

        return $result;
    }


    /**
     * Checks if the passed value is valid.
     *
     * @param FewoBookingRequest $bookingRequest The value that should be validated
     * @param Constraint $constraint The constraint for the validation
     */
    public function validate($bookingRequest, Constraint $constraint)
    {
        $fromDate = $bookingRequest->getFromDate();
        $toDate = $bookingRequest->getToDate();

        $lodging = $bookingRequest->getLodging();
        $price = $bookingRequest->getPrice();
        $season = $price->getSeason();
        $reservations = $lodging->getReservations();

        $timeDiff = date_diff($fromDate, $toDate);
        $numberDays = $timeDiff->days;

        $withinSeason = false;
        $alreadyReserved = false;

        if($fromDate >= $season->getFromDate()
            && $toDate <= $season->getToDate())
        {
            $withinSeason = true;
        }

        /** @var FewoReservation $reservation */
        foreach($reservations as $reservation)
        {
            $reservationFromDate = $reservation->getFromDate();
            $reservationToDate = $reservation->getToDate();


            if($this->alreadyReserved($fromDate, $toDate, $reservationFromDate, $reservationToDate))
            {
                $alreadyReserved = true;
            }

        }

        if(!$withinSeason)
        {
            $this->context->buildViolation("Zeitraum außerhalb der Saison!")
                ->addViolation();
        }

        if($alreadyReserved)
        {
            $this->context->buildViolation("Es gibt bereits Reservierungen innerhalb des gewünschten Zeitraums!")
                ->addViolation();
        }

        if($numberDays < $season->getMinimumStay())
        {
            $this->context->buildViolation("Mindestanzahl an Nächten nicht erreicht!")
                ->addViolation();
        }

        if($bookingRequest->getTravelerCount() > $lodging->getMaximumPersons())
        {
            $this->context->buildViolation("Anzahl der Reisenden übersteigt die maximale Personenanzahl!")
                ->addViolation();
        }
    }
}