namespace Application.Students.Queries;

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

public record GetStudentsQuery : IRequest<IReadOnlyList<StudentDto>>;

public class GetStudentsHandler(IStudentRepository studentRepository)
    : IRequestHandler<GetStudentsQuery, IReadOnlyList<StudentDto>>
{
    public async Task<IReadOnlyList<StudentDto>> Handle(
        GetStudentsQuery request,
        CancellationToken ct)
    {
        // Direct projection - only SELECT needed columns, no entity materialization
        return await studentRepository.GetAllProjectedAsync(
            s => new StudentDto(
                s.Id,
                s.Name,
                s.Email.Value,
                s.Enrollments.Sum(e => e.Subject != null ? e.Subject.Credits : Subject.CreditsPerSubject),
                s.Enrollments.Select(e => new EnrollmentDto(
                    e.Id,
                    e.SubjectId,
                    e.Subject != null ? e.Subject.Name : "",
                    e.Subject != null ? e.Subject.Credits : Subject.CreditsPerSubject,
                    e.Subject != null && e.Subject.Professor != null ? e.Subject.Professor.Name : "",
                    e.EnrolledAt)).ToList()
            ), ct);
    }
}
