using System.Net;
using System.Net.Mail;
using ColaFlow.Modules.Identity.Application.Services;
using ColaFlow.Modules.Identity.Domain.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace ColaFlow.Modules.Identity.Infrastructure.Services;
///
/// SMTP-based email service for production use
///
public sealed class SmtpEmailService : IEmailService
{
private readonly ILogger _logger;
private readonly IConfiguration _configuration;
public SmtpEmailService(
ILogger logger,
IConfiguration configuration)
{
_logger = logger;
_configuration = configuration;
}
public async Task SendEmailAsync(EmailMessage message, CancellationToken cancellationToken = default)
{
try
{
var smtpHost = _configuration["Email:Smtp:Host"];
var smtpPort = int.Parse(_configuration["Email:Smtp:Port"] ?? "587");
var smtpUsername = _configuration["Email:Smtp:Username"];
var smtpPassword = _configuration["Email:Smtp:Password"];
var enableSsl = bool.Parse(_configuration["Email:Smtp:EnableSsl"] ?? "true");
var defaultFromEmail = _configuration["Email:From"] ?? "noreply@colaflow.local";
var defaultFromName = _configuration["Email:FromName"] ?? "ColaFlow";
using var smtpClient = new SmtpClient(smtpHost, smtpPort)
{
Credentials = new NetworkCredential(smtpUsername, smtpPassword),
EnableSsl = enableSsl
};
using var mailMessage = new MailMessage
{
From = new MailAddress(
message.FromEmail ?? defaultFromEmail,
message.FromName ?? defaultFromName),
Subject = message.Subject,
Body = message.HtmlBody,
IsBodyHtml = true
};
mailMessage.To.Add(message.To);
// Add plain text alternative if provided
if (!string.IsNullOrEmpty(message.PlainTextBody))
{
var plainView = AlternateView.CreateAlternateViewFromString(
message.PlainTextBody,
null,
"text/plain");
mailMessage.AlternateViews.Add(plainView);
}
await smtpClient.SendMailAsync(mailMessage, cancellationToken);
_logger.LogInformation(
"Email sent successfully to {To} with subject: {Subject}",
message.To,
message.Subject);
return true;
}
catch (Exception ex)
{
_logger.LogError(
ex,
"Failed to send email to {To} with subject: {Subject}",
message.To,
message.Subject);
return false;
}
}
}