
package de.ivu.elect.business.gebietsbaum.boundary;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;
import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import javax.annotation.Nullable;

import de.ivu.elect.business.gebietsbaum.entity.BundeslandKennzahl;
import de.ivu.elect.business.gebietsbaum.entity.CoreWahlverwaltungGebietInformationArt;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gebietsbaum.entity.Gebietsart;
import de.ivu.elect.business.gebietsbaum.entity.Gebietsgruppierung;
import de.ivu.elect.business.gebietsbaum.entity.WahlverwaltungGebietInformationArt;
import de.ivu.elect.business.wahl.boundary.WahlartTemplate;
import de.ivu.elect.business.wahl.entity.CommonWahlart;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.WahlParameterWerte;

public class WahlverwaltungGebietInformationResolver {

  public static final String GEMEINDE_KENNUNG_KREISFREIE_STADT = WahlverwaltungGemeindeAgs8.KENNUNG_GEMEINDE_KREISFREIE_STADT;

  public WahlverwaltungGebietInformationResolver() {
    super();
  }

  public WahlverwaltungGebietDescriptor createDescriptor(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet) {
    WahlverwaltungGebietInformation wahlkreisInformation = extractWahlkreisInformation(context, gebiet);
    WahlverwaltungGebietInformation stimmkreisInformation = extractStimmkreisInformation(context, gebiet);
    WahlverwaltungGebietInformation wahlbereichInformation = extractWahlbereichInformation(context, gebiet);

    WahlverwaltungGebietInformation erfassungsgebietInformation = extractErfassungsgebietInformation(context, gebiet);

    WahlverwaltungGebietInformation bundeslandInformation = extractBundeslandInformation(context, gebiet);

    WahlverwaltungGebietInformation gemeindeverbandInformation = extractGemeindeverbandInformation(context, gebiet);
    WahlverwaltungGemeindeAgs8 gemeindeverbandAgs8 = new WahlverwaltungGemeindeAgs8(gemeindeverbandInformation.getNummer(), bundeslandInformation.getNummer());

    WahlverwaltungGebietInformation gemeindeInformation = extractGemeindeInformation(context, gebiet);
    WahlverwaltungGemeindeAgs8 gemeindeAgs8 = new WahlverwaltungGemeindeAgs8(gemeindeInformation.getNummer(), bundeslandInformation.getNummer());

    WahlverwaltungGebietInformation kreisInformation = extractKreisInformation(context, gebiet, gemeindeAgs8);
    WahlverwaltungGebietInformation stadtbezirkInformation = extractStadtbezirkInformation(context, gebiet, gemeindeInformation);

    WahlverwaltungGebietInformation stimmzettelgebietInformation = extractStimmzettelgebietInformation(context, gebiet, wahlkreisInformation, stimmkreisInformation, wahlbereichInformation,
        kreisInformation, gemeindeInformation);

    return new WahlverwaltungGebietDescriptor( //
        gebiet,

        wahlkreisInformation, //
        stimmkreisInformation, //
        wahlbereichInformation, //

        stimmzettelgebietInformation, //
        erfassungsgebietInformation, //

        bundeslandInformation, //
        kreisInformation, //
        new WahlverwaltungGemeindeInformation(gemeindeverbandInformation, gemeindeverbandAgs8), //
        new WahlverwaltungGemeindeInformation(gemeindeInformation, gemeindeAgs8), //
        stadtbezirkInformation //
    );
  }

  protected WahlverwaltungGebietInformation extractWahlkreisInformation(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet) {
    return applyWahlverwaltungGebietInformationDokumentPlatzhalter(context,
        getGebietsgruppierungOrGebietInUebergeordneterGebietshierarchie(context, gebiet, CoreWahlverwaltungGebietInformationArt.WAHLKREIS), WahlParameterWerte.DOKUMENT_PLATZHALTER_WAHLKREIS_NUMMER,
        WahlParameterWerte.DOKUMENT_PLATZHALTER_WAHLKREIS_NAME);
  }

