namespace CMSMicroservice.Application.CommissionCQ.Commands.CalculateWeeklyCommissionPool;

public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<CalculateWeeklyCommissionPoolCommand, long>
{
    private readonly IApplicationDbContext _context;

    public CalculateWeeklyCommissionPoolCommandHandler(IApplicationDbContext context)
    {
        _context = context;
    }

    public async Task<long> Handle(CalculateWeeklyCommissionPoolCommand request, CancellationToken cancellationToken)
    {
        // بررسی وجود استخر قبلی
        var existingPool = await _context.WeeklyCommissionPools
            .FirstOrDefaultAsync(x => x.WeekNumber == request.WeekNumber, cancellationToken);

        if (existingPool != null && existingPool.IsCalculated && !request.ForceRecalculate)
        {
            throw new InvalidOperationException($"استخر کمیسیون هفته {request.WeekNumber} قبلاً محاسبه شده است");
        }

        // بررسی وجود تعادل‌های هفتگی
        var weeklyBalances = await _context.NetworkWeeklyBalances
            .Where(x => x.WeekNumber == request.WeekNumber)
            .ToListAsync(cancellationToken);

        if (!weeklyBalances.Any())
        {
            throw new InvalidOperationException($"تعادل‌های هفته {request.WeekNumber} هنوز محاسبه نشده است. ابتدا CalculateWeeklyBalances را اجرا کنید");
        }

        // محاسبه مجموع مشارکت‌ها در استخر
        var totalPoolAmount = weeklyBalances.Sum(x => x.WeeklyPoolContribution);

        // محاسبه مجموع Balances
        var totalBalances = weeklyBalances.Sum(x => x.TotalBalances);

        // محاسبه ارزش هر Balance (تقسیم صحیح برای ریال)
        long valuePerBalance = 0;
        if (totalBalances > 0)
        {
            valuePerBalance = totalPoolAmount / totalBalances;
        }

        if (existingPool != null)
        {
            // به‌روزرسانی
            existingPool.TotalPoolAmount = totalPoolAmount;
            existingPool.TotalBalances = totalBalances;
            existingPool.ValuePerBalance = valuePerBalance;
            existingPool.IsCalculated = true;
            existingPool.CalculatedAt = DateTime.UtcNow;

            _context.WeeklyCommissionPools.Update(existingPool);
        }
        else
        {
            // ایجاد جدید
            var pool = new WeeklyCommissionPool
            {
                WeekNumber = request.WeekNumber,
                TotalPoolAmount = totalPoolAmount,
                TotalBalances = totalBalances,
                ValuePerBalance = valuePerBalance,
                IsCalculated = true,
                CalculatedAt = DateTime.UtcNow
            };

            await _context.WeeklyCommissionPools.AddAsync(pool, cancellationToken);
            existingPool = pool;
        }

        await _context.SaveChangesAsync(cancellationToken);

        return existingPool.Id;
    }
}
