
package de.ivu.elect.exchange.dokumente;

import static java.util.Arrays.stream;
import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.replaceIgnoreCase;
import static org.apache.commons.lang3.StringUtils.startsWithIgnoreCase;
import static org.apache.commons.lang3.StringUtils.trimToEmpty;

import javax.annotation.Nullable;

import de.ivu.elect.business.system.entity.SystemGebietsebene;

public class DokumentPlatzhalterFormatter {

  private final SystemGebietsebene systemGebietsebene;

  private final String wahlbezeichnungLang;

  private final String wahlbezeichnungKurz;

  private final String zuWaehlendesGremium;

  public DokumentPlatzhalterFormatter(DokumentPlatzhalter dokumentPlatzhalter) {
    this(dokumentPlatzhalter.getSystemGebietsebene(), dokumentPlatzhalter.getWahlbezeichnung(), dokumentPlatzhalter.getWahlbezeichnungKurz(), dokumentPlatzhalter.getZuWaehlendesGremium());
  }

  public DokumentPlatzhalterFormatter(SystemGebietsebene systemGebietsebene, String wahlbezeichnungLang, String wahlbezeichnungKurz, String zuWaehlendesGremium) {
    super();

    this.systemGebietsebene = systemGebietsebene;

    this.wahlbezeichnungLang = wahlbezeichnungLang;
    this.wahlbezeichnungKurz = wahlbezeichnungKurz;

    this.zuWaehlendesGremium = zuWaehlendesGremium;
  }

  private SystemGebietsebene getSystemGebietsebene() {
    return systemGebietsebene;
  }

  private String getWahlbezeichnungLang() {
    return wahlbezeichnungLang;
  }

  private String getWahlbezeichnungKurz() {
    return wahlbezeichnungKurz;
  }

  private String getZuWaehlendesGremium() {
    return zuWaehlendesGremium;
  }

  public String formatWahlbezeichnungLangImGebiet(@Nullable String gebietName) {
    return formatWahlbezeichnungLangImGebiet(getWahlbezeichnungLang(), gebietName);
  }

  public String formatWahlbezeichnungLangImGebiet(@Nullable String wahlbezeichnungDefault, @Nullable String gebietName) {
    return trimToEmpty(formatWahlbezeichnungLangImGebietWahlart(wahlbezeichnungDefault) + " " + formatWahlbezeichnungImGebietGebietsebene(gebietName));
  }

  public String formatWahlbezeichnungLangImGebietWahlart(@Nullable String wahlbezeichnungDefault) {
    return defaultIfBlank(getWahlbezeichnungLang(), trimToEmpty(wahlbezeichnungDefault));
  }

  public String formatWahlbezeichnungKurzImGebiet(@Nullable String gebietName) {
    return formatWahlbezeichnungKurzImGebiet(getWahlbezeichnungKurz(), gebietName);
  }

  public String formatWahlbezeichnungKurzImGebiet(@Nullable String wahlbezeichnungDefault, @Nullable String gebietName) {
    return trimToEmpty(formatWahlbezeichnungKurzImGebietWahlart(wahlbezeichnungDefault) + " " + formatWahlbezeichnungImGebietGebietsebene(gebietName));
  }

  public String formatWahlbezeichnungKurzImGebietWahlart(@Nullable String wahlbezeichnungDefault) {
    return defaultIfBlank(getWahlbezeichnungKurz(), trimToEmpty(wahlbezeichnungDefault));
  }

  public String formatWahlbezeichnungImGebietGebietsebene(@Nullable String gebietName) {
    return formatImGebietGebietsebene(gebietName);
  }

  public String formatZuWaehlendesGremiumImGebiet(@Nullable String gebietName) {
    return formatZuWaehlendesGremiumImGebiet(getZuWaehlendesGremium(), gebietName);
  }

  public String formatZuWaehlendesGremiumImGebiet(@Nullable String zuWaehlendesGremiumDefault, @Nullable String gebietName) {
    return trimToEmpty(formatZuWaehlendesGremiumImGebietGremium(zuWaehlendesGremiumDefault) + " " + formatZuWaehlendesGremiumImGebietGebietsebene(gebietName));
  }

  public String formatZuWaehlendesGremiumImGebietGremium(@Nullable String zuWaehlendesGremiumDefault) {
    return defaultIfBlank(getZuWaehlendesGremium(), trimToEmpty(zuWaehlendesGremiumDefault));
  }

  public String formatZuWaehlendesGremiumImGebietGebietsebene(@Nullable String gebietName) {
    return formatImGebietGebietsebene(gebietName);
  }

  private String formatImGebietGebietsebene(String gebietName) {
    String result = "";

    String gebietBezeichnungName = trimToEmpty(gebietName);

    if (isNotBlank(gebietBezeichnungName)) {
      String gebietBezeichnungPrefix = "in";

      switch (getSystemGebietsebene()) {
        case GEMEINDE :
        case VERBANDSGEMEINDE :
          if (startsWithAnyIgnoreCase(gebietBezeichnungName, "Gemeinde ")) {
            gebietBezeichnungPrefix = "in der";
          } else if (startsWithIgnoreCase(gebietBezeichnungName, "Markt ")) {
            gebietBezeichnungPrefix = "im";
          } else {
            gebietBezeichnungPrefix = "in der Gemeinde";
          }

          break;
        case GEMEINDE_KREISFREI :
          if (startsWithAnyIgnoreCase(gebietBezeichnungName, "kreisfrei")) {
            gebietBezeichnungName = replaceIgnoreCase(gebietBezeichnungName, "kreisfreien Stadt ", "kreisfreien Stadt ");
            gebietBezeichnungName = replaceIgnoreCase(gebietBezeichnungName, "kreisfreie Stadt ", "kreisfreien Stadt ");
          }

          if (startsWithAnyIgnoreCase(gebietBezeichnungName, "kreisfreien Stadt ")) {
            gebietBezeichnungPrefix = "in der";
          } else if (startsWithAnyIgnoreCase(gebietBezeichnungName, "Markt ")) {
            gebietBezeichnungPrefix = "im";
          } else {
            gebietBezeichnungPrefix = "in der kreisfreien Stadt";
          }

          break;
        case LANDKREIS :
          if (startsWithAnyIgnoreCase(gebietBezeichnungName, "Landkreis ", "Kreis ", "Markt ")) {
            gebietBezeichnungPrefix = "im";
          } else {
            gebietBezeichnungPrefix = "im Landkreis";
          }

          break;

        default :
          break;
      }

      result = gebietBezeichnungPrefix + " " + gebietBezeichnungName;
    }

    return result;
  }

  private boolean startsWithAnyIgnoreCase(String value, String one, String... more) {
    return startsWithIgnoreCase(value, one) || stream(more).anyMatch(prefix -> startsWithIgnoreCase(value, prefix));
  }
}