  protected WahlverwaltungGebietInformation extractStimmkreisInformation(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet) {
    return getGebietsgruppierungOrGebietInUebergeordneterGebietshierarchie(context, gebiet, CoreWahlverwaltungGebietInformationArt.STIMMKREIS);
  }

  protected WahlverwaltungGebietInformation extractWahlbereichInformation(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet) {
    return getGebietsgruppierungOrGebietInUebergeordneterGebietshierarchie(context, gebiet, CoreWahlverwaltungGebietInformationArt.WAHLBEREICH);
  }

  protected WahlverwaltungGebietInformation extractErfassungsgebietInformation(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet) {
    String art = CoreWahlverwaltungGebietInformationArt.ERFASSUNGSGEBIET.toArt();

    return findErfassungsgebietInGebietshierarchie(gebiet) //
        .orElse(emptyWahlverwaltungGebietInformation(art));
  }

  protected WahlverwaltungGebietInformation extractBundeslandInformation(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet) {
    CoreWahlverwaltungGebietInformationArt art = CoreWahlverwaltungGebietInformationArt.BUNDESLAND;

    WahlverwaltungGebietInformation result = getGebietsgruppierungOrGebietInUebergeordneterGebietshierarchie(context, gebiet, art);

    if (result.isUnbekannt()) {
      result = getGebietsgruppierungOrGebietInUebergeordneterGebietshierarchie(context, gebiet, "LAND"); // Bspw. Destatis!
    }

    if (result.isUnbekannt()) {
      result = createBundeslandInformationFallback(context, gebiet, art);
    }

    return applyWahlverwaltungGebietInformationDokumentPlatzhalter(context, result, null, WahlParameterWerte.DOKUMENT_PLATZHALTER_BUNDESLAND_NAME);
  }

  protected WahlverwaltungGebietInformation createBundeslandInformationFallback(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet, CoreWahlverwaltungGebietInformationArt art) {
    return emptyWahlverwaltungGebietInformation(art.toArt());
  }

  protected WahlverwaltungGebietInformation createBundeslandInformationFallback(CoreWahlverwaltungGebietInformationArt art, BundeslandKennzahl bundesland) {
    String kennungBundesland = bundesland.getKennzahlFormatted();

    return new WahlverwaltungGebietInformation(art.toArt(), bundesland.getBezeichnung(), kennungBundesland, bundesland.getKuerzel());
  }

  protected WahlverwaltungGebietInformation extractKreisInformation(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet, WahlverwaltungGemeindeAgs8 gemeindeAgs8) {
    CoreWahlverwaltungGebietInformationArt art = CoreWahlverwaltungGebietInformationArt.KREIS;

    WahlverwaltungGebietInformation result = getGebietsgruppierungOrGebietInUebergeordneterGebietshierarchie(context, gebiet, art);

    if (result.isUnbekannt()) {
      result = createKreisInformationFallback(context, gebiet, art, gemeindeAgs8);
    }

    return applyWahlverwaltungGebietInformationDokumentPlatzhalter(context, result, null, WahlParameterWerte.DOKUMENT_PLATZHALTER_LANDKREIS_NAME);
  }

  protected WahlverwaltungGebietInformation createKreisInformationFallback(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet, CoreWahlverwaltungGebietInformationArt art,
      WahlverwaltungGemeindeAgs8 gemeindeAgs8) {
    return emptyWahlverwaltungGebietInformation(art.toArt());
  }

  protected WahlverwaltungGebietInformation createKreisInformationFallback(CoreWahlverwaltungGebietInformationArt art, BundeslandKennzahl bundesland, String kennungRegierungsbezirk,
      String kennungKreis, String name) {
    String kennungBundesland = bundesland.getKennzahlFormatted();
    String kreisschluessel = kennungBundesland + kennungRegierungsbezirk + kennungKreis;

    return new WahlverwaltungGebietInformation(art.toArt(), name, kreisschluessel, "");
  }

