using System.Net;
using System.Net.Mail;
using ColaFlow.Modules.Identity.Application.Services;
using ColaFlow.Modules.Identity.Domain.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace ColaFlow.Modules.Identity.Infrastructure.Services;

/// <summary>
/// SMTP-based email service for production use
/// </summary>
public sealed class SmtpEmailService : IEmailService
{
    private readonly ILogger<SmtpEmailService> _logger;
    private readonly IConfiguration _configuration;

    public SmtpEmailService(
        ILogger<SmtpEmailService> logger,
        IConfiguration configuration)
    {
        _logger = logger;
        _configuration = configuration;
    }

    public async Task<bool> SendEmailAsync(EmailMessage message, CancellationToken cancellationToken = default)
    {
        try
        {
            var smtpHost = _configuration["Email:Smtp:Host"];
            var smtpPort = int.Parse(_configuration["Email:Smtp:Port"] ?? "587");
            var smtpUsername = _configuration["Email:Smtp:Username"];
            var smtpPassword = _configuration["Email:Smtp:Password"];
            var enableSsl = bool.Parse(_configuration["Email:Smtp:EnableSsl"] ?? "true");

            var defaultFromEmail = _configuration["Email:From"] ?? "noreply@colaflow.local";
            var defaultFromName = _configuration["Email:FromName"] ?? "ColaFlow";

            using var smtpClient = new SmtpClient(smtpHost, smtpPort)
            {
                Credentials = new NetworkCredential(smtpUsername, smtpPassword),
                EnableSsl = enableSsl
            };

            using var mailMessage = new MailMessage
            {
                From = new MailAddress(
                    message.FromEmail ?? defaultFromEmail,
                    message.FromName ?? defaultFromName),
                Subject = message.Subject,
                Body = message.HtmlBody,
                IsBodyHtml = true
            };

            mailMessage.To.Add(message.To);

            // Add plain text alternative if provided
            if (!string.IsNullOrEmpty(message.PlainTextBody))
            {
                var plainView = AlternateView.CreateAlternateViewFromString(
                    message.PlainTextBody,
                    null,
                    "text/plain");
                mailMessage.AlternateViews.Add(plainView);
            }

            await smtpClient.SendMailAsync(mailMessage, cancellationToken);

            _logger.LogInformation(
                "Email sent successfully to {To} with subject: {Subject}",
                message.To,
                message.Subject);

            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(
                ex,
                "Failed to send email to {To} with subject: {Subject}",
                message.To,
                message.Subject);

            return false;
        }
    }
}
