using Hangfire;
using MediatR;
using Microsoft.Extensions.Logging;
using CMSMicroservice.Application.DayaLoanCQ.Commands.CheckAndProcessDayaLoans;
using Microsoft.EntityFrameworkCore;
using CMSMicroservice.Infrastructure.Persistence;
using System.Linq;

namespace CMSMicroservice.WebApi.Workers;

/// <summary>
/// Worker برای استعلام خودکار وضعیت وام دایا و پردازش خودکار (هر 20 دقیقه)
/// </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.Now);
        
        try
        {
            // پیدا کردن کاربرانی که:
            // 1. اعتبار دایا را دریافت نکرده‌اند
            // 2. کد ملی دارند
            var pendingUsers = await _context.Users
                .Where(u => 
                    u.HasReceivedDayaCredit == false &&
                    u.NationalCode != null &&
                    u.NationalCode != "")
                .Select(u => 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);
            
            // استعلام و پردازش یکجا با Command یکپارچه
            var command = new CheckAndProcessDayaLoansCommand
            {
                NationalCodes = pendingUsers
            };
            
            var result = await _mediator.Send(command);
            
            _logger.LogInformation(
                "DayaLoanCheckWorker completed. Checked: {Total}, WithContract: {WithContract}, Processed: {Processed}", 
                result.TotalChecked, 
                result.WithContractCount, 
                result.ProcessedCount);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error in DayaLoanCheckWorker");
            throw; // Hangfire will retry
        }
    }

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