/// <summary>
        /// Make a booking and take payment from a user.
        /// </summary>
        /// <param name="user">The user that is making the booking.</param>
        /// <param name="selectedFlights">The flight(s) the user is booking.</param>
        /// <param name="paymentInfo">The user's card details to pay for the flights.</param>
        /// <returns>An asynchronous task of MethodResult indicating whether the operation was successful or not.</returns>
        public async Task <MethodResult> MakeBookingAsync(User user, SelectedFlights selectedFlights, PaymentInfo paymentInfo)
        {
            decimal price = selectedFlights.Price;

            var paymentResult = await _paymentManager.TakePaymentAsync(paymentInfo, price);

            if (paymentResult.Succeeded == false)
            {
                return(MethodResult.Failed(paymentResult.Errors.ToArray()));
            }

            // Payment succeeded - create booking.
            Booking newBooking = new Booking
            {
                Last4CardDigits = paymentInfo.CardNumber.Substring(11, 4),
                CardType        = await _paymentManager.GetCardIssuerAsync(paymentInfo.CardNumber),
                DateTimeCreated = DateTime.Now,
                FlightsDetails  = selectedFlights
            };

            // Generate the booking reference.
            await GenerateBookingReferenceAsync(newBooking);

            // Crate booking in database.
            await _dataAccess.CreateBookingAsync(newBooking, user);

            // Send confirmation email.
            await SendBookingConfirmationAsync(user, newBooking);

            return(MethodResult.Success);
        }