using System.Net;
using System.Net.Mail;
using MemberCenter.Application.Abstractions;
using MemberCenter.Application.Models.Admin;

namespace MemberCenter.Infrastructure.Services;

public sealed class SmtpEmailSender : IEmailSender
{
    private readonly ISecuritySettingsService _securitySettingsService;

    public SmtpEmailSender(ISecuritySettingsService securitySettingsService)
    {
        _securitySettingsService = securitySettingsService;
    }

    public async Task<int> SendAsync(string toEmail, string subject, string textBody, string? htmlBody = null)
    {
        var settings = await _securitySettingsService.GetSmtpSettingsAsync();
        Validate(settings);

        using var message = new MailMessage
        {
            Subject = subject,
            Body = htmlBody ?? textBody,
            IsBodyHtml = !string.IsNullOrWhiteSpace(htmlBody),
            From = new MailAddress(settings.SenderEmail, settings.SenderName)
        };
        message.To.Add(new MailAddress(toEmail));

        if (!string.IsNullOrWhiteSpace(textBody) && !string.IsNullOrWhiteSpace(htmlBody))
        {
            message.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(textBody, null, "text/plain"));
            message.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(htmlBody, null, "text/html"));
            message.Body = textBody;
            message.IsBodyHtml = false;
        }

        using var client = new SmtpClient(settings.RelayHost, settings.RelayPort)
        {
            EnableSsl = settings.UseSsl || settings.UseTls,
            DeliveryMethod = SmtpDeliveryMethod.Network,
            Timeout = Math.Max(1000, settings.TimeoutSeconds * 1000)
        };

        if (!string.IsNullOrWhiteSpace(settings.Username))
        {
            client.Credentials = new NetworkCredential(settings.Username, settings.Password);
        }

        await client.SendMailAsync(message);
        return 1;
    }

    private static void Validate(SmtpSettingsDto settings)
    {
        if (string.IsNullOrWhiteSpace(settings.RelayHost))
        {
            throw new InvalidOperationException("SMTP relay host is empty. Please save SMTP settings first.");
        }

        if (settings.UseTls && settings.UseSsl)
        {
            throw new InvalidOperationException("SMTP TLS and SSL cannot both be enabled.");
        }

        if (string.IsNullOrWhiteSpace(settings.SenderEmail))
        {
            throw new InvalidOperationException("Sender email is empty. Please save sender settings first.");
        }
    }
}