  protected WahlverwaltungGebietInformation extractGemeindeverbandInformation(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet) {
    return emptyWahlverwaltungGebietInformation("");
  }

  protected WahlverwaltungGebietInformation extractGemeindeInformation(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet) {
    String art = CoreWahlverwaltungGebietInformationArt.GEMEINDE.toArt();

    WahlverwaltungGebietInformation result = findGebietsgruppierung(context, gebiet, art) //
        .orElse(findGemeindeInformationInGebietshierarchie(context, gebiet, art) //
            .orElse(emptyWahlverwaltungGebietInformation(art)));

    return applyWahlverwaltungGebietInformationDokumentPlatzhalter(context, result, WahlParameterWerte.DOKUMENT_PLATZHALTER_GEMEINDE_NUMMER, WahlParameterWerte.DOKUMENT_PLATZHALTER_GEMEINDE_NAME);
  }

  private Optional<WahlverwaltungGebietInformation> findGemeindeInformationInGebietshierarchie(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet, String art) {
    Optional<WahlverwaltungGebietInformation> result = findGebietInUebergeordneterGebietshierarchie(gebiet, art);

    if (!result.isPresent() && !gebiet.hasUntergeordneteGebiete()) {
      result = createGemeindeInformationFallback(context, gebiet, art); // Fallback nur bei Erfassungsgebieten...
    }

    if (result.isPresent()) {
      Optional<Gebiet> gebietIfPresent = result.get().getGebiet();

      if (gebietIfPresent.isPresent()) {
        Gebiet gemeindeOderWurzelgebiet = gebietIfPresent.get();

        // ELECT-8547
        return Optional.of(new WahlverwaltungGebietInformation(gemeindeOderWurzelgebiet, defaultIfBlank(gemeindeOderWurzelgebiet.getExterneId(), gemeindeOderWurzelgebiet.getNummer())));
      }
    }

    return result;
  }

  protected Optional<WahlverwaltungGebietInformation> createGemeindeInformationFallback(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet, String art) {
    return findWurzelgebiet(context);
  }

  protected WahlverwaltungGebietInformation extractStadtbezirkInformation(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet, WahlverwaltungGebietInformation gemeindeInformation) {
    WahlverwaltungGebietInformation result = getGebietsgruppierungOrGebietInUebergeordneterGebietshierarchie(context, gebiet, CoreWahlverwaltungGebietInformationArt.STADTBEZIRK);

    if (result.isUnbekannt()) {
      return getGebietsgruppierungOrGebietInUebergeordneterGebietshierarchie(context, gebiet, "BEZIRK"); // Bspw. BER!
    }

    return result;
  }

  protected WahlverwaltungGebietInformation extractStimmzettelgebietInformation(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet,
      WahlverwaltungGebietInformation wahlkreisInformation, WahlverwaltungGebietInformation stimmkreisInformation, WahlverwaltungGebietInformation wahlbereichInformation,
      WahlverwaltungGebietInformation kreisInformation, WahlverwaltungGebietInformation gemeindeInformation) {
    if (matchesWahlartMitStimmzettelgebietWahlkreis(context)) {
      return wahlkreisInformation;
    }

    if (matchesWahlartMitStimmzettelgebietStimmkreis(context)) {
      return stimmkreisInformation;
    }

    if (matchesWahlartMitStimmzettelgebietWahlbereich(context)) {
      if (!wahlbereichInformation.isUnbekannt()) {
        return wahlbereichInformation;
      }
    }

    if (matchesWahlartMitStimmzettelgebietKreis(context)) {
      if (!kreisInformation.isUnbekannt()) { // ELECT-8535, Fallback auf Wurzelgebiet...
        return kreisInformation;
      }
    }

    WahlverwaltungGebietInformation wurzelgebiet = getWurzelgebiet(context);

    // NOTE, dass CommonWahlart#BUERGERMEISTERWAHL als Vorlage für ALLE Direktwahlen verwendet wird und bspw. auch eine Landratswahl sein könnte! Deshalb der Check auf Gebiet#isWahlgebiet...
    boolean direktwahlartMitStimmzettelgebietGemeinde = CommonWahlart.BUERGERMEISTERWAHL.equalsWahlart(context.getWahl()) && gemeindeInformation.getGebiet().map(Gebiet::isWahlgebiet).orElse(false);

    if (direktwahlartMitStimmzettelgebietGemeinde || matchesWahlartMitStimmzettelgebietGemeinde(context) || /* ELECT-9487 */ matchesGebietsartNurZurVerwaltungOhneErgebnisrelevanz(wurzelgebiet)) {
      return gemeindeInformation;
    }

    return wurzelgebiet;
  }

