private async Task LoadingThreadWorker()
        {
            BookingDataOverview data;

            try
            {
                data = await LoadData();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to load data from MOH");

                if (_cachedData != null)
                {
                    return;
                }

                data = GetFallbackData();
            }

            lock (_dataLocker)
            {
                _cachedData    = data;
                _loadingThread = null;
            }
        }
        private async Task <BookingDataOverview> LoadData()
        {
            int sleepInteval = _cachedData == null
                ? 0
                : _defaultSleepIntervalMs;

            var model = new BookingDataOverview();

            model.Vaccines = new List <Vaccine>();

            var vaccines = await _mohBookingClient.GetServicesAsync();

            Thread.Sleep(sleepInteval);

            foreach (var vaccine in vaccines)
            {
                var vaccineModel = new Vaccine()
                {
                    Id             = vaccine.Key,
                    Name           = vaccine.Name,
                    Description    = GenerateVaccineDescription(vaccine.Id),
                    Municipalities = new List <Municipality>()
                };
                model.Vaccines.Add(vaccineModel);

                var regions = await _mohBookingClient.GetRegionsAsync(vaccine.Id);

                Thread.Sleep(sleepInteval);

                foreach (var region in regions)
                {
                    var municipalities = await _mohBookingClient.GetMunicipalitiesAsync(vaccine.Id, region.Id);

                    foreach (var municipality in municipalities)
                    {
                        var municipalityModel = new Municipality()
                        {
                            RegionId   = region.Id,
                            RegionName = region.GeoName,
                            Id         = municipality.Id,
                            Name       = municipality.GeoName,
                            Locations  = new List <VaccineLocation>()
                        };

                        var branches = await _mohBookingClient.GetMunicipalityBranchesAsync(vaccine.Id, municipality.Id);

                        Thread.Sleep(sleepInteval);

                        foreach (var branch in branches)
                        {
                            var slots = await _mohBookingClient.GetSlotsAsync(vaccine.Id, region.Id, branch.Id);

                            Thread.Sleep(sleepInteval);

                            var availableSlots = slots
                                                 .SelectMany(s => s.Schedules)
                                                 .SelectMany(s => s.Dates)
                                                 .SelectMany(d => d.Slots)
                                                 .Where(s => s.Taken != true && s.Reserved != true)
                                                 .ToList();


                            if (!availableSlots.Any())
                            {
                                continue;
                            }

                            var modelLocation = new VaccineLocation()
                            {
                                BranchId       = branch.Id,
                                BranchName     = branch.Name,
                                BranchAddress  = branch.Address,
                                AvailableCount = availableSlots.Count()
                            };
                            municipalityModel.Locations.Add(modelLocation);
                        }

                        if (municipalityModel.AvailableCount > 0)
                        {
                            vaccineModel.Municipalities.Add(municipalityModel);
                        }
                    }
                }
            }

            model.Municipalities = model.Vaccines
                                   .SelectMany(v => v.Municipalities)
                                   .GroupBy(m => m.RegionId)
                                   .Select(g => g.First())
                                   .ToList();

            model.LastUpdateDt = DateTimeOffset.Now;
            return(model);
        }