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

using BookingService.API.Application.DTOs;
using BookingService.Domain.AggregatesModel.StaffAggregate;
using BookingService.Infrastructure.Repositories;
using MediatR;

namespace BookingService.API.Application.Commands;

public class UpdateStaffScheduleCommandHandler : IRequestHandler<UpdateStaffScheduleCommand, List<StaffScheduleDto>>
{
    private readonly IStaffScheduleRepository _staffScheduleRepository;
    private readonly ILogger<UpdateStaffScheduleCommandHandler> _logger;

    public UpdateStaffScheduleCommandHandler(
        IStaffScheduleRepository staffScheduleRepository,
        ILogger<UpdateStaffScheduleCommandHandler> logger)
    {
        _staffScheduleRepository = staffScheduleRepository ?? throw new ArgumentNullException(nameof(staffScheduleRepository));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task<List<StaffScheduleDto>> Handle(UpdateStaffScheduleCommand request, CancellationToken cancellationToken)
    {
        _logger.LogInformation("Updating schedule for staff {StaffId}", request.StaffId);

        // EN: Get existing schedules
        // VI: Lấy lịch hiện tại
        var existingSchedules = await _staffScheduleRepository.GetByStaffIdAsync(request.StaffId, request.ShopId, cancellationToken);

        // EN: Remove all existing
        // VI: Xóa tất cả lịch cũ
        foreach (var schedule in existingSchedules)
        {
            _staffScheduleRepository.Remove(schedule);
        }

        // EN: Add new schedules
        // VI: Thêm lịch mới
        var newSchedules = new List<StaffSchedule>();
        foreach (var day in request.Schedule)
        {
            var schedule = new StaffSchedule(
                request.StaffId,
                request.ShopId,
                day.DayOfWeek,
                day.StartTime,
                day.EndTime
            );
            _staffScheduleRepository.Add(schedule);
            newSchedules.Add(schedule);
        }

        await _staffScheduleRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation("Updated schedule for staff {StaffId} with {Count} days", request.StaffId, newSchedules.Count);

        return newSchedules.Select(s => new StaffScheduleDto
        {
            Id = s.Id,
            StaffId = s.StaffId,
            ShopId = s.ShopId,
            DayOfWeek = s.DayOfWeek,
            StartTime = s.StartTime,
            EndTime = s.EndTime
        }).ToList();
    }
}
