using CPRNIMS.Infrastructure.ViewModel.Common; using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Mail; using System.Text; using System.Threading.Tasks; namespace CPRNIMS.Infrastructure.Helper { public class SMTPHelper { private readonly IConfiguration _configuration; private readonly EmailValidationService _emailValidator; public SMTPHelper(EmailValidationService emailValidator, IConfiguration configuration) { _emailValidator = emailValidator; _configuration = configuration; } public bool IsAuthError { get; private set; } public string EMailTemplate(string contentPath) { // Get the physical path to the template folder string templateFolderPath = Path.Combine(contentPath); // Read the content of the template file string body = File.ReadAllText(templateFolderPath); return body; } public string GenerateOTP() { const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; var random = new Random(); var otp = new string(Enumerable.Repeat(chars, 8) .Select(s => s[random.Next(s.Length)]) .ToArray()); return otp; } public async Task SendEmailAsync(EmailMessageDetailsVM emailMessageBody) { try { if (string.IsNullOrWhiteSpace(emailMessageBody?.Recipient)) { Console.WriteLine("Email address is null or empty. Cannot send email."); return false; } // 👇 Reads live from appsettings.json every time — picks up changes without restart var excludedEmails = new HashSet( _configuration.GetSection("Canvass:EmailSettings:ExcludedEmails") .Get>() ?? new List(), StringComparer.OrdinalIgnoreCase ); using (MailMessage myMessage = new MailMessage()) { var recipientList = emailMessageBody.Recipient .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries) .Select(r => r.Trim()) .Where(r => !string.IsNullOrWhiteSpace(r)) .Where(r => { if (excludedEmails.Contains(r)) { Console.WriteLine($"[Excluded] Skipping: {r}"); return false; } return true; }); // Validate remaining recipients concurrently var validationResults = await _emailValidator.ValidateBatchAsync(recipientList); foreach (var result in validationResults) { if (result.IsValid) myMessage.To.Add(result.Email); else Console.WriteLine($"[Skipped] {result.Reason}: {result.Email}"); } if (myMessage.To.Count == 0) { Console.WriteLine("No valid recipients after exclusion/validation. Aborting."); return false; } myMessage.Sender = new MailAddress(emailMessageBody.SenderEmail); myMessage.From = new MailAddress(emailMessageBody.SenderEmail, emailMessageBody.DisplayName); // CC with exclusion too if (!string.IsNullOrWhiteSpace(emailMessageBody.CC)) { var ccList = emailMessageBody.CC .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries) .Select(c => c.Trim()) .Where(c => !string.IsNullOrWhiteSpace(c)) .Where(c => { if (excludedEmails.Contains(c)) { Console.WriteLine($"[Excluded CC] Skipping: {c}"); return false; } return true; }); var ccValidationResults = await _emailValidator.ValidateBatchAsync(ccList); foreach (var result in ccValidationResults) { if (result.IsValid) myMessage.CC.Add(result.Email); else Console.WriteLine($"[Skipped CC] {result.Reason}: {result.Email}"); } } myMessage.Subject = emailMessageBody.Subject; myMessage.Body = emailMessageBody.Message; myMessage.IsBodyHtml = true; if (emailMessageBody.IsCanvass && File.Exists(emailMessageBody.AttachPath)) { Attachment pdfAttachment = new Attachment(emailMessageBody.AttachPath); pdfAttachment.Name = Path.GetFileName(emailMessageBody.AttachPath); myMessage.Attachments.Add(pdfAttachment); } using (SmtpClient smtp = new SmtpClient(emailMessageBody.Server)) { smtp.Port = emailMessageBody.OutGoingPort; smtp.UseDefaultCredentials = emailMessageBody.IsSuccess; smtp.Credentials = new NetworkCredential(emailMessageBody.UserName, emailMessageBody.NewPassword); smtp.EnableSsl = true; try { await smtp.SendMailAsync(myMessage); Console.WriteLine($"Email sent successfully to {myMessage.To.Count} recipient(s)."); return true; } catch (Exception ex) { var message = ex.InnerException?.ToString() ?? ex.Message; Console.WriteLine($"Error sending email: {message}"); return false; } } } } catch (Exception ex) { IsAuthError = true; var message = ex.InnerException?.ToString() ?? ex.Message; Console.WriteLine($"Error in SendEmailAsync: {message}"); return false; } } } }