namespace Brizco.Repository.Handlers.ShiftPlan;

public class UpdateShiftPlanCommandHandler : IRequestHandler<UpdateShiftPlanCommand, bool>
{
    private readonly IRepositoryWrapper _repositoryWrapper;

    public UpdateShiftPlanCommandHandler(IRepositoryWrapper repositoryWrapper)
    {
        _repositoryWrapper = repositoryWrapper;
    }

    public async Task<bool> Handle(UpdateShiftPlanCommand request, CancellationToken cancellationToken)
    {
        var shiftPlan = await _repositoryWrapper.SetRepository<Domain.Entities.Shift.ShiftPlan>()
            .TableNoTracking.FirstOrDefaultAsync(s => s.Id == request.Id,cancellationToken);

        if (shiftPlan == null)
            throw new AppException("ShiftPlan not found", ApiResultStatusCode.NotFound);

        var shift = await _repositoryWrapper.SetRepository<Domain.Entities.Shift.Shift>()
            .TableNoTracking.FirstOrDefaultAsync(s => s.Id == request.ShiftId, cancellationToken);

        if (shift == null)
            throw new AppException("Shift not found", ApiResultStatusCode.NotFound);


        var newPlan = shift.AddPlan(request.StartAt, request.EndAt);
        newPlan.Id = request.Id;


        var shiftPlanUsers = await _repositoryWrapper.SetRepository<Domain.Entities.Shift.ShiftPlanUser>()
            .TableNoTracking
            .Where(s => s.ShiftPlanId == newPlan.Id)
            .ToListAsync(cancellationToken);

        foreach (var shiftPlanUser in shiftPlanUsers)
        {
            if (request.UserIds.Contains(shiftPlanUser.Id))
                request.UserIds.Remove(shiftPlanUser.Id);
            else
                _repositoryWrapper.SetRepository<Domain.Entities.Shift.ShiftPlanUser>()
                    .Delete(shiftPlanUser);
        }

        foreach (var userId in request.UserIds)
            newPlan.AddUser(userId);

        _repositoryWrapper.SetRepository<Domain.Entities.Shift.ShiftPlan>()
            .Update(newPlan);

        await _repositoryWrapper.SaveChangesAsync(cancellationToken);

        return true;
    }
}