using Application.Abstractions.Data;
using Application.Abstractions.Messaging;
using Microsoft.EntityFrameworkCore;

namespace Application.Features.Api.Crew.GetCrewList;

internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response>
{
    public async Task<Response> Handle(Query request, CancellationToken ct)
    {
        var query = db.Crew.AsNoTracking().Where(c => c.ChannelID == request.ChannelID);

        var total = await query.CountAsync(ct);

        var projected = query.Select(c => new CrewItem(
            c.ID, c.Name, c.Description, c.MinAmount, c.IsActive,
            c.Members.Count(m => m.IsActive),
            c.Sessions.Count,
            c.Sessions.Sum(s => s.TotalAmount),
            c.CreatedAt
        ));

        projected = (request.SortBy, request.SortDir) switch
        {
            ("amount", "asc") => projected.OrderBy(c => c.TotalDonationAmount),
            ("amount", _) => projected.OrderByDescending(c => c.TotalDonationAmount),
            ("members", "asc") => projected.OrderBy(c => c.MemberCount),
            ("members", _) => projected.OrderByDescending(c => c.MemberCount),
            ("date", "asc") => projected.OrderBy(c => c.CreatedAt),
            _ => projected.OrderByDescending(c => c.CreatedAt)
        };

        var list = await projected
            .Skip((request.PageNum - 1) * request.PerPage)
            .Take(request.PerPage)
            .ToListAsync(ct);

        return new Response(total, list);
    }
}