using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;

namespace GerbilManagerWebAPI.Inbox
{
    /// <summary>
    /// Live Gmail sender over SMTP (App Password auth, STARTTLS). Builds a correctly-threaded
    /// reply so it lands in the same Gmail conversation. Gated on Julian's App Password
    /// (tests use a fake IGmailMailSender + assert BuildMimeMessage).
    /// </summary>
    public sealed class GmailMailSender : IGmailMailSender
    {
        public async Task SendAsync(MailConnection connection, OutgoingMail mail, CancellationToken ct = default)
        {
            var message = BuildMimeMessage(connection.GmailAddress, mail);
            using var client = new SmtpClient();
            await client.ConnectAsync("smtp.gmail.com", 587, SecureSocketOptions.StartTls, ct);
            await client.AuthenticateAsync(connection.GmailAddress, connection.AppPassword, ct);
            await client.SendAsync(message, ct);
            await client.DisconnectAsync(true, ct);
        }

        /// <summary>Builds the reply MimeMessage with In-Reply-To / References / Subject set for
        /// Gmail threading. Public so the threading headers are unit-testable without SMTP.</summary>
        public static MimeMessage BuildMimeMessage(string fromAddress, OutgoingMail mail)
        {
            var message = new MimeMessage();
            message.From.Add(MailboxAddress.Parse(fromAddress));
            message.To.Add(MailboxAddress.Parse(mail.To));
            message.Subject = mail.Subject;
            message.Body = new TextPart("plain") { Text = mail.Body };

            if (!string.IsNullOrWhiteSpace(mail.InReplyTo))
                message.InReplyTo = mail.InReplyTo;
            if (!string.IsNullOrWhiteSpace(mail.References))
                foreach (var id in mail.References.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
                    message.References.Add(id);

            return message;
        }
    }
}
