/// <summary>
        /// loads the page where users can check date availability for booking
        /// </summary>
        /// <param name="brochureId">ID of brochure selected by the user</param>
        /// <returns>CheckDate view</returns>
        public IActionResult CheckDate(int?brochureId)
        {
            //if user is not logged in, send to login screen
            if (!User.Identity.IsAuthenticated)
            {
                return(RedirectToAction(nameof(AccountController.Login), "Account"));
            }

            //if brochureId is null, redirect to browse brochures page
            if (brochureId == null)
            {
                return(RedirectToAction(nameof(BrochureController.Browse), "Brochure"));
            }

            //populate the model and inject into the page
            CheckDateViewModel model = new CheckDateViewModel
            {
                BrochureId    = (int)brochureId,
                DepartureDate = DateTime.Now.Date,
                ErrorMessage  = ""
            };

            return(View(model));
        }
        public async Task <IActionResult> CheckDate(CheckDateViewModel model)
        {
            //if date is in the past, reload page
            if (model.DepartureDate < DateTime.Now || model.DepartureDate == null)
            {
                model.ErrorMessage = "Date not allowed";
                return(View(model));
            }

            //get all the bookings from the database where it shares the same brochure
            var             bookings         = _context.Bookings.Where(b => b.BrochureId == model.BrochureId && b.Status.Equals("Completed")).Include(b => b.Brochure);
            List <DateTime> unavailableDates = new List <DateTime>();

            //store the dates for every booking
            foreach (var oldBooking in bookings)
            {
                //store departure date
                unavailableDates.Add(oldBooking.DepartureDate);

                //store the dates included in the duration after departure
                var duration   = oldBooking.Brochure.Duration;
                var daysBefore = duration - 1;

                while (duration > 0)
                {
                    unavailableDates.Add(oldBooking.DepartureDate.AddDays(duration));
                    duration--;
                }

                //store the dates included in the lead upto the departure so bookings dont overlap
                while (daysBefore > 0)
                {
                    unavailableDates.Add(oldBooking.DepartureDate.AddDays(-daysBefore));
                    daysBefore--;
                }
            }

            if (unavailableDates.Contains(model.DepartureDate))
            {
                model.ErrorMessage = "Date is already booked";
                return(View(model));
            }

            //get the brochure from the database
            Brochure brochure = await _context.Brochures.FindAsync(model.BrochureId);

            //check if user already has a booking in progress
            var userId      = this.User.FindFirstValue(ClaimTypes.NameIdentifier);
            var userResults = _context.Bookings.Where(b => b.UserId.Equals(userId)).Where(b => b.Status.Equals("IN_PROGRESS"));

            //remove booking from database if one exists
            if (await userResults.CountAsync() > 0)
            {
                foreach (var oldBooking in userResults)
                {
                    _context.Remove(oldBooking);
                }
            }

            //create a new booking
            Booking booking = new Booking
            {
                BrochureId          = model.BrochureId,
                Brochure            = await _context.Brochures.FindAsync(model.BrochureId),
                DepartureDate       = (DateTime)model.DepartureDate,
                PaymentType         = PaymentType.FULL,
                TotalPrice          = brochure.PricePerPerson,
                AmountPaid          = 0,
                SpecialRequirements = "",
                Status        = "IN_PROGRESS",
                UserId        = this.User.FindFirstValue(ClaimTypes.NameIdentifier),
                DateCompleted = DateTime.Now
            };

            //add booking to database
            _context.Bookings.Add(booking);
            await _context.SaveChangesAsync();

            //redirect to AddPeople action
            return(RedirectToAction("AddNumberOfPeople", "Person", new { bookingId = booking.BookingId }));
        }