using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Infrastructure.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
using Kavenegar;

namespace CMSMicroservice.Infrastructure.Services.Monitoring;

/// <summary>
/// پیاده‌سازی UserNotificationService با Email (SMTP) و SMS (کاوه‌نگار)
/// </summary>
public class UserNotificationService : IUserNotificationService
{
    private readonly IApplicationDbContext _context;
    private readonly ILogger<UserNotificationService> _logger;
    private readonly EmailSettings _emailSettings;
    private readonly SmsSettings _smsSettings;
    private readonly KavenegarApi? _kavenegarApi;

    public UserNotificationService(
        IApplicationDbContext context,
        ILogger<UserNotificationService> logger,
        IOptions<EmailSettings> emailSettings,
        IOptions<SmsSettings> smsSettings)
    {
        _context = context;
        _logger = logger;
        _emailSettings = emailSettings.Value;
        _smsSettings = smsSettings.Value;

        // Initialize Kavenegar API
        if (_smsSettings.Enabled && !string.IsNullOrEmpty(_smsSettings.KavenegarApiKey))
        {
            try
            {
                _kavenegarApi = new KavenegarApi(_smsSettings.KavenegarApiKey);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to initialize Kavenegar API");
            }
        }
    }

    public async Task SendCommissionReceivedNotificationAsync(
        long userId,
        decimal amount,
        int weekNumber,
        string? packageName = null,
        CancellationToken cancellationToken = default)
    {
        _logger.LogInformation(
            "📧 Sending commission notification: User={UserId}, Amount={Amount}, Week={WeekNumber}",
            userId, amount, weekNumber);

        try
        {
            // Get user info from database
            var user = await _context.Users.FindAsync(new object[] { userId }, cancellationToken);
            if (user == null)
            {
                _logger.LogWarning("User {UserId} not found", userId);
                return;
            }

            var userFullName = $"{user.FirstName} {user.LastName}".Trim();
            if (string.IsNullOrEmpty(userFullName)) userFullName = "کاربر عزیز";
            
            var formattedAmount = amount.ToString("N0", new System.Globalization.CultureInfo("fa-IR"));
            var packageInfo = !string.IsNullOrEmpty(packageName) ? $" ({packageName})" : "";

            // Send Email
            if (_emailSettings.Enabled && !string.IsNullOrEmpty(user.Email))
            {
                var emailSubject = $"واریز کمیسیون هفته {weekNumber}{packageInfo}";
                var emailBody = "<div dir='rtl' style='font-family: Tahoma, Arial; text-align: right;'>" +
                    $"<h2>سلام {userFullName}</h2>" +
                    $"<p>کمیسیون هفته {weekNumber} شما{packageInfo} به مبلغ <strong>{formattedAmount} تومان</strong> به کیف پول شما واریز شد.</p>" +
                    "<p>از اعتماد شما سپاسگزاریم.</p>" +
                    "<hr/>" +
                    "<p style='color: #666; font-size: 12px;'>FourSat - سیستم مدیریت باشگاه مشتریان</p>" +
                    "</div>";
                
                await SendEmailAsync(
                    toEmail: user.Email,
                    toName: userFullName,
                    subject: emailSubject,
                    body: emailBody,
                    cancellationToken: cancellationToken);
            }

            // Send SMS
            if (_smsSettings.Enabled && !string.IsNullOrEmpty(user.Mobile))
            {
                await SendSmsAsync(
                    phoneNumber: user.Mobile,
                    message: $"سلام {userFullName}\nکمیسیون هفته {weekNumber} شما{packageInfo} به مبلغ {formattedAmount} تومان واریز شد.\nFourSat",
                    cancellationToken: cancellationToken);
            }

            _logger.LogInformation("✅ Notification sent successfully to User {UserId}", userId);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "❌ Failed to send commission notification to User {UserId}", userId);
        }
    }

    public async Task SendClubActivationNotificationAsync(
        long userId,
        string? packageName = null,
        CancellationToken cancellationToken = default)
    {
        _logger.LogInformation("🎉 Sending club activation notification: User={UserId}", userId);

        try
        {
            var user = await _context.Users.FindAsync(new object[] { userId }, cancellationToken);
            if (user == null) return;

            var userFullName = $"{user.FirstName} {user.LastName}".Trim();
            if (string.IsNullOrEmpty(userFullName)) userFullName = "کاربر عزیز";
            var packageInfo = !string.IsNullOrEmpty(packageName) ? $" با {packageName}" : "";

            // Send Email
            if (_emailSettings.Enabled && !string.IsNullOrEmpty(user.Email))
            {
                var emailSubject = "فعال‌سازی باشگاه مشتریان FourSat";
                var emailBody = "<div dir='rtl' style='font-family: Tahoma, Arial; text-align: right;'>" +
                    $"<h2>تبریک {userFullName}!</h2>" +
                    $"<p>عضویت شما در <strong>باشگاه مشتریان FourSat</strong>{packageInfo} با موفقیت فعال شد.</p>" +
                    "<p>از این پس می‌توانید از مزایای ویژه باشگاه بهره‌مند شوید.</p>" +
                    "<hr/>" +
                    "<p style='color: #666; font-size: 12px;'>FourSat - سیستم مدیریت باشگاه مشتریان</p>" +
                    "</div>";
                
                await SendEmailAsync(
                    toEmail: user.Email,
                    toName: userFullName,
                    subject: emailSubject,
                    body: emailBody,
                    cancellationToken: cancellationToken);
            }

            // Send SMS
            if (_smsSettings.Enabled && !string.IsNullOrEmpty(user.Mobile))
            {
                await SendSmsAsync(
                    phoneNumber: user.Mobile,
                    message: $"تبریک! عضویت شما در باشگاه مشتریان FourSat{packageInfo} فعال شد.",
                    cancellationToken: cancellationToken);
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to send club activation notification to User {UserId}", userId);
        }
    }

    public async Task SendPayoutErrorNotificationAsync(
        long userId,
        string errorMessage,
        string? packageName = null,
        CancellationToken cancellationToken = default)
    {
        _logger.LogWarning(
            "⚠️ Sending payout error notification: User={UserId}, Error={Error}",
            userId, errorMessage);

        try
        {
            var user = await _context.Users.FindAsync(new object[] { userId }, cancellationToken);
            if (user == null) return;

            var userFullName = $"{user.FirstName} {user.LastName}".Trim();
            if (string.IsNullOrEmpty(userFullName)) userFullName = "کاربر عزیز";

            // Send Email
            if (_emailSettings.Enabled && !string.IsNullOrEmpty(user.Email))
            {
                var emailSubject = "خطا در واریز کمیسیون";
                var emailBody = "<div dir='rtl' style='font-family: Tahoma, Arial; text-align: right;'>" +
                    $"<h2>سلام {userFullName}</h2>" +
                    "<p>متأسفانه در واریز کمیسیون شما خطایی رخ داده است:</p>" +
                    $"<p style='color: red;'><strong>{errorMessage}</strong></p>" +
                    "<p>لطفاً با پشتیبانی تماس بگیرید.</p>" +
                    "<hr/>" +
                    "<p style='color: #666; font-size: 12px;'>FourSat - سیستم مدیریت باشگاه مشتریان</p>" +
                    "</div>";
                
                await SendEmailAsync(
                    toEmail: user.Email,
                    toName: userFullName,
                    subject: emailSubject,
                    body: emailBody,
                    cancellationToken: cancellationToken);
            }

            // Send SMS
            if (_smsSettings.Enabled && !string.IsNullOrEmpty(user.Mobile))
            {
                await SendSmsAsync(
                    phoneNumber: user.Mobile,
                    message: $"خطا در واریز کمیسیون: {errorMessage}\nلطفاً با پشتیبانی تماس بگیرید.",
                    cancellationToken: cancellationToken);
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to send payout error notification to User {UserId}", userId);
        }
    }

    #region Private Helper Methods

    private async Task SendEmailAsync(
        string toEmail,
        string toName,
        string subject,
        string body,
        CancellationToken cancellationToken = default)
    {
        if (!_emailSettings.Enabled)
        {
            _logger.LogInformation("Email disabled in settings, skipping email to {Email}", toEmail);
            return;
        }

        try
        {
            var message = new MimeMessage();
            message.From.Add(new MailboxAddress(_emailSettings.FromName, _emailSettings.FromEmail));
            message.To.Add(new MailboxAddress(toName, toEmail));
            message.Subject = subject;

            var bodyBuilder = new BodyBuilder
            {
                HtmlBody = body
            };
            message.Body = bodyBuilder.ToMessageBody();

            using var client = new SmtpClient();
            await client.ConnectAsync(
                _emailSettings.SmtpHost,
                _emailSettings.SmtpPort,
                _emailSettings.EnableSsl ? SecureSocketOptions.StartTls : SecureSocketOptions.None,
                cancellationToken);

            if (!string.IsNullOrEmpty(_emailSettings.SmtpUsername))
            {
                await client.AuthenticateAsync(_emailSettings.SmtpUsername, _emailSettings.SmtpPassword, cancellationToken);
            }

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

            _logger.LogInformation("📧 Email sent to {Email}: {Subject}", toEmail, subject);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "❌ Failed to send email to {Email}", toEmail);
            throw;
        }
    }

    private async Task SendSmsAsync(
        string phoneNumber,
        string message,
        CancellationToken cancellationToken = default)
    {
        if (!_smsSettings.Enabled)
        {
            _logger.LogInformation("SMS disabled in settings, skipping SMS to {PhoneNumber}", phoneNumber);
            return;
        }

        if (_kavenegarApi == null)
        {
            _logger.LogWarning("Kavenegar API not initialized, cannot send SMS");
            return;
        }

        try
        {
            // Kavenegar Send is synchronous
            await Task.Run(() =>
            {
                var result = _kavenegarApi.Send(
                    sender: _smsSettings.Sender,
                    receptor: phoneNumber,
                    message: message);

                _logger.LogInformation("📱 SMS sent to {PhoneNumber}: {MessageId}", phoneNumber, result.Messageid);
            }, cancellationToken);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "❌ Failed to send SMS to {PhoneNumber}", phoneNumber);
            throw;
        }
    }

    #endregion
}
