namespace Hims.Api.Senders
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;

    using Domain.Configurations;
    using Domain.Helpers;

    using Models.MailTemplates;

    using Shared.DataFilters;
    using Shared.Library;
    using Shared.Library.MailKit;

    using Hims.Shared.EntityModels;
    using VirtualSteth.Api.Models.MailTemplates;
    using Hims.Shared.UserModels;

    /// <inheritdoc />
    public class EmailSender : IEmailSender
    {
        /// <summary>
        /// The application configuration.
        /// </summary>
        private readonly IApplicationConfiguration applicationConfiguration;

        /// <summary>
        /// The template helper.
        /// </summary>
        private readonly ITemplateHelper templateHelper;

        /// <summary>
        /// The email helper.
        /// </summary>
        private readonly IEmailHelper emailHelper;

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

        /// <summary>
        /// The mail server error.
        /// </summary>
        private readonly string mailServerError;

        /// <inheritdoc cref="IEmailSender"/> />
        public EmailSender(IApplicationConfiguration applicationConfiguration, ITemplateHelper templateHelper, IEmailHelper emailHelper, IRunningEnvironment runningEnvironment)
        {
            this.applicationConfiguration = applicationConfiguration;
            this.templateHelper = templateHelper;
            this.emailHelper = emailHelper;
            this.runningEnvironment = runningEnvironment;
            this.mailServerError = "Due to mail server issue we are unable to send mails at this moment. Please contact an administrator for further details.";
        }

        /// <inheritdoc />
        public async Task<OTPResponse> SendOTPAsync(string email, string fullName)
        {
            var otp = CoreFilter.RandomNumbers(4);
            try
            {
                var mailTemplateModel = new EmailOTP
                {
                    FullName = fullName,
                    OTP = otp,
                    Email = email,
                    AndroidAppLink = this.applicationConfiguration.AndroidAppLink,
                    IOSAppLink = this.applicationConfiguration.IOSAppLink,
                    MailTemplatesImagesLink = this.applicationConfiguration.MailTemplatesImagesLink
                };

                var emailMessage = new EmailMessage
                {
                    Importance = true,
                    Priority = true,
                    Subject = "Careaxes Verification Code",
                    Content = await this.templateHelper.RenderTemplateAsync("EmailOTP", mailTemplateModel)
                };

                emailMessage.ToAddresses.Add(new EmailAddress { Name = mailTemplateModel.FullName, Address = email });
                await this.emailHelper.SendAsync(emailMessage);
                return new OTPResponse { OTP = otp, OTPExpiresIn = 180 };
            }
            catch
            {
                return new OTPResponse { Error = true, ErrorDescription = this.mailServerError, OTP = otp, OTPExpiresIn = 180 };
            }
        }

        /// <inheritdoc />
        public async Task<bool> SendVideoLinkAsync(string email, string fullName, string providerName, string link)
        {
            try
            {
                var mailTemplateModel = new VideoConferenceLink
                {
                    FullName = fullName,
                    VideoLink = link,
                    DoctorName = providerName,
                    AndroidAppLink = this.applicationConfiguration.AndroidAppLink,
                    IOSAppLink = this.applicationConfiguration.IOSAppLink,
                    MailTemplatesImagesLink = this.applicationConfiguration.MailTemplatesImagesLink
                };

                var emailMessage = new EmailMessage
                {
                    Importance = true,
                    Priority = true,
                    Subject = "Virtual Steth Video Conference Link",
                    //Content = $"{link} is your Virtual Steth video conference link to connect your doctor."
                    Content = await this.templateHelper.RenderTemplateAsync("VideoConferenceLink", mailTemplateModel)
                };

                emailMessage.ToAddresses.Add(new EmailAddress { Name = mailTemplateModel.FullName, Address = email });
                await this.emailHelper.SendAsync(emailMessage);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <inheritdoc />
        public async Task<bool> SendProviderWelcomeMailAsync(string email, string fullName)
        {
            try
            {
                var mailTemplateModel = new Welcome
                {
                    FullName = fullName,
                    AccountName = "Doctor",
                    GetStartedLink = this.applicationConfiguration.ProviderPortalLink,
                    AndroidAppLink = this.applicationConfiguration.AndroidAppLink,
                    IOSAppLink = this.applicationConfiguration.IOSAppLink,
                    MailTemplatesImagesLink = this.applicationConfiguration.MailTemplatesImagesLink
                };

                var emailMessage = new EmailMessage
                {
                    Importance = true,
                    Priority = true,
                    Subject = "Welcome to Careaxes",
                    Content = await this.templateHelper.RenderTemplateAsync("Welcome", mailTemplateModel)
                };

                emailMessage.ToAddresses.Add(new EmailAddress { Name = mailTemplateModel.FullName, Address = email });
                await this.emailHelper.SendAsync(emailMessage);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <inheritdoc />
        public async Task<bool> SendPatientWelcomeMailAsync(string email, string fullName)
        {
            try
            {
                var mailTemplateModel = new Welcome
                {
                    FullName = fullName,
                    AccountName = "Patient",
                    GetStartedLink = this.applicationConfiguration.WebsiteLink,
                    AndroidAppLink = this.applicationConfiguration.AndroidAppLink,
                    IOSAppLink = this.applicationConfiguration.IOSAppLink,
                    MailTemplatesImagesLink = this.applicationConfiguration.MailTemplatesImagesLink
                };

                var emailMessage = new EmailMessage
                {
                    Importance = true,
                    Priority = true,
                    Subject = "Welcome to Careaxes",
                    Content = await this.templateHelper.RenderTemplateAsync("Welcome", mailTemplateModel)
                };

                emailMessage.ToAddresses.Add(new EmailAddress { Name = mailTemplateModel.FullName, Address = email });
                await this.emailHelper.SendAsync(emailMessage);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <inheritdoc />
        public async Task<bool> SendCreatePasswordMailAsync(string email, string fullName, string createPasswordLink, string roleName)
        {
            try
            {
                var mailTemplateModel = new CreatePassword
                {
                    FullName = fullName,
                    AccountName = roleName,
                    CreatePasswordLink = createPasswordLink,
                    AndroidAppLink = this.applicationConfiguration.AndroidAppLink,
                    IOSAppLink = this.applicationConfiguration.IOSAppLink,
                    MailTemplatesImagesLink = this.applicationConfiguration.MailTemplatesImagesLink
                };

                var emailMessage = new EmailMessage
                {
                    Importance = true,
                    Priority = true,
                    Subject = "Welcome to Careaxes",
                    Content = await this.templateHelper.RenderTemplateAsync("CreatePassword", mailTemplateModel)
                };

                emailMessage.ToAddresses.Add(new EmailAddress { Name = mailTemplateModel.FullName, Address = email });
                await this.emailHelper.SendAsync(emailMessage);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <inheritdoc />
        public async Task<bool> SendBookAppointmentMailAsync(string email, string patientName, string accountName, string doctorName, string appointmentTime, string type)
        {
            try
            {
                var mailTemplateModel = new BookAppointment
                {
                    FullName = accountName == "Patient" ? patientName : doctorName,
                    AccountName = accountName,
                    Message = accountName == "Patient" ? $@"Your Appointment {type} with Dr.{doctorName}" : $@"Patient {patientName} {type} an appointment with you",
                    AppointmentTime = appointmentTime,
                    AndroidAppLink = this.applicationConfiguration.AndroidAppLink,
                    IOSAppLink = this.applicationConfiguration.IOSAppLink,
                    MailTemplatesImagesLink = this.applicationConfiguration.MailTemplatesImagesLink
                };
                var emailMessage = new EmailMessage
                {
                    Importance = true,
                    Priority = true,
                    Subject = "Careaxes Appointment Confirmation",
                    Content = await this.templateHelper.RenderTemplateAsync("BookAppointment", mailTemplateModel)
                };
                emailMessage.ToAddresses.Add(new EmailAddress { Name = mailTemplateModel.FullName, Address = email });
                await this.emailHelper.SendAsync(emailMessage);
                return true;
            }
            catch (Exception e)
            {
                e.Message.ToString();
                return false;
            }
        }

        /// <inheritdoc />
        public async Task<bool> SendMailAsync(string doctorName)
        {
            try
            {
                var mailTemplateModel = new EmailOTP
                {
                    FullName = "Vikas",
                    OTP = $@"Hi, Dr.{doctorName} registered with us, can you please verify and approve/reject it",
                    Email = "vikas@docassistant.net",
                    AndroidAppLink = this.applicationConfiguration.AndroidAppLink,
                    IOSAppLink = this.applicationConfiguration.IOSAppLink,
                    MailTemplatesImagesLink = this.applicationConfiguration.MailTemplatesImagesLink
                };

                var emailMessage = new EmailMessage
                {
                    Importance = true,
                    Priority = true,
                    Subject = "Hims Provider registration",
                    Content = await this.templateHelper.RenderTemplateAsync("BookAppointment", mailTemplateModel)
                };
                emailMessage.ToAddresses.Add(new EmailAddress { Name = mailTemplateModel.FullName, Address = this.applicationConfiguration.Email });
                await this.emailHelper.SendAsync(emailMessage);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <inheritdoc />
        public async Task<bool> SendWelcomeMailAsync(string email, string fullName, string password, string createPasswordLink)
        {
            try
            {
                // Welcome
                var welcomeModel = new Welcome
                {
                    FullName = fullName,
                    AccountName = "Patient",
                    AndroidAppLink = this.applicationConfiguration.AndroidAppLink,
                    IOSAppLink = this.applicationConfiguration.IOSAppLink,
                    GetStartedLink = this.applicationConfiguration.WebsiteLink,
                    MailTemplatesImagesLink = this.applicationConfiguration.MailTemplatesImagesLink
                };

                var emailMessage = new EmailMessage
                {
                    Importance = true,
                    Priority = true,
                    Subject = "Welcome to Careaxes",
                    Content = await this.templateHelper.RenderTemplateAsync("Welcome", welcomeModel)
                };

                emailMessage.ToAddresses.Add(new EmailAddress { Name = fullName, Address = email });
                await this.emailHelper.SendAsync(emailMessage);

                // Create Account
                if (string.IsNullOrEmpty(password))
                {
                    var createPasswordModel = new CreatePassword
                    {
                        FullName = fullName,
                        CreatePasswordLink = createPasswordLink,
                        AndroidAppLink = this.applicationConfiguration.AndroidAppLink,
                        IOSAppLink = this.applicationConfiguration.IOSAppLink,
                        MailTemplatesImagesLink = this.applicationConfiguration.MailTemplatesImagesLink
                    };

                    emailMessage = new EmailMessage
                    {
                        Importance = true,
                        Priority = true,
                        Subject = "Create your password in Careaxes",
                        Content = await this.templateHelper.RenderTemplateAsync("CreatePassword", createPasswordModel)
                    };

                    emailMessage.ToAddresses.Add(new EmailAddress { Name = fullName, Address = email });
                    await this.emailHelper.SendAsync(emailMessage);
                }

                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        /// <inheritdoc />
        public async Task<bool> ResetPasswordMailAsync(string email, string fullName, string accountType, string resetPasswordLink)
        {
            try
            {
                var mailTemplateModel = new ResetPassword
                {
                    FullName = fullName,
                    AccountName = accountType,
                    ResetPasswordLink = resetPasswordLink,
                    AndroidAppLink = this.applicationConfiguration.AndroidAppLink,
                    IOSAppLink = this.applicationConfiguration.IOSAppLink,
                    MailTemplatesImagesLink = this.applicationConfiguration.MailTemplatesImagesLink
                };

                var emailMessage = new EmailMessage
                {
                    Importance = true,
                    Priority = true,
                    Subject = "Reset your password in Careaxes",
                    Content = await this.templateHelper.RenderTemplateAsync("ResetPassword", mailTemplateModel)
                };

                emailMessage.ToAddresses.Add(new EmailAddress { Name = fullName, Address = email });
                await this.emailHelper.SendAsync(emailMessage);

                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <inheritdoc />
        public async Task<bool> SendPaymentMailAsync(string email, string fullName, string paymentLink)
        {
            try
            {
                var mailTemplateModel = new PayoutSmartSend
                {
                    FullName = fullName,
                    AccountName = "Provider",
                    PaymentLink = paymentLink,
                    AndroidAppLink = this.applicationConfiguration.AndroidAppLink,
                    IOSAppLink = this.applicationConfiguration.IOSAppLink,
                    MailTemplatesImagesLink = this.applicationConfiguration.MailTemplatesImagesLink
                };
                var emailMessage = new EmailMessage
                {
                    Importance = true,
                    Priority = true,
                    Subject = "Careaxes Payment Disburse",
                    Content = await this.templateHelper.RenderTemplateAsync("SmartSend", mailTemplateModel)
                };
                emailMessage.ToAddresses.Add(new EmailAddress { Name = mailTemplateModel.FullName, Address = email });
                await this.emailHelper.SendAsync(emailMessage);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <inheritdoc />
        public async Task<bool> SendAlertEmailToSupport(IEnumerable<AccountModel> model)
        {
            try
            {
                var mobile = "";
                var description = "";
                var patientName = "";
                int i = 0;
                foreach (var item in model)
                {
                    if (i == 0)
                    {
                        mobile = item.Mobile;
                        description = item.Description;
                        patientName = item.RoleName;
                        break;
                    }
                    i++;
                }
                var mailTemplateModel = new EmailOTP
                {
                    AndroidAppLink = this.applicationConfiguration.AndroidAppLink,
                    IOSAppLink = this.applicationConfiguration.IOSAppLink,
                    MailTemplatesImagesLink = this.applicationConfiguration.MailTemplatesImagesLink,
                    Mobile = mobile,
                    Description = description,
                    UserName = patientName
                };

                var emailMessage = new EmailMessage
                {
                    Importance = true,
                    Priority = true,
                    Subject = "Careaxes Ticket Alert",
                    Content = await this.templateHelper.RenderTemplateAsync("TicketReminder", mailTemplateModel)
                };

                foreach (var accountModel in model)
                {
                    emailMessage.ToAddresses.Add(new EmailAddress { Name = accountModel.FullName, Address = accountModel.Email });
                }

                await this.emailHelper.SendAsync(emailMessage);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <inheritdoc />
        public async Task<bool> SendAppLinksAsync(string email)
        {
            try
            {
                var mailTemplateModel = new BookAppointment
                {
                    AccountName = "",
                    FullName = "",
                    AppointmentTime = "",
                    AndroidAppLink = this.applicationConfiguration.AndroidAppLink,
                    IOSAppLink = this.applicationConfiguration.IOSAppLink,
                    MailTemplatesImagesLink = this.applicationConfiguration.MailTemplatesImagesLink
                };

                var emailMessage = new EmailMessage
                {
                    Importance = true,
                    Priority = true,
                    Subject = "Mobile App link",
                    Content = await this.templateHelper.RenderTemplateAsync("GetLinksToEmail", mailTemplateModel)
                };

                emailMessage.ToAddresses.Add(new EmailAddress { Name = mailTemplateModel.FullName, Address = email });
                await this.emailHelper.SendAsync(emailMessage);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <inheritdoc />
        public async Task<bool> SendAssignEmailToSupport(Tickets ticket)
        {
            try
            {
                ticket.MailTemplatesImagesLink = this.applicationConfiguration.MailTemplatesImagesLink;
                var emailMessage = new EmailMessage
                {
                    Importance = true,
                    Priority = true,
                    Subject = "Careaxes Ticket Alert",
                    Content = await this.templateHelper.RenderTemplateAsync("TicketAssign", ticket)
                };

                foreach (var accountModel in ticket.SupportUsers)
                {
                    emailMessage.ToAddresses.Add(new EmailAddress { Name = accountModel.FullName, Address = accountModel.Email });
                }

                await this.emailHelper.SendAsync(emailMessage);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <inheritdoc />
        public async Task<bool> SendExceptionLogEmailToSupport(IEnumerable<AccountModel> supportUsers, string logfrom, string errorMessage)
        {
            try
            {
                var mailTemplateModel = new ExceptionLogInfo
                {
                    LogFrom = logfrom,
                    ErrorMessage = errorMessage,
                    LogDate = DateTime.Now
                };

                var emailMessage = new EmailMessage
                {
                    Importance = true,
                    Priority = true,
                    Subject = $@"Exception occurs in {this.runningEnvironment.CurrentEnvironment}: {logfrom}",
                    Content = errorMessage
                };

                foreach (var accountModel in supportUsers)
                {
                    emailMessage.ToAddresses.Add(new EmailAddress { Name = accountModel.FullName, Address = accountModel.Email });
                }

                await this.emailHelper.SendAsync(emailMessage);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

       
        /// <inheritdoc />
        public async Task<bool> SendPharmacyMailAsync(IEnumerable<AccountModel> emails, ProductEmailModel model)
        {
            try
            {
                var emailMessage = new EmailMessage
                {
                    Importance = true,
                    Priority = true,
                    Subject = "New Purchase Bill Added",
                    Content = await this.templateHelper.RenderTemplateAsync("PharmacyPurchaseEmail", model)
                };
                foreach (var email in emails)
                {
                    emailMessage.ToAddresses.Add(new EmailAddress { Address = email.Email });
                }
                await this.emailHelper.SendAsync(emailMessage);
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        /// <inheritdoc />
        public async Task<bool> SendFinalBillEmailAsync(IEnumerable<AccountModel> emails, PharmacyBillReportModel model)
        {
            try
            {
                var emailMessage = new EmailMessage
                {
                    Importance = true,
                    Priority = true,
                    Subject = "Final Bill Report",
                    Content = await this.templateHelper.RenderTemplateAsync("PharmacyFinalBillEmail", model)
                };
                foreach (var email in emails)
                {
                    emailMessage.ToAddresses.Add(new EmailAddress { Address = email.Email });
                }
                await this.emailHelper.SendAsync(emailMessage);
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

    }
}