namespace WalletService.API.Application.Queries;

using MediatR;
using WalletService.Domain.AggregatesModel.WalletAggregate;
using WalletService.Domain.Exceptions;

/// <summary>
/// EN: Handler for GetWalletTransactionsQuery
/// VI: Handler cho GetWalletTransactionsQuery
/// </summary>
public class GetWalletTransactionsQueryHandler : IRequestHandler<GetWalletTransactionsQuery, WalletTransactionsDto>
{
    private readonly IWalletRepository _walletRepository;

    public GetWalletTransactionsQueryHandler(IWalletRepository walletRepository)
    {
        _walletRepository = walletRepository;
    }

    public async Task<WalletTransactionsDto> Handle(
        GetWalletTransactionsQuery request,
        CancellationToken cancellationToken)
    {
        var wallet = await _walletRepository.GetByUserIdAsync(request.UserId)
            ?? throw new WalletDomainException($"Wallet not found for user {request.UserId}");

        var transactions = await _walletRepository.GetTransactionsAsync(
            wallet.Id, request.Page, request.PageSize);

        var totalCount = await _walletRepository.CountTransactionsAsync(wallet.Id);
        var totalPages = (int)Math.Ceiling(totalCount / (double)request.PageSize);

        return new WalletTransactionsDto(
            transactions.Select(t => new WalletTransactionDto(
                t.Id,
                t.Amount.Amount,
                t.Amount.Currency,
                t.Type.Name,
                t.Description,
                t.ReferenceId,
                t.BalanceAfter,
                t.CreatedAt
            )),
            totalCount,
            request.Page,
            request.PageSize,
            totalPages
        );
    }
}
