namespace WalletService.API.Application.Queries;

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

/// <summary>
/// EN: Handler for GetPointTransactionsQuery
/// VI: Handler cho GetPointTransactionsQuery
/// </summary>
public class GetPointTransactionsQueryHandler : IRequestHandler<GetPointTransactionsQuery, PointTransactionsDto>
{
    private readonly IPointAccountRepository _pointAccountRepository;

    public GetPointTransactionsQueryHandler(IPointAccountRepository pointAccountRepository)
    {
        _pointAccountRepository = pointAccountRepository;
    }

    public async Task<PointTransactionsDto> Handle(
        GetPointTransactionsQuery request,
        CancellationToken cancellationToken)
    {
        var account = await _pointAccountRepository.GetByUserIdAsync(request.UserId)
            ?? throw new PointsDomainException($"Point account not found for user {request.UserId}");

        var transactions = await _pointAccountRepository.GetTransactionsAsync(
            account.Id, request.Page, request.PageSize);

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

        return new PointTransactionsDto(
            transactions.Select(t => new PointTransactionDto(
                t.Id,
                t.Points,
                t.Type.Name,
                t.Source,
                t.Description,
                t.BalanceAfter,
                t.CreatedAt,
                t.ExpiresAt
            )),
            totalCount,
            request.Page,
            request.PageSize,
            totalPages
        );
    }
}
