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

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 shop with pagination.
/// VI: Handler để lấy appointments theo shop với phân trang.
/// </summary>
public class GetAppointmentsByShopQueryHandler : IRequestHandler<GetAppointmentsByShopQuery, PaginatedList<AppointmentDto>>
{
    private readonly BookingContext _context;

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

    public async Task<PaginatedList<AppointmentDto>> Handle(GetAppointmentsByShopQuery request, CancellationToken cancellationToken)
    {
        // EN: Build query with filters
        // VI: Xây dựng query với filters
        var query = _context.Appointments
            .Where(a => a.ShopId == request.ShopId);

        if (request.StartDate.HasValue)
        {
            query = query.Where(a => a.StartTime >= request.StartDate.Value);
        }

        if (request.EndDate.HasValue)
        {
            query = query.Where(a => a.StartTime <= request.EndDate.Value);
        }

        if (!string.IsNullOrWhiteSpace(request.Status))
        {
            query = query.Where(a => a.Status == request.Status);
        }

        // 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);
    }
}