  public boolean matchesGebietsartNurZurVerwaltungOhneErgebnisrelevanz(WahlverwaltungGebietInformation gebietInformation) {
    return gebietInformation != null && gebietInformation.getGebiet().map(this::matchesGebietsartNurZurVerwaltungOhneErgebnisrelevanz).orElse(false);
  }

  public boolean matchesGebietsartNurZurVerwaltungOhneErgebnisrelevanz(Gebiet gebiet) {
    return gebiet != null && matchesGebietsartNurZurVerwaltungOhneErgebnisrelevanz(gebiet.getGebietsart());
  }

  protected boolean matchesGebietsartNurZurVerwaltungOhneErgebnisrelevanz(Gebietsart gebietsart) {
    return false;
  }

  protected boolean matchesGebietsart(Gebietsart gebietsart, String gebietsartNameOderTitel) {
    return gebietsart != null && isNotBlank(gebietsartNameOderTitel)
        && (equalsIgnoreCase(gebietsart.getName(), gebietsartNameOderTitel) || equalsIgnoreCase(gebietsart.getTitel(), gebietsartNameOderTitel));
  }

  private boolean matchesWahlartMitStimmzettelgebietWahlkreis(WahlverwaltungGebietInformationResolverContext context) {
    return matchesAnyWahlart(context, collectWahlartenMitStimmzettelgebietWahlkreis());
  }

  private boolean matchesWahlartMitStimmzettelgebietStimmkreis(WahlverwaltungGebietInformationResolverContext context) {
    return matchesAnyWahlart(context, collectWahlartenMitStimmzettelgebietStimmkreis());
  }

  private boolean matchesWahlartMitStimmzettelgebietWahlbereich(WahlverwaltungGebietInformationResolverContext context) {
    return matchesAnyWahlart(context, collectWahlartenMitStimmzettelgebietWahlbereich());
  }

  private boolean matchesWahlartMitStimmzettelgebietKreis(WahlverwaltungGebietInformationResolverContext context) {
    return matchesAnyWahlart(context, collectWahlartenMitStimmzettelgebietKreis());
  }

  private boolean matchesWahlartMitStimmzettelgebietGemeinde(WahlverwaltungGebietInformationResolverContext context) {
    return matchesAnyWahlart(context, collectWahlartenMitStimmzettelgebietGemeinde());
  }

  protected boolean matchesWahlart(WahlverwaltungGebietInformationResolverContext context, WahlartTemplate wahlartTemplate) {
    return matchesAnyWahlart(context, wahlartTemplate);
  }

  protected boolean matchesAnyWahlart(WahlverwaltungGebietInformationResolverContext context, WahlartTemplate... wahlartTemplates) {
    return matchesAnyWahlart(context, asList(wahlartTemplates));
  }

  private boolean matchesAnyWahlart(WahlverwaltungGebietInformationResolverContext context, Collection<WahlartTemplate> wahlartTemplates) {
    Wahl wahl = context.getWahl();

    return wahlartTemplates.stream().anyMatch(wahlartTemplate -> wahlartTemplate.equalsWahlart(wahl));
  }

  protected Collection<WahlartTemplate> collectWahlartenMitStimmzettelgebietWahlkreis() {
    return asList(CommonWahlart.BUNDESTAGSWAHL);
  }

