using Application.Abstractions.Messaging.Email;
using Infrastructure.Persistence;
using MailKit.Net.Smtp;
using MailKit.Security;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MimeKit;
using SharedKernel;

namespace Infrastructure.Messaging.Email
{
    public class MailService : IMailService
    {
        private readonly AppSettings.SmtpSection _smtp;
        private readonly AppDbContext _db;
        private readonly ILogger<MailService> _logger;

        public MailService(IOptions<AppSettings> options, AppDbContext db, ILogger<MailService> logger)
        {
            _smtp = options.Value.SMTP;
            _db = db;
            _logger = logger;
        }

        public async Task SendAsync(SendData data, CancellationToken ct = default)
        {
            _logger.LogInformation("Sending email to {ToAddress} with subject {Subject}", data.ToAddress, data.Subject);

            var message = new MimeMessage();
            message.From.Add(new MailboxAddress(_smtp.FromName, _smtp.FromEmail));
            message.To.Add(MailboxAddress.Parse(data.ToAddress));
            message.Subject = data.Subject;

            var body = new BodyBuilder
            {
                HtmlBody = data.MessageHtml,
                TextBody = data.MessageText
            };

            message.Body = body.ToMessageBody();

            using var client = new SmtpClient();
            var secure = _smtp.UseStartTls ? SecureSocketOptions.StartTls : SecureSocketOptions.Auto;

            await client.ConnectAsync(_smtp.Host, _smtp.Port, secure, ct);

            if (!string.IsNullOrWhiteSpace(_smtp.User))
            {
                await client.AuthenticateAsync(_smtp.User, _smtp.Password, ct);
            }

            await client.SendAsync(message, ct);
            await client.DisconnectAsync(true, ct);

            _logger.LogInformation("Email sent to {ToAddress} with subject {Subject}", data.ToAddress, data.Subject);
        }
    }
}