namespace CMSMicroservice.Application.InventoryItemCQ.Queries.GetAllInventoryItems;

public class GetAllInventoryItemsQueryHandler : IRequestHandler<GetAllInventoryItemsQuery, GetAllInventoryItemsResponseDto>
{
    private readonly IApplicationDbContext _context;

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

    public async Task<GetAllInventoryItemsResponseDto> Handle(GetAllInventoryItemsQuery request, CancellationToken cancellationToken)
    {
        var query = _context.InventoryItems
            .AsNoTracking()
            .Include(i => i.Warehouse)
            .Include(i => i.Product)
            .Include(i => i.DiscountProduct)
            .AsQueryable();

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

        if (request.ProductId.HasValue)
        {
            query = query.Where(i => i.ProductId == request.ProductId.Value);
        }

        if (request.DiscountProductId.HasValue)
        {
            query = query.Where(i => i.DiscountProductId == request.DiscountProductId.Value);
        }

        if (request.ProductType.HasValue)
        {
            query = query.Where(i => i.ProductType == request.ProductType.Value);
        }

        if (!string.IsNullOrEmpty(request.SearchTerm))
        {
            query = query.Where(i =>
                (i.Product != null && i.Product.Title.Contains(request.SearchTerm)) ||
                (i.DiscountProduct != null && i.DiscountProduct.Title.Contains(request.SearchTerm)));
        }

        if (request.IsActive.HasValue)
        {
            // فعلاً بدون فیلتر IsActive چون entity این فیلد رو نداره
        }

        if (request.IsLowStock == true)
        {
            query = query.Where(i => i.Quantity <= i.LowStockThreshold);
        }

        if (request.IsOutOfStock == true)
        {
            query = query.Where(i => i.AvailableQuantity <= 0);
        }

        var totalCount = await query.CountAsync(cancellationToken);

        var items = await query
            .OrderByDescending(i => i.Created)
            .Skip(request.Skip)
            .Take(request.Take)
            .Select(i => new InventoryItemListDto
            {
                Id = i.Id,
                ProductId = i.ProductId,
                DiscountProductId = i.DiscountProductId,
                ProductType = i.ProductType,
                WarehouseId = i.WarehouseId,
                WarehouseName = i.Warehouse != null ? i.Warehouse.Name : null,
                ProductTitle = i.Product != null ? i.Product.Title : (i.DiscountProduct != null ? i.DiscountProduct.Title : null),
                ProductPrice = i.Product != null ? i.Product.Price : (i.DiscountProduct != null ? i.DiscountProduct.Price : 0),
                Quantity = i.Quantity,
                ReservedQuantity = i.ReservedQuantity,
                AvailableQuantity = i.AvailableQuantity,
                LowStockThreshold = i.LowStockThreshold,
                MaxStockLevel = i.MaxStockLevel,
                LastRestockedAt = i.LastRestockedAt,
                LastSoldAt = i.LastSoldAt,
                Created = i.Created
            })
            .ToListAsync(cancellationToken);

        return new GetAllInventoryItemsResponseDto
        {
            Items = items,
            TotalCount = totalCount
        };
    }
}
