// EN: Query handlers for Inventory Service.
// VI: Query handlers cho Inventory Service.

using InventoryService.API.Application.DTOs;
using InventoryService.API.Application.Mappers;
using InventoryService.Domain.AggregatesModel.InventoryAggregate;
using MediatR;

namespace InventoryService.API.Application.Queries;

/// <summary>
/// EN: Handler for GetInventoryByShopQuery.
/// VI: Handler cho GetInventoryByShopQuery.
/// </summary>
public class GetInventoryByShopQueryHandler 
    : IRequestHandler<GetInventoryByShopQuery, PagedResult<InventoryItemDto>>
{
    private readonly IInventoryRepository _repository;

    public GetInventoryByShopQueryHandler(IInventoryRepository repository)
    {
        _repository = repository;
    }

    public async Task<PagedResult<InventoryItemDto>> Handle(
        GetInventoryByShopQuery request, 
        CancellationToken ct)
    {
        var (items, total) = await _repository.GetByShopAsync(
            request.ShopId, 
            request.Skip, 
            request.Take, 
            ct);

        var dtos = items.Select(i => i.ToDto()).ToList();

        return new PagedResult<InventoryItemDto>(dtos, total);
    }
}

/// <summary>
/// EN: Handler for GetStockLevelQuery.
/// VI: Handler cho GetStockLevelQuery.
/// </summary>
public class GetStockLevelQueryHandler 
    : IRequestHandler<GetStockLevelQuery, InventoryItemDto?>
{
    private readonly IInventoryRepository _repository;

    public GetStockLevelQueryHandler(IInventoryRepository repository)
    {
        _repository = repository;
    }

    public async Task<InventoryItemDto?> Handle(
        GetStockLevelQuery request, 
        CancellationToken ct)
    {
        var item = await _repository.GetByProductAndShopAsync(
            request.ProductId, 
            request.ShopId, 
            ct);

        return item?.ToDto();
    }
}

/// <summary>
/// EN: Handler for GetTransactionsQuery.
/// VI: Handler cho GetTransactionsQuery.
/// </summary>
public class GetTransactionsQueryHandler 
    : IRequestHandler<GetTransactionsQuery, PagedResult<InventoryTransactionDto>>
{
    private readonly IInventoryRepository _repository;

    public GetTransactionsQueryHandler(IInventoryRepository repository)
    {
        _repository = repository;
    }

    public async Task<PagedResult<InventoryTransactionDto>> Handle(
        GetTransactionsQuery request, 
        CancellationToken ct)
    {
        var (transactions, total) = await _repository.GetTransactionsAsync(
            request.InventoryItemId, 
            request.Skip, 
            request.Take, 
            ct);

        var dtos = transactions.Select(t => t.ToDto()).ToList();

        return new PagedResult<InventoryTransactionDto>(dtos, total);
    }
}

/// <summary>
/// EN: Handler for GetLowStockItemsQuery.
/// VI: Handler cho GetLowStockItemsQuery.
/// </summary>
public class GetLowStockItemsQueryHandler 
    : IRequestHandler<GetLowStockItemsQuery, PagedResult<InventoryItemDto>>
{
    private readonly IInventoryRepository _repository;

    public GetLowStockItemsQueryHandler(IInventoryRepository repository)
    {
        _repository = repository;
    }

    public async Task<PagedResult<InventoryItemDto>> Handle(
        GetLowStockItemsQuery request, 
        CancellationToken ct)
    {
        var (items, total) = await _repository.GetLowStockItemsAsync(
            request.ShopId, 
            request.Skip, 
            request.Take, 
            ct);

        var dtos = items.Select(i => i.ToDto()).ToList();

        return new PagedResult<InventoryItemDto>(dtos, total);
    }
}
