namespace Application.Students.Queries;

using Application.Students.DTOs;
using Domain.Entities;
using Domain.Ports.Repositories;
using MediatR;

public record GetStudentsPagedQuery(int? AfterCursor = null, int PageSize = 10)
    : IRequest<PagedResult<StudentPagedDto>>;

public class GetStudentsPagedHandler(IStudentRepository studentRepository)
    : IRequestHandler<GetStudentsPagedQuery, PagedResult<StudentPagedDto>>
{
    private const int MaxPageSize = 50;

    public async Task<PagedResult<StudentPagedDto>> Handle(
        GetStudentsPagedQuery request,
        CancellationToken ct)
    {
        var pageSize = Math.Min(request.PageSize, MaxPageSize);

        var (items, nextCursor, totalCount) = await studentRepository.GetPagedProjectedAsync(
            s => new StudentPagedDto(
                s.Id,
                s.Name,
                s.Email.Value,
                s.Enrollments.Sum(e => e.Subject != null ? e.Subject.Credits : Subject.CreditsPerSubject)
            ),
            request.AfterCursor,
            pageSize,
            ct);

        return new PagedResult<StudentPagedDto>(
            items,
            nextCursor,
            totalCount,
            nextCursor.HasValue);
    }
}
