/// <summary>
        /// Get template of the confirm booking time message
        /// </summary>
        /// <param name="specialistDto"></param>
        /// <returns></returns>
        protected string GetBookingConfirmMessage(UserDto specialistDto, BookingType type, SpecializationDto specializationDto, DateTime startTime, DateTime endTime)
        {
            decimal bookingRate = Services.Booking.GetCustomerPrice(specializationDto.Id, type);
            decimal minCharge = Services.Booking.GetCustomerMinimumPrice(specializationDto.Id);

            string confirmMessage = string.Empty;
            switch (type)
            {
                case BookingType.ASAP:
                    confirmMessage = BuildConfirmMessage("a consultation as soon as possible", specialistDto, bookingRate, minCharge, specializationDto.IsApplyNoMinimumCharge);
                    break;

                case BookingType.StandardHour:
                    confirmMessage = BuildConfirmMessage("a consultation between " + startTime.ToString(Constants.GlobalDateTimeFormat) +
                        " and " + endTime.ToString(Constants.GlobalDateTimeFormat), specialistDto, bookingRate, minCharge, specializationDto.IsApplyNoMinimumCharge);
                    break;

                case BookingType.OutOfHour:
                    confirmMessage = BuildConfirmMessage("a consultation between " + startTime.ToString(Constants.GlobalDateTimeFormat) +
                        " and " + endTime.ToString(Constants.GlobalDateTimeFormat), specialistDto, bookingRate, minCharge, specializationDto.IsApplyNoMinimumCharge);
                    break;

                case BookingType.TalkNow:
                    confirmMessage = BuildConfirmMessage("to talk now", specialistDto, bookingRate, minCharge, specializationDto.IsApplyNoMinimumCharge);
                    break;
            }

            return confirmMessage;
        }
        public IHttpActionResult TalkNow(TalkNowApi model)
        {
            var twiMLUrl = string.Empty;
            bool status = false;
            var booking = new BookingDto();

            try
            {
                // Get Customer and Specialist
                var customer = Services.Users.GetUserById(model.CustomerId);
                var specialist = Services.Users.GetUserById(model.SpecialistId);
                var customerPricing = Services.Booking.GetCustomerPricing(specialist.Profile.Specializations.FirstOrDefault().Id);

                var minimumBookingTime = (int)Services.SystemConfig.GetValueByKey(ParamatricBusinessRules.MINIMUM_BOOKING.ToString());
                var minimumCost = minimumBookingTime * customerPricing.TalkNow;
                var limitAmount = customerPricing.IsApplyNoMinimumCharge ?
                         minimumCost : minimumCost > customerPricing.Minimum ? customerPricing.Minimum : minimumCost;

                // Log
                Log.Info(string.Format("TalkNowApi. CustomerId: {0} Limit amount: {1} Customer prepayment amount: {2}", customer.Id, limitAmount, customer.PrePaymentAmount));

                if (model.IsTalkNow) // If talk now
                {
                    // Check call in progress
                    var callInProgress = Services.Call.GetCallInProgressByCallerId(model.CustomerId);

                    if (callInProgress == null)
                    {
                        // If payment menthod is prepayment => Compare customer amount prepayment with customerPricing.Minimum
                        // If payment menthod is credit card => If charge success
                        switch (customer.PaymentMethod)
                        {
                            case PaymentMethod.CreditCard:
                                var result = Services.Payment.Authorization(CurrentUser.Id.ToString(), limitAmount);
                                if (!result.Success)
                                {
                                    return Json(new { Success = false, Error = CallMessage.BalanceIsExpire });
                                }
                                else
                                {
                                    Services.Payment.Void(result.Transaction.Id);
                                }
                                break;

                            default:
                                if (customer.PrePaymentAmount <= limitAmount)
                                {
                                    return Json(new { Success = false, Error = CallMessage.BalanceIsExpire });
                                }
                                break;
                        }

                        // If customer prepayment amount <= minimum cost => Notify for customer
                        if (customer.PrePaymentAmount <= minimumCost && PaymentMethod.PrePayment.Equals(customer.PaymentMethod))
                        {
                            CallHelper.NotifyBalanceCloseToExpiring(customer.UserName);
                        }

                        // Get specialization
                        SpecializationDto specialization = new SpecializationDto();

                        if (specialist.Profile.Specializations != null
                            && specialist.Profile.Specializations.Count > 0)
                        {
                            specialization = new SpecializationDto()
                            {
                                Id = specialist.Profile.Specializations[0].Id
                            };
                        }

                        // Save to database;
                        booking = Services.Booking.Create(new BookingDto
                        {
                            Customer = customer,
                            Specialist = specialist,
                            Enquiry = model.Enquiry,
                            CostPerMinute = customerPricing.TalkNow,
                            RatePerMinute = specialist.Profile.Specializations.FirstOrDefault().TalkNowRate,
                            SpecialistMinCharge = specialist.Profile.Specializations.FirstOrDefault().MinimumCharge,
                            CustomerMinCharge = customerPricing.Minimum,
                            CreatedDate = DateTime.UtcNow,
                            ModifiedDate = DateTime.UtcNow,
                            StartTime = DateTime.UtcNow,
                            EndTime = DateTime.UtcNow,
                            Status = BookingStatus.InProgress,
                            Type = BookingType.TalkNow,
                            Specialization = specialization,
                            IsApplyNoMinimumCharge = specialist.Profile.Specializations.FirstOrDefault().IsApplyNoMinimumCharge
                        });

                        // Generate twiml url
                        twiMLUrl = CallHelper.GenerateTwimlUrl(new CallContextModel
                        {
                            BookingId = booking.Id,
                            CallerId = booking.Customer.Id,
                            ReceiverId = booking.Specialist.Id,
                            IsCustomer = true,
                            NatureOfEnquiry = booking.Enquiry
                        });

                        // Set status for make call
                        status = true;
                    }
                    else // Have call inprogress
                    {
                        return Json(new { Success = false, Error = CallMessage.CallInProgress });
                    }
                }
                else // Make call from booking confirm
                {
                    // Get booking
                    booking = Services.Booking.GetById(model.BookingId);

                    // If payment menthod is prepayment => Compare customer amount prepayment with customerPricing.Minimum
                    // If payment menthod is credit card => If charge success
                    switch (customer.PaymentMethod)
                    {
                        case PaymentMethod.CreditCard:
                            var result = Services.Payment.Authorization(CurrentUser.Id.ToString(), limitAmount);
                            if (!result.Success)
                            {
                                // Show popup notify for specialist
                                CallHelper.ShowPopupNotifyInConference(booking.Specialist,
                                    ConferencePopupConst.CallFailsTitle, ConferencePopupConst.PrepaidBalanceForConsultant);

                                // Show popup notify for customer
                                CallHelper.ShowPopupNotifyInConference(booking.Customer,
                                    ConferencePopupConst.CallFailsTitle,
                                    string.Format(ConferencePopupConst.PrepaidBalanceForCustomer, booking.ReferenceNo));

                                // Return message error
                                return Json(new { Success = false });
                            }
                            else
                            {
                                Services.Payment.Void(result.Transaction.Id);
                            }
                            break;

                        default:
                            if (customer.PrePaymentAmount <= limitAmount)
                            {
                                // Show popup notify for specialist
                                CallHelper.ShowPopupNotifyInConference(booking.Specialist,
                                    ConferencePopupConst.CallFailsTitle, ConferencePopupConst.PrepaidBalanceForConsultant);

                                // Show popup notify for customer
                                CallHelper.ShowPopupNotifyInConference(booking.Customer,
                                    ConferencePopupConst.CallFailsTitle,
                                    string.Format(ConferencePopupConst.PrepaidBalanceForCustomer, booking.ReferenceNo));

                                // Return message error
                                return Json(new { Success = false });
                            }
                            break;
                    }

                    // If customer prepayment amount <= minimum cost => Notify for customer
                    if (booking.Customer.PrePaymentAmount <= minimumCost && PaymentMethod.PrePayment.Equals(booking.Customer.PaymentMethod))
                    {
                        CallHelper.NotifyBalanceCloseToExpiring(booking.Customer.UserName);
                    }

                    // Check call in progress
                    var callInProgress = Services.Call.GetCallInProgressByCallerId(model.SpecialistId);

                    if (callInProgress == null)
                    {
                        // Check make call fails to customer
                        if (booking.CallFails <= 3)
                        {
                            // Generate twiml url
                            twiMLUrl = CallHelper.GenerateTwimlUrl(new CallContextModel
                            {
                                BookingId = model.BookingId,
                                CallerId = model.SpecialistId,
                                ReceiverId = model.CustomerId,
                                IsCustomer = false,
                                NatureOfEnquiry = model.Enquiry
                            });

                            // Set status for make call
                            status = true;
                        }
                        else
                        {
                            // Show popup notify for specialist
                            CallHelper.ShowPopupNotifyInConference(booking.Specialist, ConferencePopupConst.CallFailsTitle,
                                string.Format(ConferencePopupConst.CallFailsContent,
                                booking.CallFails));

                            // Add to booking event
                            Services.Booking.CreateBookingEvent(new BookingEventDto
                            {
                                Booking = booking,
                                SourceUser = booking.Specialist,
                                TargetUser = booking.Customer,
                                ShortDescription = AlertShortDescription.FailedAttemptsCancellation,
                                Description = AlertDescription.FailedAttemptsCancellation,
                                CreatedDate = DateTime.UtcNow,
                                ModifiedDate = DateTime.UtcNow,
                                IsRead = false,
                                EmailAlertSubject = EmailAlertSubject.FailedAttemptsCancellation,
                                EmailAlertDetail = EmailAlertDetail.FailedAttemptsCancellation,
                                SMSAlertDetail = SMSAlertDetail.FailedAttemptsCancellation
                            });

                            // Return message error
                            return Json(new { Success = false });
                        }
                    }
                    else // Call in progress
                    {
                        return Json(new { Success = false, Error = CallMessage.CallInProgress });
                    }
                }

                if (status == true)
                {
                    // Make a call
                    var call = Services.Call.MakeCallForConsultantion(booking, twiMLUrl, model.IsTalkNow);
                    if (call.RestException == null)
                    {
                        return Json(new { Success = "True" });
                    }

                    // Log
                    Log.Error("TalkNowApi. Make call for consultation. Error: " + call.RestException.Message);

                    return Json(new { Success = "False", Error = CallMessage.SystemError });
                }

                return Json(new { Success = "False", Error = CallMessage.SystemError });
            }
            catch (Exception e)
            {
                // Log
                Log.Error("TalkNowAPI. Error", e);

                return Json(new { Success = "False", Error = CallMessage.SystemError });
            }
        }