namespace CMSMicroservice.Application.StockMovementCQ.Queries.GetStockMovements;

public class GetStockMovementsQueryHandler : IRequestHandler<GetStockMovementsQuery, GetStockMovementsResponseDto>
{
    private readonly IApplicationDbContext _context;

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

    public async Task<GetStockMovementsResponseDto> Handle(GetStockMovementsQuery request, CancellationToken cancellationToken)
    {
        var query = _context.StockMovements
            .AsNoTracking()
            .Include(s => s.InventoryItem)
                .ThenInclude(i => i!.Product)
            .Include(s => s.InventoryItem)
                .ThenInclude(i => i!.DiscountProduct)
            .AsQueryable();

        // فیلترها
        if (request.InventoryItemId.HasValue)
        {
            query = query.Where(s => s.InventoryItemId == request.InventoryItemId.Value);
        }

        if (request.ProductId.HasValue)
        {
            query = query.Where(s =>
                s.InventoryItem != null &&
                (s.InventoryItem.ProductId == request.ProductId.Value ||
                 s.InventoryItem.DiscountProductId == request.ProductId.Value));
        }

        if (request.ProductType.HasValue)
        {
            query = query.Where(s =>
                s.InventoryItem != null &&
                s.InventoryItem.ProductType == request.ProductType.Value);
        }

        if (request.MovementType.HasValue)
        {
            query = query.Where(s => s.MovementType == request.MovementType.Value);
        }

        if (request.StartDate.HasValue)
        {
            query = query.Where(s => s.Created >= request.StartDate.Value);
        }

        if (request.EndDate.HasValue)
        {
            query = query.Where(s => s.Created <= request.EndDate.Value);
        }

        var totalCount = await query.CountAsync(cancellationToken);

        var movements = await query
            .OrderByDescending(s => s.Created)
            .Skip(request.Skip)
            .Take(request.Take)
            .Select(s => new StockMovementListDto
            {
                Id = s.Id,
                InventoryItemId = s.InventoryItemId,
                MovementType = s.MovementType,
                Quantity = s.Quantity,
                QuantityBefore = s.QuantityBefore,
                QuantityAfter = s.QuantityAfter,
                Note = s.Note,
                ReferenceNumber = s.ReferenceNumber,
                OrderId = s.OrderId,
                DiscountOrderId = s.DiscountOrderId,
                PerformedByUserId = s.PerformedByUserId,
                ProductTitle = s.InventoryItem != null && s.InventoryItem.Product != null
                    ? s.InventoryItem.Product.Title
                    : (s.InventoryItem != null && s.InventoryItem.DiscountProduct != null
                        ? s.InventoryItem.DiscountProduct.Title
                        : null),
                Created = s.Created
            })
            .ToListAsync(cancellationToken);

        return new GetStockMovementsResponseDto
        {
            Movements = movements,
            TotalCount = totalCount
        };
    }
}
