using System.Net;
using System.Net.Mail;
using Microsoft.Extensions.Options;
using TrackQrApi.Features.Email.Templates;

namespace TrackQrApi.Features.Email.Services;

public class SmtpEmailService : IEmailService
{
    private readonly ILogger<SmtpEmailService> _logger;
    private readonly EmailSettings _settings;

    public SmtpEmailService(IOptions<EmailSettings> settings, ILogger<SmtpEmailService> logger)
    {
        _settings = settings.Value;
        _logger = logger;
    }

    public async Task SendPasswordResetEmailAsync(string toEmail, string resetToken, CancellationToken ct = default)
    {
        var resetUrl = $"{_settings.BaseUrl}/reset-password?token={Uri.EscapeDataString(resetToken)}";
        var (subject, htmlBody, textBody) = EmailTemplates.PasswordReset(resetUrl);

        await SendEmailAsync(toEmail, subject, htmlBody, textBody, ct);
        _logger.LogInformation("Password reset email sent to {Email}", toEmail);
    }

    public async Task SendEmailVerificationAsync(string toEmail, string verificationToken,
        CancellationToken ct = default)
    {
        var verifyUrl = $"{_settings.BaseUrl}/verify-email?token={Uri.EscapeDataString(verificationToken)}";
        var (subject, htmlBody, textBody) = EmailTemplates.EmailVerification(verifyUrl);

        await SendEmailAsync(toEmail, subject, htmlBody, textBody, ct);
        _logger.LogInformation("Verification email sent to {Email}", toEmail);
    }

    public async Task SendWelcomeEmailAsync(string toEmail, string userName, CancellationToken ct = default)
    {
        var dashboardUrl = $"{_settings.BaseUrl}/dashboard";
        var (subject, htmlBody, textBody) = EmailTemplates.Welcome(userName, dashboardUrl);

        await SendEmailAsync(toEmail, subject, htmlBody, textBody, ct);
        _logger.LogInformation("Welcome email sent to {Email}", toEmail);
    }

    private async Task SendEmailAsync(string toEmail, string subject, string htmlBody, string textBody,
        CancellationToken ct)
    {
        if (_settings.Smtp == null)
        {
            _logger.LogWarning("SMTP settings not configured. Email not sent to {Email}", toEmail);
            return;
        }

        try
        {
            using var message = new MailMessage
            {
                From = new MailAddress(_settings.FromEmail, _settings.FromName),
                Subject = subject,
                IsBodyHtml = true,
                Body = htmlBody
            };

            message.To.Add(new MailAddress(toEmail));

            // Add plain text alternative
            var plainTextView = AlternateView.CreateAlternateViewFromString(textBody, null, "text/plain");
            var htmlView = AlternateView.CreateAlternateViewFromString(htmlBody, null, "text/html");
            message.AlternateViews.Add(plainTextView);
            message.AlternateViews.Add(htmlView);

            using var client = new SmtpClient(_settings.Smtp.Host, _settings.Smtp.Port)
            {
                EnableSsl = _settings.Smtp.UseSsl,
                DeliveryMethod = SmtpDeliveryMethod.Network
            };

            if (!string.IsNullOrEmpty(_settings.Smtp.Username))
                client.Credentials = new NetworkCredential(_settings.Smtp.Username, _settings.Smtp.Password);

            await client.SendMailAsync(message, ct);
            _logger.LogDebug("Email sent successfully to {Email}", toEmail);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to send email to {Email}", toEmail);
            throw;
        }
    }
}