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.PlanDate,request.RoutineId);
        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.UserAndPositionIds.Contains(new KeyValuePair<Guid, Guid>(shiftPlanUser.PositionId,shiftPlanUser.UserId)))
                request.UserAndPositionIds.Remove(new KeyValuePair<Guid, Guid>(shiftPlanUser.PositionId, shiftPlanUser.UserId));
            else
                _repositoryWrapper.SetRepository<Domain.Entities.Shift.ShiftPlanUser>()
                    .Delete(shiftPlanUser);
        }

        foreach (var userId in request.UserAndPositionIds)
            newPlan.AddUser(userId.Key,userId.Value);

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

        await _repositoryWrapper.SaveChangesAsync(cancellationToken);

        return true;
    }
}