using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Domain.Entities.Commission;
using CMSMicroservice.Domain.Entities.History;
using CMSMicroservice.Domain.Enums;
using Microsoft.Extensions.Logging;

namespace CMSMicroservice.Application.CommissionCQ.Commands.BulkCreditPayouts;

public class BulkCreditPayoutsCommandHandler : IRequestHandler<BulkCreditPayoutsCommand, BulkCreditPayoutsResult>
{
    private readonly IApplicationDbContext _context;
    private readonly ICurrentUserService _currentUser;
    private readonly ILogger<BulkCreditPayoutsCommandHandler> _logger;

    public BulkCreditPayoutsCommandHandler(
        IApplicationDbContext context,
        ICurrentUserService currentUser,
        ILogger<BulkCreditPayoutsCommandHandler> logger)
    {
        _context = context;
        _currentUser = currentUser;
        _logger = logger;
    }

    public async Task<BulkCreditPayoutsResult> Handle(BulkCreditPayoutsCommand request, CancellationToken cancellationToken)
    {
        var pendingPayouts = await _context.UserCommissionPayouts
            .Where(p => p.WeekDefinitionId == request.WeekDefinitionId
                     && p.Status == CommissionPayoutStatus.Pending
                     && !p.IsDeleted)
            .ToListAsync(cancellationToken);

        if (!pendingPayouts.Any())
        {
            return new BulkCreditPayoutsResult { CreditedCount = 0, TotalCredited = 0 };
        }

        var performedBy = _currentUser.GetPerformedBy() ?? "System";
        var now = DateTime.UtcNow;

        var payoutHistories = new List<CommissionPayoutHistory>();
        var creditedCount = 0;
        long totalCredited = 0;

        foreach (var payout in pendingPayouts)
        {
            payout.Status = CommissionPayoutStatus.Paid;
            payout.PaidAt = now;
            payout.LastModified = now;

            payoutHistories.Add(new CommissionPayoutHistory
            {
                UserCommissionPayoutId = payout.Id, 
                UserId = payout.UserId,
                WeekDefinitionId = payout.WeekDefinitionId,
                AmountBefore = payout.TotalAmount,
                AmountAfter = payout.TotalAmount,
                OldStatus = CommissionPayoutStatus.Pending,
                NewStatus = CommissionPayoutStatus.Paid,
                Action = CommissionPayoutAction.Paid,
                PerformedBy = performedBy,
                Reason = $"تایید پرداخت دسته‌جمعی کمیسیون هفته {payout.WeekDefinitionId} توسط {performedBy}"
            });

            creditedCount++;
            totalCredited += payout.TotalAmount;
        }

        await _context.CommissionPayoutHistories.AddRangeAsync(payoutHistories, cancellationToken);
        await _context.SaveChangesAsync(cancellationToken);

        _logger.LogInformation(
            "BulkCreditPayouts completed: Week={WeekId}, Credited={Count}, TotalAmount={Total}, By={By}",
            request.WeekDefinitionId, creditedCount, totalCredited, performedBy);

        return new BulkCreditPayoutsResult
        {
            CreditedCount = creditedCount,
            TotalCredited = totalCredited
        };
    }
}
