// EN: Handler for GetAppointmentsByCustomerQuery.
// VI: Handler cho GetAppointmentsByCustomerQuery.

using BookingService.API.Application.DTOs;
using BookingService.Infrastructure;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace BookingService.API.Application.Queries;

/// <summary>
/// EN: Handler for retrieving appointments by customer.
/// VI: Handler để lấy appointments theo customer.
/// </summary>
public class GetAppointmentsByCustomerQueryHandler : IRequestHandler<GetAppointmentsByCustomerQuery, PaginatedList<AppointmentDto>>
{
    private readonly BookingContext _context;

    public GetAppointmentsByCustomerQueryHandler(BookingContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    public async Task<PaginatedList<AppointmentDto>> Handle(GetAppointmentsByCustomerQuery request, CancellationToken cancellationToken)
    {
        // EN: Build query
        // VI: Xây dựng query
        var query = _context.Appointments
            .Where(a => a.CustomerId == request.CustomerId);

        // EN: Get total count
        // VI: Lấy tổng số lượng
        var totalCount = await query.CountAsync(cancellationToken);

        // EN: Apply pagination
        // VI: Áp dụng phân trang
        var items = await query
            .OrderByDescending(a => a.StartTime)
            .Skip((request.Page - 1) * request.PageSize)
            .Take(request.PageSize)
            .Select(a => new AppointmentDto
            {
                Id = a.Id,
                ShopId = a.ShopId,
                CustomerId = a.CustomerId,
                StaffId = a.StaffId,
                ResourceId = a.ResourceId,
                ServiceId = a.ServiceId,
                StartTime = a.StartTime,
                EndTime = a.EndTime,
                Status = a.Status,
                Notes = a.Notes,
                CreatedAt = a.CreatedAt
            })
            .ToListAsync(cancellationToken);

        return PaginatedList<AppointmentDto>.Create(items, totalCount, request.Page, request.PageSize);
    }
}