  protected Collection<WahlartTemplate> collectWahlartenMitStimmzettelgebietStimmkreis() {
    return emptyList();
  }

  protected Collection<WahlartTemplate> collectWahlartenMitStimmzettelgebietWahlbereich() {
    return emptyList();
  }

  protected Collection<WahlartTemplate> collectWahlartenMitStimmzettelgebietKreis() {
    return asList(CommonWahlart.EUROPAWAHL, CommonWahlart.KREISTAGSWAHL);
  }

  protected Collection<WahlartTemplate> collectWahlartenMitStimmzettelgebietGemeinde() {
    return asList(CommonWahlart.GEMEINDERATSWAHL);
  }

  protected String extractWahlParameter(WahlverwaltungGebietInformationResolverContext context, @Nullable WahlParameterWerte template) {
    if (template == null) {
      return "";
    }

    return context.extractWahlParameter(template);
  }

  protected WahlverwaltungGebietInformation getGebietsgruppierungOrGebietInUebergeordneterGebietshierarchie(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet,
      CoreWahlverwaltungGebietInformationArt wahlverwaltungGebietInformationArt) {
    return getGebietsgruppierungOrGebietInUebergeordneterGebietshierarchie(context, gebiet, wahlverwaltungGebietInformationArt.toArt());
  }

  protected WahlverwaltungGebietInformation getGebietsgruppierungOrGebietInUebergeordneterGebietshierarchie(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet, String art) {
    return findGebietsgruppierung(context, gebiet, art) //
        .orElse(findGebietInUebergeordneterGebietshierarchie(gebiet, art) //
            .orElse(emptyWahlverwaltungGebietInformation(art)));
  }

  protected WahlverwaltungGebietInformation getWurzelgebiet(WahlverwaltungGebietInformationResolverContext context) {
    return findWurzelgebiet(context) //
        .orElse(emptyWahlverwaltungGebietInformation(""));
  }

  protected WahlverwaltungGebietInformation getGebietInUebergeordneterGebietshierarchie(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet,
      CoreWahlverwaltungGebietInformationArt wahlverwaltungGebietInformationArt) {
    return getGebietInUebergeordneterGebietshierarchie(context, gebiet, wahlverwaltungGebietInformationArt.toArt());
  }

  protected WahlverwaltungGebietInformation getGebietInUebergeordneterGebietshierarchie(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet, String art) {
    return findGebietInUebergeordneterGebietshierarchie(gebiet, art) //
        .orElse(emptyWahlverwaltungGebietInformation(art));
  }

  private Optional<WahlverwaltungGebietInformation> findGebietsgruppierung(WahlverwaltungGebietInformationResolverContext context, Gebiet gebiet, String gebietsgruppierungArt) {
    Collection<Gebietsgruppierung> gebietsgruppierungenByArt = context.collectGebietsgruppierungen(gebietsgruppierungArt);
    Collection<Gebietsgruppierung> gebietsgruppierungenByArtAndGebiet = gebietsgruppierungenByArt.stream() //
        .filter(gebietsgruppierung -> gebietsgruppierung.isEnthaeltGebietOderUebergeordnetesGebietVon(gebiet)) //
        .collect(toSet());

    if (gebietsgruppierungenByArtAndGebiet.size() > 1) {
      throw new IllegalArgumentException("Ein Gebiet ist in mehr als einer Gebietsgruppierung derselben Art enthalten [art = " + gebietsgruppierungArt + ", gebiet = " + gebiet.getNummer() + "]");
    }

    if (gebietsgruppierungenByArtAndGebiet.size() == 1) {
      Gebietsgruppierung gebietsgruppierung = gebietsgruppierungenByArtAndGebiet.iterator().next();

      return Optional.of(new WahlverwaltungGebietInformation(calculateGebietsgruppierungArtIndexOrDefault(gebietsgruppierung, gebietsgruppierungenByArt), gebietsgruppierung));
    }

    return Optional.empty();
  }

