using System.Net;
using System.Net.Mail;

namespace JobTrackerApi.Services;

public interface IAppEmailSender
{
    Task SendAsync(string toEmail, string subject, string bodyText, CancellationToken cancellationToken = default);
}

public sealed class SmtpEmailSender : IAppEmailSender
{
    private readonly IEmailSettingsResolver _settings;
    private readonly ILogger<SmtpEmailSender> _logger;

    public SmtpEmailSender(IEmailSettingsResolver settings, ILogger<SmtpEmailSender> logger)
    {
        _settings = settings;
        _logger = logger;
    }

    public async Task SendAsync(string toEmail, string subject, string bodyText, CancellationToken cancellationToken = default)
    {
        var snapshot = await _settings.GetSnapshotAsync(cancellationToken);
        var host = snapshot.Host;
        var user = snapshot.User;
        var pass = snapshot.Password;
        var from = snapshot.From;
        var fromName = snapshot.FromName;
        var port = snapshot.Port;
        var enableSsl = snapshot.EnableSsl;
        var timeoutMs = snapshot.TimeoutMs;

        var enabled = snapshot.Enabled;
        if (!enabled)
        {
            _logger.LogWarning("Email sending is disabled. Suppressed email to {To} subject={Subject}", toEmail, subject);
            return;
        }

        if (string.IsNullOrWhiteSpace(host)) throw new InvalidOperationException("Email:SmtpHost is not configured.");
        if (string.IsNullOrWhiteSpace(from)) throw new InvalidOperationException("Email:From is not configured.");

        using var msg = new MailMessage();
        msg.From = new MailAddress(from, string.IsNullOrWhiteSpace(fromName) ? null : fromName);
        msg.To.Add(new MailAddress(toEmail));
        msg.Subject = subject;
        msg.Body = bodyText;
        msg.IsBodyHtml = false;

        using var smtp = new SmtpClient(host, port)
        {
            EnableSsl = enableSsl,
            DeliveryMethod = SmtpDeliveryMethod.Network,
            Timeout = timeoutMs,
        };

        if (!string.IsNullOrWhiteSpace(user))
        {
            smtp.Credentials = new NetworkCredential(user, pass);
        }

        await Task.Run(() => smtp.Send(msg), cancellationToken);
    }
}
