namespace CMSMicroservice.Application.ProductsCQ.Commands.BulkUpdateProductStock;

public class BulkUpdateProductStockCommandHandler : IRequestHandler<BulkUpdateProductStockCommand, BulkUpdateProductStockResponseDto>
{
    private readonly IApplicationDbContext _context;
    private readonly ILogger<BulkUpdateProductStockCommandHandler> _logger;

    public BulkUpdateProductStockCommandHandler(
        IApplicationDbContext context,
        ILogger<BulkUpdateProductStockCommandHandler> logger)
    {
        _context = context;
        _logger = logger;
    }

    public async Task<BulkUpdateProductStockResponseDto> Handle(BulkUpdateProductStockCommand request, CancellationToken cancellationToken)
    {
        var response = new BulkUpdateProductStockResponseDto();
        var productIds = request.Products.Select(p => p.ProductId).ToList();

        // دریافت محصولات از دیتابیس
        var products = await _context.Products
            .Where(p => productIds.Contains(p.Id))
            .ToListAsync(cancellationToken);

        var productDict = products.ToDictionary(p => p.Id);

        foreach (var update in request.Products)
        {
            try
            {
                if (!productDict.TryGetValue(update.ProductId, out var product))
                {
                    response.FailedCount++;
                    response.Errors.Add($"محصول با شناسه {update.ProductId} یافت نشد");
                    continue;
                }

                var oldStock = product.RemainingCount;

                // به‌روزرسانی موجودی بر اساس نوع
                switch (request.UpdateType)
                {
                    case StockUpdateType.Set:
                        product.RemainingCount = update.Quantity;
                        break;

                    case StockUpdateType.Add:
                        product.RemainingCount += update.Quantity;
                        break;

                    case StockUpdateType.Subtract:
                        product.RemainingCount -= update.Quantity;
                        // جلوگیری از موجودی منفی
                        if (product.RemainingCount < 0)
                        {
                            response.FailedCount++;
                            response.Errors.Add($"محصول {update.ProductId}: موجودی منفی شد (موجودی فعلی: {oldStock}, کم کردن: {update.Quantity})");
                            product.RemainingCount = oldStock; // بازگرداندن مقدار قبلی
                            continue;
                        }
                        break;
                }

                response.UpdatedCount++;
                
                _logger.LogInformation(
                    "Product {ProductId} stock updated from {OldStock} to {NewStock} (Type: {UpdateType})",
                    product.Id, oldStock, product.RemainingCount, request.UpdateType);
            }
            catch (Exception ex)
            {
                response.FailedCount++;
                response.Errors.Add($"خطا در به‌روزرسانی محصول {update.ProductId}: {ex.Message}");
                _logger.LogError(ex, "Error updating product {ProductId} stock", update.ProductId);
            }
        }

        if (response.UpdatedCount > 0)
        {
            await _context.SaveChangesAsync(cancellationToken);
            _logger.LogInformation("Bulk stock update completed: {UpdatedCount} succeeded, {FailedCount} failed", 
                response.UpdatedCount, response.FailedCount);
        }

        return response;
    }
}
