public static LocalityZoneData Convert(LocalityZone localityZone, string languageCode)
 => new LocalityZoneData
 {
     Id               = localityZone.Id,
     LocalityId       = localityZone.Id,
     LocalityZoneName = localityZone.Names.GetValueOrDefault(languageCode)
 };
        public async Task Map(string supplier, Tracer tracer, TelemetrySpan parentSpan, CancellationToken cancellationToken)
        {
            using var localityZoneMappingSpan =
                      tracer.StartActiveSpan("Map Locality zones", SpanKind.Internal, parentSpan);

            _logger.LogMappingLocalityZonesStart(supplier);

            var countries = await _locationMapperDataRetrieveService.GetCountries(cancellationToken);

            foreach (var country in countries)
            {
                _logger.LogMappingLocalityZonesOfSpecifiedCountryStart(supplier, country.Code);

                var changedLocalityZonesPairs = new Dictionary <int, int>();
                var countryLocalities         = await _locationMapperDataRetrieveService.GetNormalizedLocalitiesByCountry(country.Code, cancellationToken);

                var dbNormalizedLocalityZones =
                    await _locationMapperDataRetrieveService.GetNormalizedLocalityZonesByCountry(country.Code, cancellationToken);

                var notSuppliersLocalityZones = dbNormalizedLocalityZones
                                                .Where(l => !l.LocalityZone.SupplierLocalityZoneCodes.ContainsKey(supplier)).ToList();
                var suppliersLocalityZones = dbNormalizedLocalityZones
                                             .Where(l => l.LocalityZone.SupplierLocalityZoneCodes.ContainsKey(supplier)).ToList();

                var localityZonesToMap = await _context.RawAccommodations
                                         .Where(ac => ac.Supplier == supplier && ac.LocalityZoneNames != null &&
                                                ac.CountryCode == country.Code)
                                         .Select(ac
                                                 => new
                {
                    LocalityNames     = ac.LocalityNames,
                    CountryCode       = ac.CountryCode,
                    CountryNames      = ac.CountryNames,
                    LocalityZoneNames = ac.LocalityZoneNames,
                    LocalityZoneCode  = ac.SupplierLocalityZoneCode
                })
                                         .Distinct().ToListAsync(cancellationToken);

                localityZonesToMap = localityZonesToMap
                                     .GroupBy(lz => new { LocalityName = lz.LocalityNames.En, LocalityZoneName = lz.LocalityZoneNames.En })
                                     .Select(lz => lz.First())
                                     .ToList();

                var localityZonesToUpdate = new List <LocalityZone>();
                var localityZonesToAdd    = new List <LocalityZone>();
                var utcDate = DateTimeOffset.UtcNow;

                foreach (var zone in localityZonesToMap)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var defaultCountryName     = zone.CountryNames.GetValueOrDefault(Constants.DefaultLanguageCode);
                    var normalizedCountryName  = _locationNameNormalizer.GetNormalizedCountryName(defaultCountryName);
                    var defaultLocalityName    = zone.LocalityNames.GetValueOrDefault(Constants.DefaultLanguageCode);
                    var normalizedLocalityName =
                        _locationNameNormalizer.GetNormalizedLocalityName(normalizedCountryName, defaultLocalityName);
                    var defaultLocalityZone    = zone.LocalityZoneNames.GetValueOrDefault(Constants.DefaultLanguageCode);
                    var normalizedLocalityZone = defaultLocalityZone.ToNormalizedName();
                    if (!normalizedLocalityZone.IsValid())
                    {
                        continue;
                    }

                    var dbNotSuppliersZone = notSuppliersLocalityZones.FirstOrDefault(lz
                                                                                      => lz.DefaultLocality == normalizedLocalityName &&
                                                                                      lz.LocalityZone.Names.En == normalizedLocalityZone);
                    var dbSuppliersZone = suppliersLocalityZones.FirstOrDefault(lz
                                                                                => lz.DefaultLocality == normalizedLocalityName &&
                                                                                lz.LocalityZone.Names.En == normalizedLocalityZone);

                    var dbLocalityZone = new LocalityZone
                    {
                        Names    = _multilingualDataHelper.NormalizeCountryMultiLingualNames(zone.LocalityZoneNames),
                        IsActive = true,
                        Modified = utcDate
                    };

                    if (dbNotSuppliersZone != default)
                    {
                        dbLocalityZone.Id         = dbNotSuppliersZone.LocalityZone.Id;
                        dbLocalityZone.LocalityId = dbNotSuppliersZone.LocalityZone.LocalityId;
                        dbLocalityZone.Names      =
                            MultiLanguageHelpers.MergeMultilingualStrings(dbLocalityZone.Names,
                                                                          dbNotSuppliersZone.LocalityZone.Names);
                        dbLocalityZone.SupplierLocalityZoneCodes =
                            new Dictionary <string, string>(dbNotSuppliersZone.LocalityZone
                                                            .SupplierLocalityZoneCodes);
                        dbLocalityZone.SupplierLocalityZoneCodes.TryAdd(supplier, zone.LocalityZoneCode);
                        if (dbSuppliersZone != default)
                        {
                            changedLocalityZonesPairs.Add(dbSuppliersZone.LocalityZone.Id,
                                                          dbNotSuppliersZone.LocalityZone.Id);

                            foreach (var sup in dbSuppliersZone.LocalityZone.SupplierLocalityZoneCodes)
                            {
                                dbLocalityZone.SupplierLocalityZoneCodes.TryAdd(sup.Key, sup.Value);
                            }

                            dbSuppliersZone.LocalityZone.IsActive = false;
                            localityZonesToUpdate.Add(dbSuppliersZone.LocalityZone);
                        }

                        localityZonesToUpdate.Add(dbLocalityZone);
                    }
                    else if (dbSuppliersZone == default)
                    {
                        dbLocalityZone.Created = utcDate;

                        if (!_localityValidator.IsNormalizedValid(normalizedCountryName, normalizedLocalityName))
                        {
                            continue;
                        }

                        dbLocalityZone.LocalityId = countryLocalities.First(l => l.Names.En == normalizedLocalityName).Id;
                        dbLocalityZone.SupplierLocalityZoneCodes = new Dictionary <string, string>
                        {
                            { supplier, zone.LocalityZoneCode }
                        };
                        localityZonesToAdd.Add(dbLocalityZone);
                    }
                }

                _context.UpdateRange(localityZonesToUpdate.Distinct(new LocalityZoneComparer()));
                _context.AddRange(localityZonesToAdd.Distinct(new LocalityZoneComparer()));
                await ChangeLocalityZoneDependencies(changedLocalityZonesPairs, cancellationToken);

                await _context.SaveChangesAsync(cancellationToken);

                // await _locationsChangePublisher.PublishRemovedLocalityZones(changedLocalityZonesPairs.Keys.ToList());
                // await _locationsChangePublisher.PublishAddedLocalityZones(localityZonesToAdd
                //     .Distinct(new LocalityZoneComparer())
                //     .Select(lz => new LocalityZoneData(lz.Id, lz.Names.En,
                //         countryLocalities.First(l => l.Id == lz.LocalityId).Names.En, country.Name, country.Code))
                //     .ToList());

                _context.ChangeTracker.Entries()
                .Where(e => e.Entity != null)
                .Where(e => e.State != EntityState.Detached)
                .ToList()
                .ForEach(e => e.State = EntityState.Detached);

                localityZoneMappingSpan.AddEvent($"Done mapping locality zones of country with code {country.Code}");

                _logger.LogMappingLocalityZonesOfSpecifiedCountryFinish(supplier, country.Code);
            }

            _logger.LogMappingLocalityZonesFinish(supplier);
        }