namespace Hims.Api.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.Threading.Tasks;

    using AutoMapper;

    using Domain.Helpers;
    using Domain.Services;

    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;

    using Models.Provider;

    using Newtonsoft.Json;

    using Senders;

    using Shared.DataFilters;
    using Shared.EntityModels;
    using Shared.Library;
    using Shared.Library.Enums;
    using Shared.UserModels;
    using Shared.UserModels.Filters;

    using Utilities;

    using Hims.Domain.Configurations;
    using Hims.Api.Models;
    using Hims.Domain.Entities;
    using DocumentFormat.OpenXml.Wordprocessing;
    using Image = System.Drawing.Image;
    using Hims.Shared.UserModels.Labs;
    using Hims.Domain.Repositories.UnitOfWork;
    using Hims.Shared.UserModels.Queue;
    using Hims.Api.Models.Patient;

    /// <summary>
    /// The providers controller.
    /// </summary>
    [Route("api/providers")]
    [Consumes("application/json")]
    [Produces("application/json")]
    public class ProvidersController : BaseController
    {
        /// <summary>
        /// The Auto Mapper
        /// </summary>
        private readonly IMapper mapper;

        /// <summary>
        /// the provider service
        /// </summary>
        private readonly IProviderService providerServices;

        /// <summary>
        /// The AES helper.
        /// </summary>
        private readonly IAESHelper aesHelper;

        /// <summary>
        /// The email sender.
        /// </summary>
        private readonly IEmailSender emailSender;

        /// <summary>
        /// The SMS sender.
        /// </summary>
        private readonly ISMSSender smsSender;

        /// <summary>
        /// The document helper.
        /// </summary>
        private readonly IDocumentHelper documentHelper;

        /// <summary>
        /// The account services.
        /// </summary>
        private readonly IAccountService accountServices;

        /// <summary>
        /// The provider location services.
        /// </summary>
        private readonly IProviderLocationService providerLocationServices;

        /// <summary>
        /// The auditlog services.
        /// </summary>
        private readonly IAuditLogService auditLogServices;

        /// <summary>
        /// The provider bank account services.
        /// </summary>
        private readonly IProviderBankAccountService providerBankAccountServices;

        /// <summary>
        /// The Application configuration.
        /// </summary>
        private readonly IApplicationConfiguration applicationConfiguration;

        /// <summary>
        /// The ftp helper.
        /// </summary>
        private readonly IFtpHelper ftpHelper;

        /// <summary>
        /// The FTP upload helper.
        /// </summary>
        private readonly IFtpUploadHelper ftpUploadHelper;

        /// <summary>
        /// The running environment.
        /// </summary>
        private readonly IRunningEnvironment runningEnvironment;

        /// <summary>
        /// The whats application SMS sender
        /// </summary>
        private readonly IWhatsAppSMSSender whatsAppSMSSender;

        /// <summary>
        /// The setting service
        /// </summary>
        private readonly ISettingService settingService;
        /// <inheritdoc />
        public ProvidersController(IProviderService providerServices, IMapper mapper, IAESHelper aesHelper, IEmailSender emailSender, ISMSSender smsSender, IDocumentHelper documentHelper, IAccountService accountServices, IProviderLocationService providerLocationServices, IProviderBankAccountService providerBankAccountServices, IApplicationConfiguration applicationConfiguration, IAuditLogService auditLogServices,
            IFtpHelper ftpHelper, IFtpUploadHelper ftpUploadHelper, IRunningEnvironment runningEnvironment, IWhatsAppSMSSender whatsAppSMSSender, ISettingService settingService)
        {
            this.providerServices = providerServices;
            this.mapper = mapper;
            this.aesHelper = aesHelper;
            this.emailSender = emailSender;
            this.smsSender = smsSender;
            this.documentHelper = documentHelper;
            this.accountServices = accountServices;
            this.providerLocationServices = providerLocationServices;
            this.providerBankAccountServices = providerBankAccountServices;
            this.applicationConfiguration = applicationConfiguration;
            this.auditLogServices = auditLogServices;

            this.ftpHelper = ftpHelper;
            this.ftpUploadHelper = ftpUploadHelper;
            this.runningEnvironment = runningEnvironment;
            this.whatsAppSMSSender = whatsAppSMSSender;
            this.settingService = settingService;
        }

        [HttpPost]
        [Authorize]
        [Route("get-raw")]
        public async Task<ActionResult> GetRawAsync([FromBody] EncryptedIdRequest model)
        {
            var id = model.Id ?? 0;
            model = (EncryptedIdRequest)EmptyFilter.Handler(model);
            if (!string.IsNullOrEmpty(model.EncryptedId))
            {
                id = Convert.ToInt32(this.aesHelper.Decode(model.EncryptedId));
            }
            var data = await this.providerServices.GetRawAsync(id);
            return this.Success(data);
        }

        /// <summary>
        /// To register provider
        /// </summary>
        /// <param name="model" >
        /// The provider registration request Model.
        /// </param>
        /// <returns>
        /// The http status.
        /// </returns>
        /// <remarks>
        /// ### REMARKS ###
        /// The following codes are returned
        /// - 200 - Registration successful and returns Provider GUID.
        /// - 409 - Email or Mobile or NPI already exists.
        /// - 500 - Problem with Server side code.
        /// </remarks>
        [HttpPost]
        [AllowAnonymous]
        [Route("register")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(typeof(OTPResponse), 200)]
        [ProducesResponseType(409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> RegisterAsync([FromBody] ProviderRegistrationModel model)
        {
            model = (ProviderRegistrationModel)EmptyFilter.Handler(model);

            if (model.CountryId == null && model.Username.Contains("@"))
            {
                if (string.IsNullOrEmpty(model.Username))
                {
                    return this.BadRequest();
                }

                var email = model.Username.Contains("@") ? model.Username : null;
                var mobile = !model.Username.Contains("@") ? model.Username : null;

                var fullName = "Dr. " + CoreFilter.FullName(model.FirstName, string.Empty, model.LastName);
                var providerExists = await this.providerServices.CheckProviderAsync(mobile, model.CountryId, null, email, 0);
                if (providerExists == -1)
                {
                    return this.Conflict("Given email address has already been exists with us.");
                }

                if (providerExists == -2)
                {
                    return this.Conflict("Given mobile has already been exists with us.");
                }

                if (string.IsNullOrEmpty(model.Password))
                {
                    return this.Success(await this.emailSender.SendOTPAsync(email, fullName));
                }

                var response = await this.providerServices.RegisterAsync(model);
                if (response <= 0)
                {
                    return this.ServerError();
                }

                var mailSent = await this.emailSender.SendProviderWelcomeMailAsync(email, fullName);
                if (mailSent)
                {
                    this.Success(this.MailServerError());
                }
            }
            else
            {
                if (string.IsNullOrEmpty(model.Username) || model.CountryId == null || model.CountryId == 0)
                {
                    return this.BadRequest();
                }

                var mobile = model.Username;
                var countryId = Convert.ToInt32(model.CountryId);
                var fullName = CoreFilter.FullName(model.FirstName, string.Empty, model.LastName);
                var providerExists = await this.providerServices.CheckProviderAsync(mobile, countryId, null, null, 0);
                if (providerExists == -2)
                {
                    return this.Conflict("Given mobile number has already been exists with us.");
                }

                if (string.IsNullOrEmpty(model.Password))
                {
                    var otp = CoreFilter.RandomNumbers(4);
                    var WhatsAppMessageSetting = await this.settingService.FetchAsync("WhatsAppMsgService", null, null);
                    var WhatsAppMessage = WhatsAppMessageSetting.ToList();
                    if ((bool)WhatsAppMessage[0].Active)
                    {
                        bool Ret = await this.whatsAppSMSSender.SendOTPAsync(mobile, otp);
                    }
                    return this.Success(await this.smsSender.SendOTPAsync(mobile, countryId,otp));
                }

                var response = await this.providerServices.RegisterAsync(model);
                if (response <= 0)
                {
                    return this.ServerError();
                }
                var smsSent = await this.smsSender.SendSMSAsync(mobile, countryId, $"Hi {fullName}, Welcome to {"Careaxes"} - Careaxes. Thank you for registered with us.", "1207162031726799648");
                if (!smsSent)
                {
                    return this.Success(this.SMSServerError());
                }
            }

            var emailSent = await this.emailSender.SendMailAsync(model.FriendlyName);

            return emailSent ? this.Success(this.MailServerError()) : this.Success("Provider has been registered successfully.");
        }

        /// <summary>
        /// To register provider
        /// </summary>
        /// <param name="model" >
        /// The provider registration request Model.
        /// </param>
        /// <returns>
        /// The http status.
        /// </returns>
        /// <remarks>
        /// ### REMARKS ###
        /// The following codes are returned
        /// - 200 - Registration successful and returns Provider GUID.
        /// - 409 - Email or Mobile or NPI already exists.
        /// - 500 - Problem with Server side code.
        /// </remarks>
        [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1126:PrefixCallsCorrectly", Justification = "Reviewed. Suppression is OK here.")]
        [HttpPost]
        [AllowAnonymous]
        [Route("self-register")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(typeof(OTPResponse), 200)]
        [ProducesResponseType(409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> SelfRegisterAsync([FromBody] SelfRegistrationModel model)
        {
            model = (SelfRegistrationModel)EmptyFilter.Handler(model);
            var providerExists = await this.providerServices.CheckProviderAsync(model.Mobile, model.CountryId, null, model.Email, 0);
            if (providerExists == -1)
            {
                return this.Conflict("Given email address has already been exists with us.");
            }

            if (providerExists == -2)
            {
                return this.Conflict("Given mobile has already been exists with us.");
            }

            var (response, guid) = await this.providerServices.SelfRegisterAsync(model);
            if (response <= 0)
            {
                return this.ServerError();
            }


            (model.ProfileImageUrl, model.ThumbnailUrl) = await this.documentHelper.UploadAsync(model.Base64ProfileImage, (Guid)guid, "Profile", "profile_" + DateTime.UtcNow.Ticks);
            if (!string.IsNullOrEmpty(model.ProfileImageUrl))
            {
                var request = new ProviderModel();
                request.ThumbnailUrl = model.ThumbnailUrl;
                request.ProfileImageUrl = model.ProfileImageUrl;
                request.ProviderId = response;
                await this.providerServices.UpdateImageUrlsAsync(request, (Guid)guid);
            }
            var otp = CoreFilter.RandomNumbers(4);
            var WhatsAppMessageSetting = await this.settingService.FetchAsync("WhatsAppMsgService", null, null);
            var WhatsAppMessage = WhatsAppMessageSetting.ToList();
            if ((bool)WhatsAppMessage[0].Active)
            {
                bool Ret = await this.whatsAppSMSSender.SendOTPAsync(model.Mobile, otp);
            }
            return this.Success(await this.smsSender.SendOTPAsync(model.Mobile, model.CountryId,otp));
        }

        /// <summary>
        /// To register provider
        /// </summary>
        /// <param name="model" >
        /// The provider registration request Model.
        /// </param>
        /// <returns>
        /// The http status.
        /// </returns>
        /// <remarks>
        /// ### REMARKS ###
        /// The following codes are returned
        /// - 200 - Registration successful and returns Provider GUID.
        /// - 409 - Email or Mobile or NPI already exists.
        /// - 500 - Problem with Server side code.
        /// </remarks>
        [HttpPost]
        [AllowAnonymous]
        [Route("otp-verification")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(typeof(OTPResponse), 200)]
        [ProducesResponseType(409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> OTPVerificationAsync([FromBody] SelfRegistrationModel model)
        {
            model = (SelfRegistrationModel)EmptyFilter.Handler(model);

            var fullName = "Dr. " + CoreFilter.FullName(model.FirstName, string.Empty, model.LastName);

            var response = await this.providerServices.OTPVerificationAsync(model);

            var createPasswordLink = this.applicationConfiguration.CreatePasswordLink + this.aesHelper.Encode(response.ToString());

            if (!string.IsNullOrEmpty(model.Email))
            {
                var mailSent = await this.emailSender.SendProviderWelcomeMailAsync(model.Email, fullName);
                if (mailSent)
                {
                    this.Success(this.MailServerError());
                }

                var emailResponse = await this.emailSender.SendCreatePasswordMailAsync(model.Email, fullName, createPasswordLink, "Provider");
                if (!emailResponse)
                {
                    this.Success(this.MailServerError());
                }
            }
            var smsSent = await this.smsSender.SendSMSAsync(model.Mobile, model.CountryId, $"Hi {fullName}, Welcome to {""} - Careaxes. Thank you for being registered with us.", "1207162031726799648");
            if (!smsSent)
            {
                this.Success(this.SMSServerError());
            }

            var smsResponse = await this.smsSender.SendCreatePasswordAsync(model.Mobile, fullName, createPasswordLink, model.CountryId);
            if (!smsResponse)
            {
                this.Success(this.SMSServerError());
            }

            return response != 0 ? this.Success("Provider has been registered successfully.") : this.ServerError();
        }

        /// <summary>
        /// To approve provider
        /// </summary>
        /// <param name="request" >
        /// The provider approve request Model.
        /// </param>
        /// <returns>
        /// The string.
        /// </returns>
        /// <remarks>
        /// ### REMARKS ###
        /// The following codes are returned
        /// - 200 - Provider approved successfully.
        /// - 500 - Problem with Server side code.
        /// </remarks>
        [HttpPut]
        [Authorize]
        [Route("approve")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> ApproveAsync([FromBody] ApproveProviderRequest request, [FromHeader] LocationHeader header)
        {
            request = (ApproveProviderRequest)EmptyFilter.Handler(request);
            var model = await this.providerServices.ApproveAsync(request.ProviderId);
            if (model == null)
            {
                return this.ServerError();
            }
            var smsSent = await this.smsSender.SendSMSAsync(model.Mobile, Convert.ToInt32(model.CountryId), $"Congratulations {model.FullName}! Your registration has been successfully approved. - Careaxes, {null}", "1207162031767244703");

            var auditLogModel = new AuditLogModel
            {
                AccountId = request.ModifiedBy,
                LogTypeId = (int)LogTypes.Provider,
                LogFrom = (short)request.RoleId,
                LogDate = DateTime.UtcNow.AddMinutes(330),
                LogDescription = $"{request.AccountFullName} has Approved {request.ProviderName} on {DateTime.UtcNow.AddMinutes(330)}",
                LocationId = Convert.ToInt32(header.LocationId)
            };
            await this.auditLogServices.LogAsync(auditLogModel);

            return smsSent
                       ? this.Success(this.SMSServerError())
                       : this.Success("Provider has been approved successfully.");
        }

        /// <summary>
        /// To reject provider
        /// </summary>
        /// <param name="request" >
        /// The provider reject request Model.
        /// </param>
        /// <returns>
        /// The string.
        /// </returns>
        /// <remarks>
        /// ### REMARKS ###
        /// The following codes are returned
        /// - 200 - Provider rejected successfully.
        /// - 500 - Problem with Server side code.
        /// </remarks>
        [HttpPut]
        [Authorize]
        [Route("reject")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> RejectAsync([FromBody] RejectProviderRequest request, [FromHeader] LocationHeader header)
        {
            request = (RejectProviderRequest)EmptyFilter.Handler(request);
            var model = await this.providerServices.RejectAsync(request.ProviderId, request.RejectedComments);
            if (model == null)
            {
                return this.ServerError();
            }
            var smsSent = false;
            try
            {
                var messageBody = string.IsNullOrEmpty(request.RejectedComments)
                ? $"Hi {model.FullName}, We're sorry to inform you that your registration has been rejected.  - Careaxes, {null}"
                : $"Hi {model.FullName}, We're sorry to inform you that your registration has been rejected due to '{request.RejectedComments}'. - Careaxes, {null}";
                var templatedId = string.IsNullOrEmpty(request.RejectedComments) ? "1207162031743574677" : "1207162031735609426";
                smsSent = await this.smsSender.SendSMSAsync(model.Mobile, Convert.ToInt32(model.CountryId), messageBody, templatedId);
            }
            catch (Exception e)
            {
                // ignore
            }

            var auditLogModel = new AuditLogModel
            {
                AccountId = request.ModifiedBy,
                LogTypeId = (int)LogTypes.Provider,
                LogFrom = (short)request.RoleId,
                LogDate = DateTime.UtcNow.AddMinutes(330),
                LogDescription = $"{request.AccountFullName} has rejected {request.ProviderName} on {DateTime.UtcNow.AddMinutes(330)}",
                LocationId = Convert.ToInt32(header.LocationId)
            };
            await this.auditLogServices.LogAsync(auditLogModel);
            return smsSent
                       ? this.Success(this.SMSServerError())
                       : this.Success("Provider has been rejected successfully.");
        }

        /// <summary>
        /// To find provider
        /// </summary>
        /// <param name="model" >
        /// The provider find request Model.
        /// </param>
        /// <param name="location"></param>
        /// <returns>
        /// The provider model.
        /// </returns>
        /// <remarks>
        /// ### REMARKS ###
        /// The following codes are returned
        /// - 200 - Provider model.
        /// - 400 - Sorry! We don't have a provider in the system.
        /// - 500 - Problem with Server side code.
        /// </remarks>
        [HttpPost]
        [Route("find")]
        [ProducesResponseType(typeof(ProviderModel), 200)]
        [ProducesResponseType(typeof(string), 400)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FindAsync([FromBody] FindProviderRequest model, [FromHeader] LocationHeader location)
        {
            if ((model.EncryptedProviderId == "null" && model.LocationId == null && model.SpecializationId == null) || (model.EncryptedProviderId == "undefined" && model.LocationId == null && model.SpecializationId == null))
            {
                return this.Failed("Model is null.");
            }
            model = (FindProviderRequest)EmptyFilter.Handler(model);
            var providerId = Convert.ToInt32(this.aesHelper.Decode(model.EncryptedProviderId));
            model.LocationId = string.IsNullOrEmpty(location.LocationId) ? (int?)null : int.Parse(location.LocationId);

            var provider = await this.providerServices.FindAsync(providerId, model.LocationId, model.SpecializationId);

            if (provider == null || provider.ProviderId == 0)
            {
                return this.BadRequest("Sorry! We don't have a provider in the system.");
            }
            if (provider.ProviderId > 0)
            {
                provider.EncryptedProviderId = this.aesHelper.Encode(provider.ProviderId.ToString());
            }

            if (!string.IsNullOrEmpty(provider.Availability))
            {
                var date = DateTime.UtcNow;
                var day = ((int)(date.DayOfWeek + 6) % 7) + 1;

                var slots = JsonConvert.DeserializeObject<List<ProviderShiftModel>>(provider.Availability);
                var availability = slots.FirstOrDefault(m => m.Day == day) ?? new ProviderShiftModel();
                provider.ConsultationCharges = availability.ConsultationCharges;
                provider.TelemedicineCharges = availability.TelemedicineCharges;

                if (availability.TelemedicineCharges == null)
                {
                    var count = 0;
                    for (int i = day; i <= 7; i++)
                    {
                        count++;
                        if (count >= 8)
                        {
                            break;
                        }

                        availability = slots.FirstOrDefault(m => m.Day == i) ?? new ProviderShiftModel();
                        provider.ConsultationCharges = availability.ConsultationCharges;
                        provider.TelemedicineCharges = availability.TelemedicineCharges;
                        if (i == 7)
                        {
                            i = 1;
                        }
                        if (availability.TelemedicineCharges != null)
                        {
                            break;
                        }
                    }
                }
            }

            if (!string.IsNullOrEmpty(provider.Specializations))
            {
                provider.Specializations = provider.Specializations.Replace("{", string.Empty);
                provider.Specializations = provider.Specializations.Replace("}", string.Empty);
            }

            if (!string.IsNullOrEmpty(provider.Services))
            {
                provider.Services = provider.Services.Replace("{", string.Empty);
                provider.Services = provider.Services.Replace("}", string.Empty);
            }

            // var locations = await this.providerLocationServices.FetchAsync(provider.ProviderId, true, model.LocationId) ?? new List<ProviderLocationModel>();
            var availbility = await this.providerLocationServices.FetchAsync(provider.ProviderId, model.SpecializationId, true, model.LocationId) ?? new List<ProviderAvailabilityModel>();
            var bankDetails = await this.providerBankAccountServices.FindAsync(provider.ProviderId) ?? new ProviderBankAccountModel();
            return this.Success(new { provider, availbility, bankDetails });
        }

        /// <summary>
        /// To fetch providers
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="location"></param>
        /// <returns>
        /// The list of providers.
        /// </returns>
        /// <remarks>
        /// ### REMARKS ###
        /// The following codes are returned
        /// - 200 - List of providers.
        /// - 500 - Problem with Server side code.
        /// </remarks>
        [HttpPost]
        [Authorize]
        [Route("fetch")]
        [ProducesResponseType(typeof(IEnumerable<ProviderModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FetchAsync([FromBody] ProviderFilterModel model, [FromHeader] LocationHeader location)
        {
            model = (ProviderFilterModel)EmptyFilter.Handler(model);
            model.LocationId = !string.IsNullOrEmpty(location.LocationId) ? int.Parse(location.LocationId) : (int?)null;
            var providers = await this.providerServices.FetchAsync(model);
            if (providers == null)
            {
                return this.ServerError();
            }

            foreach (var provider in providers)
            {
                provider.EncryptedProviderId = this.aesHelper.Encode(provider.ProviderId.ToString());
            }

            return this.Success(providers);
        }

        /// <summary>
        /// To fetch provider list items
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The list of providers.
        /// </returns>
        /// <remarks>
        /// ### REMARKS ###
        /// The following codes are returned
        /// - 200 - List of providers.
        /// - 500 - Problem with Server side code.
        /// </remarks>
        [HttpPost]
        [AllowAnonymous]
        [Route("fetch-list-items")]
        [ProducesResponseType(typeof(IEnumerable<ProviderListItemModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FetchListItemsAsync([FromBody] ProviderListItemFilterModel model)
        {
            model = (ProviderListItemFilterModel)EmptyFilter.Handler(model);
            var providers = await this.providerServices.FetchListItemsAsync(model);
            if (providers == null)
            {
                return this.ServerError();
            }

            foreach (var provider in providers)
            {
                provider.EncryptedProviderId = this.aesHelper.Encode(provider.ProviderId.ToString());

                var date = DateTime.Now;
                var day = ((int)(date.DayOfWeek + 6) % 7) + 1;
                if (!string.IsNullOrEmpty(provider.Availability))
                {
                    var slots = JsonConvert.DeserializeObject<List<ProviderShiftModel>>(provider.Availability);

                    slots.ForEach(m =>
                    {
                        var specializationAvailability = m.Slots.Where(t => t.Specializations.Contains((int)provider.SpecializationId));
                        if (specializationAvailability != null)
                        {
                            var availability = slots.FirstOrDefault(m => m.Day == day) ?? new ProviderShiftModel();
                            provider.ChargeType = availability.ChargeType;
                        }
                    });
                }
            }

            return this.Success(providers);
        }

        /// <summary>
        /// The add provider.
        /// </summary>
        /// <param name="request">
        /// The request.
        /// </param>
        /// <param name="header"></param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [Authorize]
        [Route("add")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(typeof(string), 409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> AddAsync([FromBody] ModifyProviderRequest request, [FromHeader] LocationHeader header)
        {
            request = (ModifyProviderRequest)EmptyFilter.Handler(request);
            var model = this.mapper.Map<ProviderModel>(request);
            model.FullName = CoreFilter.FullName(model.FirstName, string.Empty, model.LastName);
            var (accountId, providerId, guid) = await this.providerServices.AddAsync(model);
            switch (accountId)
            {
                case -1:
                    return this.Conflict("Given email address has already been exists with us.");
                case -2:
                    return this.Conflict("Given mobile number has already been exists with us.");
                case -3:
                    return this.Conflict("Given NPI has already been exists with us.");
                case 0:
                    return this.ServerError();
            }
            if (accountId > 0)
            {
                var auditLogModel = new AuditLogModel
                {
                    AccountId = model.CreatedBy,
                    LogTypeId = (int)LogTypes.Provider,
                    LogFrom = (short)model.RoleId,
                    LogDate = DateTime.UtcNow.AddMinutes(330),
                    LogDescription = $"{model.AccountFullName} has added Doctor '{model.FullName}' on '{DateTime.UtcNow.AddMinutes(330)}",
                    LocationId = Convert.ToInt32(header.LocationId)
                };
                await this.auditLogServices.LogAsync(auditLogModel);
            }

            if (!string.IsNullOrEmpty(model.Base64ProfileImage))
            {
                var filePath = $@"{this.runningEnvironment.CurrentEnvironment}/{guid}/ProfileImage";

                try
                {
                    await this.ftpUploadHelper.CreateDirectory(filePath);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
                var dbPath = $@"{model.FullName}_{DateTime.UtcNow.Ticks}.jpg";
                filePath += $@"/{dbPath}";

                try
                {
                    var uploadResponse = await this.ftpUploadHelper.UploadProfileImageAsync(model.Base64ProfileImage, filePath);
                    if (uploadResponse > 0)
                    {
                        model.ProfileImageUrl = $@"ProfileImage/{dbPath}";
                        model.ThumbnailUrl = $@"ProfileImage/{dbPath}";
                    }
                }
                catch (Exception)
                {
                    model.ProfileImageUrl = null;
                    model.ThumbnailUrl = null;
                }
            }
            if (!string.IsNullOrEmpty(model.Base64Signature))
            {
                var filePath = $@"{this.runningEnvironment.CurrentEnvironment}/{guid}/Signature";

                try
                {
                    await this.ftpUploadHelper.CreateDirectory(filePath);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
                var dbPath = $@"{model.FullName}_{DateTime.UtcNow.Ticks}.jpg";
                filePath += $@"/{dbPath}";

                try
                {
                    var uploadResponse = await this.ftpUploadHelper.UploadProfileImageAsync(model.Base64Signature, filePath);
                    if (uploadResponse > 0)
                    {
                        model.Signature = $@"Signature/{dbPath}";
                    }
                }
                catch (Exception)
                {
                    model.Signature = null;
                }
            }

            //await this.providerservices.updatethumbnailimageurlsasync(profileimageurl, thumbnailurl, (guid)guid);
            //if (!string.isnullorempty(model.profileimageurl))
            //{
            //    await this.providerservices.updatethumbnailimageurlsasync(model.profileimageurl, model.thumbnailurl, (guid)guid);
            //}

            //var signature = await this.documentHelper.UploadEncounterImagesAsync(
            //                   request.Base64Signature,
            //                   (Guid)guid,
            //                   "signature",
            //                   "doctorSignature" + DateTime.UtcNow.Ticks);

            //var clinicLogo = await this.documentHelper.UploadEncounterImagesAsync(
            //                     request.Base64ClinicPicture,
            //                     (Guid)guid,
            //                     "LogoClinic",
            //                     "logo" + DateTime.UtcNow.Ticks);

            //model.Signature = !string.IsNullOrEmpty(signature) ? signature : model.Signature;
            //model.ClinicPicture = !string.IsNullOrEmpty(clinicLogo) ? clinicLogo : model.ClinicPicture;

            await this.providerServices.UpdateProfileImageUrlsAsync(model.ProfileImageUrl, model.ThumbnailUrl, (Guid)guid);
            await this.providerServices.UpdateSignatureUrlsAsync(model.Signature, model.ClinicPicture, (Guid)guid);
            var createPasswordLink = this.applicationConfiguration.CreatePasswordLink + this.aesHelper.Encode(accountId.ToString());

            if (model.Email != null)
            {
                await this.emailSender.SendCreatePasswordMailAsync(model.Email, model.FullName, createPasswordLink, "Doctor");
            }

            var smsResponse = false;
            try
            {
                smsResponse = await this.smsSender.SendCreatePasswordAsync(model.Mobile, model.FullName, createPasswordLink, Convert.ToInt32(model.CountryId));
                return !smsResponse ? this.Success(this.SMSServerError()) : this.Success("Provider has been added successfully.");
            }
            catch (Exception ex)
            {
                throw ex;
            }


            return this.Success("Doctor has been added successfully.");
        }

        /// <summary>
        /// The update provider.
        /// </summary>
        /// <param name="request">
        /// The request.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        /// <remarks>
        /// ### REMARKS ###
        /// The following codes are returned
        /// - 200 - Provider details has been updated successfully.
        /// - 409 - Provider has already been exists with us.
        /// - 500 - Problem with Server side code.
        /// </remarks>
        [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1126:PrefixCallsCorrectly", Justification = "Reviewed. Suppression is OK here.")]
        [HttpPut]
        [Authorize]
        [Route("update")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(typeof(string), 409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> UpdateAsync([FromBody] ModifyProviderRequest request, [FromHeader] LocationHeader header)
        {
            request = (ModifyProviderRequest)EmptyFilter.Handler(request);
            var model = this.mapper.Map<ProviderModel>(request);

            model.FullName = CoreFilter.FullName(model.FirstName, string.Empty, model.LastName);
            var path = await this.providerServices.FindAsync(model.ProviderId, (int?)null, (int?)null);
            if (path == null)
            {
                return this.ServerError();
            }


            if (!string.IsNullOrEmpty(model.Base64ProfileImage))
            {
                var filePath = $@"{this.runningEnvironment.CurrentEnvironment}/{path.Guid}/ProfileImage";

                try
                {
                    await this.ftpUploadHelper.CreateDirectory(filePath);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
                var dbPath = $@"{model.FullName}_{DateTime.UtcNow.Ticks}.jpg";
                filePath += $@"/{dbPath}";

                try
                {
                    var uploadResponse = await this.ftpUploadHelper.UploadProfileImageAsync(model.Base64ProfileImage, filePath);
                    if (uploadResponse > 0)
                    {
                        if (path.ProfileImageUrl != null || path.ThumbnailUrl != null)
                        {
                            await this.ftpUploadHelper.DeleteFile(path.ProfileImageUrl);
                        }
                        model.ProfileImageUrl = $@"ProfileImage/{dbPath}";
                        model.ThumbnailUrl = $@"ProfileImage/{dbPath}";
                    }
                }
                catch (Exception)
                {
                    model.ProfileImageUrl = null;
                    model.ThumbnailUrl = null;
                }
            }
            if (!string.IsNullOrEmpty(model.Base64Signature))
            {
                var filePath = $@"{this.runningEnvironment.CurrentEnvironment}/{path.Guid}/Signature";

                try
                {
                    await this.ftpUploadHelper.CreateDirectory(filePath);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
                var dbPath = $@"{model.FullName}_{DateTime.UtcNow.Ticks}.jpg";
                filePath += $@"/{dbPath}";

                try
                {
                    var uploadResponse = await this.ftpUploadHelper.UploadProfileImageAsync(model.Base64Signature, filePath);
                    if (uploadResponse > 0)
                    {
                        if (path.Signature != null)
                        {
                            await this.ftpUploadHelper.DeleteFile(path.Signature);
                        }
                        model.Signature = $@"Signature/{dbPath}";
                    }
                }
                catch (Exception)
                {
                    model.Signature = null;
                }
            }

            var response = await this.providerServices.UpdateAsync(model);

            switch (response)
            {
                case -1:
                    return this.Conflict("Given email address has already been exists with us.");
                case -2:
                    return this.Conflict("Given mobile number has already been exists with us.");
                case -3:
                    return this.Conflict("Given NPI has already been exists with us.");
                case 0:
                    return this.ServerError();
                default:

                    var auditLogModel = new AuditLogModel
                    {
                        AccountId = request.ModifiedBy,
                        LogTypeId = (int)LogTypes.Provider,
                        LogFrom = (short)request.RoleId,
                        LogDate = DateTime.UtcNow.AddMinutes(330),
                        LogDescription = $"{request.AccountFullName} has modified the Doctor '{model.FullName}' on {DateTime.UtcNow.AddMinutes(330)}",
                        LocationId = Convert.ToInt32(header.LocationId)
                    };
                    await this.auditLogServices.LogAsync(auditLogModel);


                    return this.Success("Provider details has been updated successfully.");
            }
        }

        /// <summary>
        /// The update provider profile.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        /// <remarks>
        /// ### REMARKS ###
        /// The following codes are returned
        /// - 200 - Provider specializations has been updated successfully.
        /// - 500 - Problem with Server side code.
        /// </remarks>
        [HttpPut]
        [Authorize]
        [Route("update-profile")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(typeof(string), 409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> UpdateProfileAsync([FromBody] ModifyProviderProfileModel model, [FromHeader] LocationHeader header)
        {
            model = (ModifyProviderProfileModel)EmptyFilter.Handler(model);
            var response = await this.providerServices.UpdateProfileAsync(model);
            var provider = await this.providerServices.FindProviderByProviderId(model.ProviderId);
            if (response == 0)
            {
                return this.ServerError();
            }

            var auditLogModel = new AuditLogModel
            {
                AccountId = model.ModifiedBy,
                LogTypeId = (int)LogTypes.Provider,
                LogFrom = (short)model.RoleId,
                LogDate = DateTime.UtcNow.AddMinutes(330),
                //LogDescription = $"{model.SpecializationName} specialization has been added."
                LogDescription = $"{model.FullName} has added specializtion for {provider.FullName} on {DateTime.UtcNow.AddMinutes(330)}",
                LocationId = Convert.ToInt32(header.LocationId)
            };
            await this.auditLogServices.LogAsync(auditLogModel);

            return this.Success("Provider profile has been updated successfully.");
        }

        /// <summary>
        /// The update profile image async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="location"></param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1126:PrefixCallsCorrectly", Justification = "Reviewed. Suppression is OK here.")]
        [HttpPut]
        [Authorize]
        [Route("update-profile-image")]
        [Consumes("application/json")]
        [Produces("application/json")]
        [ProducesResponseType(500)]
        public async Task<ActionResult> UpdateProfileImageAsync([FromBody] UpdateProviderImageRequest model, [FromHeader] LocationHeader location)
        {
            model = (UpdateProviderImageRequest)EmptyFilter.Handler(model);
            if (string.IsNullOrEmpty(model.Base64ImageString))
            {
                return this.BadRequest("No profile image found. Please try again.");
            }

            var locationId = string.IsNullOrEmpty(location.LocationId) ? (int?)null : int.Parse(location.LocationId);

            var providerModel = await this.providerServices.FindAsync(model.ProviderId, locationId, null);
            var guid = await this.accountServices.FindGuidAsync(providerModel.ProviderId, Roles.Provider);
            var (profileImageUrl, thumbnailUrl) = await this.documentHelper.UploadAsync(model.Base64ImageString, guid, "Profile", "profile_" + DateTime.UtcNow.Ticks);
            if (profileImageUrl != null)
            {
                providerModel.ProfileImageUrl = profileImageUrl;
            }

            if (thumbnailUrl != null)
            {
                providerModel.ThumbnailUrl = thumbnailUrl;
            }

            var response = await this.providerServices.UpdateImageUrlsAsync(providerModel, guid);
            switch (response)
            {
                case 0:
                    return this.ServerError();
                default:
                    return this.Success(new
                    {
                        ProfileImageUrl = this.documentHelper.GetUrl(guid, providerModel.ProfileImageUrl),
                        ThumbnailUrl = this.documentHelper.GetUrl(guid, providerModel.ThumbnailUrl)
                    });
            }
        }

        /// <summary>
        /// The upload old profiles.
        /// </summary>
        /// <param name="path">
        /// The path.
        /// </param>
        /// <param name="location"></param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        /// <remarks>
        /// ### REMARKS ###
        /// The following codes are returned
        /// - 200 - documents updated successfully.
        /// - 500 - Problem with Server side code.
        /// </remarks>
        [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1126:PrefixCallsCorrectly", Justification = "Reviewed. Suppression is OK here.")]
        [HttpPost]
        [AllowAnonymous]
        [Route("upload-old-profiles")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> UploadOldProfilesAsync(string path, [FromHeader] LocationHeader location)
        {
            var logPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot\\logs", "Log_" + DateTime.Now.ToString("mmddyyhhMMss") + ".txt");
            try
            {
                var directories = Directory.GetDirectories($@"{path}");
                var count = 0;
                foreach (var directory in directories)
                {
                    count++;
                    var providerId = Convert.ToInt32(directory.Split("\\")[3]);
                    var locationId = string.IsNullOrEmpty(location.LocationId) ? (int?)null : int.Parse(location.LocationId);
                    var providerModel = await this.providerServices.FindAsync(providerId, locationId, null);
                    if (providerModel == null)
                    {
                        UpdateLog(logPath, $"{count}.Doctor not found");
                        continue;
                    }

                    var guid = await this.accountServices.FindGuidAsync(providerModel.ProviderId, Roles.Provider);

                    var files = Directory.GetFiles(directory + "\\Profile");
                    if (files.Length <= 0)
                    {
                        UpdateLog(logPath, $"{count}.Doctor({providerModel.Email}) Profile documents not found");
                    }
                    else
                    {
                        UpdateLog(logPath, $"{count}.Doctor({providerModel.Email}) Profile documents upload started");

                        foreach (var item in files)
                        {
                            using (var image = Image.FromFile(item))
                            {
                                using (var stream = new MemoryStream())
                                {
                                    image.Save(stream, image.RawFormat);
                                    var bytes = stream.ToArray();
                                    var base64String = Convert.ToBase64String(bytes);
                                    base64String = "data:image/jpg;base64," + base64String;
                                    var (profileImageUrl, thumbnailUrl) = await this.documentHelper.UploadAsync(base64String, guid, "Profile", "profile_" + DateTime.UtcNow.Ticks);
                                    if (profileImageUrl != null)
                                    {
                                        providerModel.ProfileImageUrl = profileImageUrl;
                                    }

                                    if (thumbnailUrl != null)
                                    {
                                        providerModel.ThumbnailUrl = thumbnailUrl;
                                    }

                                    await this.providerServices.UpdateImageUrlsAsync(providerModel, guid);
                                }
                            }
                        }

                        if (files.Length > 0)
                        {
                            UpdateLog(logPath, $"{files.Length} Doctor documents uploaded");
                        }

                        UpdateLog(logPath, $"Documents uploaded successfully");
                    }
                }

                return this.Success("Doctor documents has been updated successfully.");
            }
            catch (Exception ex)
            {
                UpdateLog(logPath, $"Documents upload aborted : {ex.Message} {Environment.NewLine} {ex.StackTrace}");
                return this.ServerError();
            }
        }

        /// <summary>
        /// The locked status async.
        /// </summary>
        /// <param name="request">
        /// The request.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPut]
        [Authorize]
        [Route("lock-status")]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(typeof(string), 409)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> LockedStatusAsync([FromBody] ProviderModel request, [FromHeader] LocationHeader header)
        {
            try
            {
                var model = this.mapper.Map<ProviderModel>(request);

                model.ProviderId = Convert.ToInt32(this.aesHelper.Decode(model.EncryptedProviderId));

                var provider = await this.providerServices.FindProviderByProviderId(model.ProviderId);

                var response = await this.providerServices.LockedStatusAsync(model);


                switch (response)
                {
                    case 0:
                        return this.ServerError();
                    default:
                        var auditLogModel = new AuditLogModel
                        {
                            AccountId = request.ModifiedBy,
                            LogTypeId = (int)LogTypes.Provider,
                            LogFrom = (short)request.RoleId,
                            LogDate = DateTime.UtcNow.AddMinutes(330),
                            LogDescription = request.IsLocked == true ? $"{request.AccountFullName} has locked {provider.FullName} on {DateTime.UtcNow.AddMinutes(330)}" : $"{request.AccountFullName} has unlocked {provider.FullName} on {DateTime.UtcNow.AddMinutes(330)}",
                            LocationId = Convert.ToInt32(header.LocationId)
                        };
                        await this.auditLogServices.LogAsync(auditLogModel);

                        return this.Success("Provider has been " + (request.IsLocked == true ? "locked" : "Unlock") + " successfully.");
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        /// <summary>
        /// The fetch provider list async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [AllowAnonymous]
        [Route("fetch-providers-list")]
        [ProducesResponseType(typeof(IEnumerable<ProviderListItemModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FetchProviderListAsync([FromBody] ProviderListItemFilterModel model)
        {
            model = (ProviderListItemFilterModel)EmptyFilter.Handler(model);
            var providers = await this.providerServices.ProviderList(model);
            if (providers == null)
            {
                return this.ServerError();
            }

            foreach (var provider in providers)
            {
                provider.EncryptedProviderId = this.aesHelper.Encode(provider.ProviderId.ToString());
            }

            return this.Success(providers);
        }

        /// <summary>
        /// The fetch provider list async.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        [HttpPost]
        [AllowAnonymous]
        [Route("fetch-providers-availability")]
        [ProducesResponseType(typeof(IEnumerable<ProviderListItemModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FetchProviderAvailabilityAsync([FromBody] ProviderListItemFilterModel model)
        {
            model = (ProviderListItemFilterModel)EmptyFilter.Handler(model);
            var providers = await this.providerServices.GetProviderAvailabilityAsync(model.ProviderIds, model.ProviderLocationId);
            if (providers == null)
            {
                return this.ServerError();
            }

            foreach (var provider in providers)
            {
                var date = DateTime.UtcNow;
                var day = ((int)(date.DayOfWeek + 6) % 7) + 1;
                if (!string.IsNullOrEmpty(provider.Availability))
                {
                    var slots = JsonConvert.DeserializeObject<List<ProviderShiftModel>>(provider.Availability);
                    var availability = slots.FirstOrDefault(m => m.Day == day) ?? new ProviderShiftModel();
                    provider.ConsultationCharges = availability.ConsultationCharges;
                    provider.TelemedicineCharges = availability.TelemedicineCharges;

                    if (availability.TelemedicineCharges == null)
                    {
                        var count = 0;
                        for (int i = day; i <= 7; i++)
                        {
                            count++;
                            if (count >= 8)
                            {
                                break;
                            }

                            availability = slots.FirstOrDefault(m => m.Day == i) ?? new ProviderShiftModel();
                            provider.ConsultationCharges = availability.ConsultationCharges;
                            provider.TelemedicineCharges = availability.TelemedicineCharges;
                            if (i == 7)
                            {
                                i = 1;
                            }
                            if (availability.TelemedicineCharges != null)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            return this.Success(providers);
        }

        /// <summary>
        /// The update agreement.
        /// </summary>
        /// <param name="model">
        /// The agreement.
        /// </param>
        /// <param name="location"></param>
        [HttpPost]
        [Route("provider-details")]
        [ProducesResponseType(typeof(ProviderModel), 200)]
        [ProducesResponseType(typeof(ProviderModel), 400)]
        public async Task<ActionResult> FindProviderIdByAsync([FromBody] ProviderModel model, [FromHeader] LocationHeader location)
        {
            model = (ProviderModel)EmptyFilter.Handler(model);
            var providerId = this.providerServices.FindProviderIdByAsync(model.Email, model.Mobile);
            var locationId = string.IsNullOrEmpty(location.LocationId) ? (int?)null : int.Parse(location.LocationId);
            var providerModel = await this.providerServices.FindAsync(providerId, locationId, null);
            if (providerModel == null)
            {
                return this.ServerError();
            }
            return this.Success(providerModel);
        }

        /// <summary>
        /// Assigns the consultation room provider.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="location">The location.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("modify-provider-consultation-room")]
        public async Task<ActionResult> AssignConsultationRoomProvider([FromBody] ProviderConsultationRoomModel model, [FromHeader] LocationHeader location)
        {
            model = (ProviderConsultationRoomModel)EmptyFilter.Handler(model);
            model.LocationId = Convert.ToInt32(location.LocationId);
            var response = await this.providerServices.AddProviderConsultationRoom(model);
            return this.Success(response);
        }

        /// <summary>
        /// Fetches the consultation room provider.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="location">The location.</param>
        /// <returns></returns>
        [HttpPost]
        [Route("fetch-provider-consultation-room")]
        public async Task<ActionResult> FetchConsultationRoomProvider([FromBody] ProviderConsultationRoomModel model, [FromHeader] LocationHeader location)
        {
            model ??= new ProviderConsultationRoomModel();
            model.LocationId = Convert.ToInt32(location.LocationId);
            var response = await this.providerServices.FetchProvidersRoom(model);
            return this.Success(response);
        }

        /// <summary>
        /// To fetch provider list items
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <returns>
        /// The list of providers.
        /// </returns>
        /// <remarks>
        /// ### REMARKS ###
        /// The following codes are returned
        /// - 200 - List of providers.
        /// - 500 - Problem with Server side code.
        /// </remarks>
        [HttpPost]
        [AllowAnonymous]
        [Route("fetch-provider-list-items")]
        [ProducesResponseType(typeof(IEnumerable<ProviderListItemModel>), 200)]
        [ProducesResponseType(500)]
        public async Task<ActionResult> FetchProviderListItemsAsync([FromBody] ProviderListItemFilterModel model)
        {
            model = (ProviderListItemFilterModel)EmptyFilter.Handler(model);
            var providers = await this.providerServices.FetchProviderListItemsAsync(model);
            if (providers == null)
            {
                return this.ServerError();
            }

            foreach (var provider in providers)
            {
                provider.EncryptedProviderId = this.aesHelper.Encode(provider.ProviderId.ToString());

                var date = DateTime.Now;
                var day = ((int)(date.DayOfWeek + 6) % 7) + 1;
                if (!string.IsNullOrEmpty(provider.Availability))
                {
                    var slots = JsonConvert.DeserializeObject<List<ProviderShiftModel>>(provider.Availability);

                    slots.ForEach(m =>
                    {
                        var specializationAvailability = m.Slots.Where(t => t.Specializations.Contains((int)provider.SpecializationId));
                        if (specializationAvailability != null)
                        {
                            var availability = slots.FirstOrDefault(m => m.Day == day) ?? new ProviderShiftModel();
                            provider.ChargeType = availability.ChargeType;
                        }
                    });
                }

                //if (!string.IsNullOrEmpty(provider.ThumbnailUrl))
                //{
                //    string ftpfullpath = this.newftpConfiguration.fullDoctorProfilesPath + provider.ProviderId + "/" + provider.ThumbnailUrl;
                //    provider.ThumbnailUrl = await this.documentHelper.FetchImageBase64(provider.ProviderId, ftpfullpath);
                //}
                //else
                //{
                //    provider.ThumbnailUrl = null;
                //}
            }

            return this.Success(providers);
        }

        /// <summary>
        /// The update log.
        /// </summary>
        /// <param name="logPath">
        /// The log path.
        /// </param>
        /// <param name="message">
        /// The message.
        /// </param>
        private static void UpdateLog(string logPath, string message)
        {
            message = $"{DateTime.Now:G}: {message}.{Environment.NewLine}";
            System.IO.File.AppendAllText(logPath, message);
        }
    }
}