using Hangfire;
using MediatR;
using Microsoft.Extensions.Logging;
using CMSMicroservice.Application.DayaLoanCQ.Commands.CheckDayaLoanStatus;
using CMSMicroservice.Application.DayaLoanCQ.Commands.ProcessDayaLoanApproval;
using CMSMicroservice.Domain.Enums;
using Microsoft.EntityFrameworkCore;
using CMSMicroservice.Infrastructure.Persistence;
using System.Linq;

namespace CMSMicroservice.WebApi.Workers;

/// <summary>
/// Worker برای استعلام خودکار وضعیت وام دایا (هر 15 دقیقه)
/// </summary>
public class DayaLoanCheckWorker
{
    private readonly IMediator _mediator;
    private readonly ApplicationDbContext _context;
    private readonly ILogger<DayaLoanCheckWorker> _logger;

    public DayaLoanCheckWorker(
        IMediator mediator,
        ApplicationDbContext context,
        ILogger<DayaLoanCheckWorker> logger)
    {
        _mediator = mediator;
        _context = context;
        _logger = logger;
    }

    /// <summary>
    /// متد اصلی که توسط Hangfire فراخوانی می‌شود
    /// </summary>
    [AutomaticRetry(Attempts = 3)]
    public async Task ExecuteAsync()
    {
        _logger.LogInformation("DayaLoanCheckWorker started at {Time}", DateTime.UtcNow);
        
        try
        {
            // پیدا کردن کاربرانی که اعتبار دایا را دریافت نکرده‌اند
            var pendingUsers = await _context.Users
                .Where(u => 
                    u.HasReceivedDayaCredit == false &&
                    u.NationalCode != null &&
                    u.NationalCode != "")
                .Select(u => new { u.Id, u.NationalCode })
                .ToListAsync();
            
            if (!pendingUsers.Any())
            {
                _logger.LogInformation("No pending users found for Daya loan check");
                return;
            }
            
            _logger.LogInformation("Found {Count} users with pending Daya loan status", pendingUsers.Count);
            
            // استعلام از دایا
            var checkCommand = new CheckDayaLoanStatusCommand
            {
                NationalCodes = pendingUsers.Select(u => u.NationalCode).ToList()
            };
            
            var checkResult = await _mediator.Send(checkCommand);
            
            // پردازش نتایج
            foreach (var result in checkResult.Results)
            {
                // فقط وضعیت PendingReceive را پردازش می‌کنیم (یعنی وام درخواست شده)
                if (result.Status == DayaLoanStatus.PendingReceive && !string.IsNullOrEmpty(result.ContractNumber))
                {
                    var user = pendingUsers.FirstOrDefault(u => u.NationalCode == result.NationalCode);
                    if (user != null)
                    {
                        try
                        {
                            // پردازش تایید وام و شارژ کیف پول
                            var processCommand = new ProcessDayaLoanApprovalCommand
                            {
                                UserId = user.Id,
                                ContractNumber = result.ContractNumber
                            };
                            
                            var processResult = await _mediator.Send(processCommand);
                            
                            _logger.LogInformation("Daya loan processed for user {UserId}. Contract: {ContractNumber}", 
                                user.Id, result.ContractNumber);
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError(ex, "Error processing Daya loan for user {UserId}", user.Id);
                        }
                    }
                }
            }
            
            _logger.LogInformation("DayaLoanCheckWorker completed. Checked: {Total}, Processed: {Success}", 
                checkResult.TotalChecked, checkResult.SuccessCount);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error in DayaLoanCheckWorker");
            throw; // Hangfire will retry
        }
    }

    /// <summary>
    /// متد برای Schedule کردن Worker (هر 15 دقیقه)
    /// </summary>
    public static void Schedule(IRecurringJobManager recurringJobManager)
    {
        // هر 15 دقیقه: */15 * * * *
        recurringJobManager.AddOrUpdate<DayaLoanCheckWorker>(
            "daya-loan-check",
            worker => worker.ExecuteAsync(),
            "*/15 * * * *", // هر 15 دقیقه
            TimeZoneInfo.Utc
        );
    }
}