  // ELECT-8091
  private int calculateGebietsgruppierungArtIndexOrDefault(Gebietsgruppierung templateByArt, Collection<Gebietsgruppierung> gebietsgruppierungenByArt) {
    List<Gebietsgruppierung> gebietsgruppierungenByArtAndTemplate = gebietsgruppierungenByArt.stream() //
        .filter(gebietsgruppierung -> gebietsgruppierung.isPersistent() //
            && Objects.equals(gebietsgruppierung.getGebietsgruppierungArt(), templateByArt.getGebietsgruppierungArt()) //
            && Objects.equals(gebietsgruppierung.getName(), templateByArt.getName()) //
            && Objects.equals(gebietsgruppierung.getPosition(), templateByArt.getPosition())) //
        .sorted((one, another) -> one.getId().compareTo(another.getId())).collect(toList());

    if (gebietsgruppierungenByArtAndTemplate.size() > 1) {
      return gebietsgruppierungenByArtAndTemplate.indexOf(templateByArt) + 1;
    }

    return 0; // Ignored!
  }

  private Optional<WahlverwaltungGebietInformation> findWurzelgebiet(WahlverwaltungGebietInformationResolverContext context) {
    return context.collectGebiete().stream() //
        .filter(gebiet -> !gebiet.hasUebergeordnetesGebiet()) //
        .map(gebiet -> (Gebiet) gebiet) //
        .findFirst().map(WahlverwaltungGebietInformation::new);
  }

  private Optional<WahlverwaltungGebietInformation> findErfassungsgebietInGebietshierarchie(Gebiet gebiet) {
    if (gebiet.hasUntergeordneteGebiete()) {
      return Optional.empty();
    }

    return Optional.of(new WahlverwaltungGebietInformation(gebiet, gebiet.getNummerBezirkFallsGesetzt())); // ELECT-8546
  }

  private Optional<WahlverwaltungGebietInformation> findGebietInUebergeordneterGebietshierarchie(Gebiet gebiet, String art) {
    if (WahlverwaltungGebietInformationArt.equalsGebietsart(art, gebiet)) {
      return Optional.of(new WahlverwaltungGebietInformation(gebiet));
    }

    return gebiet.getInGebietshierarchieUebergeordneteGebiete().stream() //
        .filter(gebietUebergeordnet -> WahlverwaltungGebietInformationArt.equalsGebietsart(art, gebietUebergeordnet)) //
        .findFirst().map(WahlverwaltungGebietInformation::new);
  }

  private WahlverwaltungGebietInformation applyWahlverwaltungGebietInformationDokumentPlatzhalter(WahlverwaltungGebietInformationResolverContext context, WahlverwaltungGebietInformation result,
      @Nullable WahlParameterWerte templateNummer, @Nullable WahlParameterWerte templateName) {
    return applyWahlverwaltungGebietInformationDokumentPlatzhalter(context, result, true, templateNummer, templateName);
  }

  private WahlverwaltungGebietInformation applyWahlverwaltungGebietInformationDokumentPlatzhalter(WahlverwaltungGebietInformationResolverContext context, WahlverwaltungGebietInformation result,
      boolean override, @Nullable WahlParameterWerte templateNummer, @Nullable WahlParameterWerte templateName) {
    String nummer = result.getNummer();

    if (override || isBlank(nummer)) {
      nummer = defaultIfBlank(extractWahlParameter(context, templateNummer), nummer);
    }

    String name = result.getName();

    if (override || isBlank(name)) {
      name = defaultIfBlank(extractWahlParameter(context, templateName), name);
    }

    return new WahlverwaltungGebietInformation(result.getGebiet(), result.getGebietsgruppierung(), result.getArt(), result.getArtIndex(), name, nummer, result.getKuerzel());
  }

  private WahlverwaltungGebietInformation emptyWahlverwaltungGebietInformation(String art) {
    return new WahlverwaltungGebietInformation(art, "", "", "");
  }
}
