
package de.ivu.elect.business.dokumente.entity;

import java.util.List;

import javax.annotation.Nullable;

import org.slf4j.LoggerFactory;

import de.ivu.elect.business.datei.entity.FileType;


import static java.util.Arrays.asList;
import static java.util.Arrays.stream;
import static java.util.Collections.singletonList;
import static java.util.Objects.nonNull;
import static org.apache.commons.lang3.StringUtils.containsIgnoreCase;
import static org.apache.commons.lang3.StringUtils.indexOfIgnoreCase;
import static org.apache.commons.lang3.StringUtils.startsWithIgnoreCase;
import static org.apache.commons.lang3.StringUtils.trimToEmpty;

public enum DokumentVorlageArt {

  // ELECT-8170
  LAYOUT {
    @Override
    protected List<String> collectDokumentVorlageArtPrefixes() {
      return asList(LAYOUT_DOCUMENT_PREFIX);
    }

    @Override
    public boolean isNotwendigFuerKorrekteFunktionDerAnwendung() {
      return false; // ELECTMUC-2437
    }
  },

  WAHLTERMIN {
    @Override
    protected List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAHLTERMIN_DOCUMENT_PREFIX);
    }

    @Override
    public boolean isNotwendigFuerKorrekteFunktionDerAnwendung() {
      return false; // ELECTMUC-2437
    }
  },

  // COMMON
  AUSZAHLUNG {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(AUSZAHLUNG_DOCUMENT_PREFIX);
    }

    @Override
    public boolean isInWahlhelferdatenbankanzeigen() {
      return true;
    }
  },
  VERANSTALTUNG {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(VERANSTALTUNG_DOKUMENT_PREFIX);
    }

    @Override
    public boolean isInWahlhelferdatenbankanzeigen() {
      return true;
    }
  },
  VERANSTALTUNGEN_ALS_LISTE {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(VERANSTALTUNGEN_ALS_LISTE_DOKUMENT_PREFIX);
    }

    @Override
    public boolean isInWahlhelferdatenbankanzeigen() {
      return true;
    }
  },
  // WOS
  /**
   * A.k.a. STANDORT_VERMIETER_ENTSCHAEDIGUNG.
   */
  STANDORT_MIETVERTRAG {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(STANDORT_MIETVERTRAG_DOKUMENT_PREFIX);
    }
  },
  /**
   * A.k.a. STANDORT_ANSPRECHPARTNER_ENTSCHAEDIGUNG.
   */
  STANDORT_HAUSMEISTERQUITTUNG {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(STANDORT_HAUSMEISTERQUITTUNG_DOKUMENT_PREFIX);
    }
  },
  WAHLHELFER_BENACHRICHTIGUNG {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAHLHELFER_BENACHRICHTIGUNG_DOKUMENT_PREFIX);
    }

    @Override
    public boolean isInWahlhelferdatenbankanzeigen() {
      return true;
    }
  },
  WAHLHELFER_ALS_LISTE {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAHLHELFER_ALS_LISTE_DOKUMENT_PREFIX);
    }

    @Override
    public boolean isInWahlhelferdatenbankanzeigen() {
      return true;
    }
  },

  BRIEFWAHLTISCH_BESETZUNG {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(BRIEFWAHLTISCH_BESETZUNG_DOKUMENT_PREFIX);
    }
  },
  WAHLLOKAL_BESETZUNG {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAHLLOKAL_BESETZUNG_DOKUMENT_PREFIX);
    }
  },
  WAHLHELFEREINSATZORT_UEBERSICHT {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAHLHELFEREINSATZORT_UEBERSICHT_DOKUMENT_PREFIX);
    }
  },
  GEBIET_UEBERSICHT {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(GEBIET_UEBERSICHT_DOKUMENT_PREFIX);
    }
  },

  STANDORT_UEBERSICHT {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(STANDORT_UEBERSICHT_DOKUMENT_PREFIX);
    }
  },

  // CORE
  STIMMEINGABE {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(STIMMEINGABE_DOKUMENT_PREFIX, //
          //  ELECT-8020
          "ergebnis-erste-schnellmeldung", DokumentVorlageArt.SCHNELLMELDUNG_V3_DOKUMENT_PREFIX, //
          "ergebnis-wahlniederschrift", DokumentVorlageArt.WAHLNIEDERSCHRIFT_V1_DOKUMENT_PREFIX //
      );
    }
  },

  // WUS
  @Deprecated
  // NICHT MEHR VERWENDEN => WAHLVORSCHLAEGE_AlS_LISTE_MAENGEL nehmen
      BEKANNTMACHUNG_WAHLVORSCHLAEGE {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(BEKANNTMACHUNG_WAHLVORSCHLAEGE_DOKUMENT_PREFIX);
    }
  },

  UNTERSTUETZER_UNTERSCHRIFT {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(UNTERSTUETZER_UNTERSCHRIFT_DOKUMENT_PREFIX);
    }
  },
  UNTERSTUETZER_STATUSUEBERSICHT {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(UNTERSTUETZER_STATUSUEBERSICHT_DOKUMENT_PREFIX);
    }
  },

  FREMDKANDIDATUR_BESCHEINIGUNG {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(FREMDKANDIDATUR_BESCHEINIGUNG_DOKUMENT_PREFIX);
    }
  },

  WAHLAUSSCHUSSMITGLIEDER_ALS_LISTE {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAHLAUSSCHUSSMITGLIEDER_ALS_LISTE_DOKUMENT_PREFIX);
    }
  },

  WAHLVORSCHLAG_EMPFANGSQUITTUNG {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAHLVORSCHLAG_EMPFANGSQUITTUNG_DOKUMENT_PREFIX);
    }
  },
  WAHLVORSCHLAG_MAENGEL {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAHLVORSCHLAG_MAENGEL_DOKUMENT_PREFIX);
    }
  },
  WAHLVORSCHLAEGE_AlS_LISTE_MAENGEL {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAHLVORSCHLAEGE_ALS_LISTE_MAENGEL_DOKUMENT_PREFIX);
    }
  },

  WAHLVORSCHLAEGE_NACH_GEBIET {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAHLVORSCHLAEGE_NACH_GEBIET_DOKUMENT_PREFIX);
    }
  },
  GRUPPEN_MIT_WAHLVORSCHLAEGEN_AlS_LISTE {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(GRUPPEN_MIT_WAHLVORSCHLAEGEN_ALS_LISTE_DOKUMENT_PREFIX);
    }
  },
  KANDIDATUREN_AlS_LISTE {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(KANDIDATUREN_ALS_LISTE_DOKUMENT_PREFIX);
    }
  },
  WAHLBEWERBER {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAHLBEWERBER_DOKUMENT_PREFIX);
    }
  },
  STIMMZETTEL {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(STIMMZETTEL_DOKUMENT_PREFIX);
    }
  },

  // WAS
  ERSTE_SCHNELLMELDUNG_V2 {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(ERSTE_SCHNELLMELDUNG_V2_DOKUMENT_PREFIX);
    }
  },
  ZAEHLLISTE_LISTENSTIMMEN_V4 {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(ZAEHLLISTE_LISTENSTIMMEN_V4_DOKUMENT_PREFIX, // ELECT-9101
          "zaehlliste-zweitstimmen-v4", //
          "ergebnis-zaehlliste" //  ELECT-9101
      );
    }
  },
  ZWEITE_SCHNELLMELDUNG_V5 {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(ZWEITE_SCHNELLMELDUNG_V5_DOKUMENT_PREFIX, //
          "ergebnis-kandidaturen" // ELECT-14018
      );
    }
  },
  ZWEITE_SCHNELLMELDUNG_V6 {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(ZWEITE_SCHNELLMELDUNG_V6_DOKUMENT_PREFIX);
    }
  },
  GESAMTERGEBNIS_V7 {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(GESAMTERGEBNIS_V7_DOKUMENT_PREFIX, //
          "ergebnis-gesamtergebnis" // ELECT-8020
      );
    }
  },
  BEKANNTMACHUNG_ERGEBNIS {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(BEKANNTMACHUNG_ERGEBNIS_DOKUMENT_PREFIX, //
          "bekanntmachung-wahlergebnis" // ELECT-8020
      );
    }
  },
  NIEDERSCHRIFT_WAHLAUSSCHUSS {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(NIEDERSCHRIFT_WAHLAUSSCHUSS_DOKUMENT_PREFIX, //
          "wahlausschuss-niederschrift" // ELECT-8020
      );
    }
  },
  NIEDERSCHRIFT_WAHLAUSSCHUSS_SENVW {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(NIEDERSCHRIFT_WAHLAUSSCHUSS_SENVW_DOKUMENT_PREFIX);
    }
  },
  KANDIDATUR_GEWAEHLT {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(KANDIDATUR_GEWAEHLT_DOKUMENT_PREFIX);
    }
  },
  GESAMT_ERGEBNIS {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(GESAMT_ERGEBNIS_DOKUMENT_PREFIX);
    }
  },
  GESAMT_ERGEBNIS_VERGLEICH {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(GESAMT_ERGEBNIS_VERGLEICH_DOKUMENT_PREFIX);
    }
  },
  WAHLBUCH {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAHLBUCH_DOKUMENT_PREFIX);
    }
  },

  WAHLBUCH_REFERENDUM {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAHLBUCH_REFERENDUM_DOKUMENT_PREFIX);
    }
  },

  INTERNET_PREASENTATION_VELOCITY_TEMPLATES {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(INTERNET_PREASENTATION_VELOCITY_TEMPLATES_DOKUMENT_PREFIX);
    }

    @Override
    public boolean matchesDokumentVorlageArtPrefix(String fileName) {
      return super.matchesDokumentVorlageArtPrefix(fileName) || containsIgnoreCase(trimToEmpty(fileName), getDefaultDokumentVorlageArtPrefix());
    }

    @Override
    public boolean isZurAuswahlAnbieten() {
      return false;
    }
  },
  INTERNET_PRAESENTATION {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(INTERNET_PREASENTATION_TEMPLATES_DOKUMENT_PREFIX);
    }

  },

  SYSTEM_AUFGABEN {
    @Override
    protected List<String> collectDokumentVorlageArtPrefixes() {
      return singletonList(SYSTEM_AUFGABEN_DOKUMENT_PREFIX);
    }

    @Override
    public boolean matchesDokumentVorlageArtPrefix(String fileName) {
      return super.matchesDokumentVorlageArtPrefix(fileName) || containsIgnoreCase(trimToEmpty(fileName), getDefaultDokumentVorlageArtPrefix());
    }

    @Override
    public boolean isZurAuswahlAnbieten() {
      return false;
    }

  },

  PRUEFKRITERIEN {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(PRUEFKRITERIEN_TEMPLATES_DOKUMENT_PREFIX);
    }

  },
  // WVZ
  WAHLBENACHRICHTIGUNG {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAHLBENACHRICHTIGUNG_DOKUMENT_PREFIX);
    }
  },
  WAHLBENACHRICHTIGUNG_ALS_LISTE {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAHLBENACHRICHTIGUNG_ALS_LISTE_DOKUMENT_PREFIX);
    }
  },
  WAHLSCHEIN {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAHLSCHEIN_DOKUMENT_PREFIX);
    }
  },
  WAEHLERVERZEICHNIS_EINTRAG {
    @Override
    public boolean isNotwendigFuerKorrekteFunktionDerAnwendung() {
      return false;
    }

    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAEHLERVERZEICHNIS_EINTRAG_PREFIX);
    }

  },
  WAHLSCHEINANTRAG {
    @Override
    public boolean isNotwendigFuerKorrekteFunktionDerAnwendung() {
      return false;
    }

    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return asList(WAHLSCHEINANTRAG_PREFIX);
    }

  },
  UNGUELTIGE_WAHLSCHEINE {
    @Override
    public boolean isNotwendigFuerKorrekteFunktionDerAnwendung() {
      return false;
    }

    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return singletonList(UNGUELTIGE_WAHLSCHEINE_PREFIX);
    }
  },
  @Deprecated // nicht mehr verwenden
  WES_TEMPLATE {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return singletonList("disabled"); // TODO (?)
    }

    @Override
    public boolean matchesDokumentVorlageArtPrefix(String fileName) {
      return false;
    }

    @Override
    public boolean isNotwendigFuerKorrekteFunktionDerAnwendung() {
      return false;
    }

    @Override
    public boolean isInWahlhelferdatenbankanzeigen() {
      return false;
    }

    @Override
    public boolean isZurAuswahlAnbieten() {
      return false;
    }

    @Override
    public boolean isActive() {
      return false;
    }
  },

  WES_STIMMZETTEL_PRUEFUNG {
    @Override
    protected List<String> collectDokumentVorlageArtPrefixes() {
      return singletonList(STIMMZETTEL_PRUEFUNG_PREFIX);
    }
  },
  LEERFORMULAR {
    @Override
    public boolean isNotwendigFuerKorrekteFunktionDerAnwendung() {
      return false;
    }

    @Override
    public boolean isActive() {
      return false;
    }

    @Override
    public boolean isZurAuswahlAnbieten() {
      return false;
    }

    @Override
    protected List<String> collectDokumentVorlageArtPrefixes() {
      return List.of(LEERFORMULAR_PREFIX);
    }

    @Override
    public boolean isLeerformular() {
      return true;
    }
  },
  // SONSTIGES
  DEAKTIVIERT {
    @Override
    public List<String> collectDokumentVorlageArtPrefixes() {
      return singletonList("disabled");
    }
  },
  // ELECT-15078
  KEEP_ME {
    @Override
    protected List<String> collectDokumentVorlageArtPrefixes() {
      return singletonList(KEEPME_PREFIX);
    }

    @Override
    public boolean isNotwendigFuerKorrekteFunktionDerAnwendung() {
      return false;
    }

    @Override
    public boolean isActive() {
      return false;
    }

    @Override
    public boolean isZurAuswahlAnbieten() {
      return false;
    }
  };

  public static final String STIMMZETTEL_PRUEFUNG_PREFIX = "stimmzettelpruefung";

  public static final String BRIEFWAHLTISCH_BESETZUNG_DOKUMENT_PREFIX = "briefwahltisch-besetzung";

  public static final String LAYOUT_DOCUMENT_PREFIX = "layout";

  public static final String AUSZAHLUNG_DOCUMENT_PREFIX = "auszahlung";

  public static final String WAHLTERMIN_DOCUMENT_PREFIX = "wahltermin";

  public static final String VERANSTALTUNG_DOKUMENT_PREFIX = "veranstaltung-teilnehmer";

  public static final String VERANSTALTUNGEN_ALS_LISTE_DOKUMENT_PREFIX = "veranstaltungen-als-liste";

  public static final String STANDORT_MIETVERTRAG_DOKUMENT_PREFIX = "standort-mietvertrag";

  public static final String STANDORT_HAUSMEISTERQUITTUNG_DOKUMENT_PREFIX = "standort-hausmeisterquittung";

  public static final String WAHLHELFER_BENACHRICHTIGUNG_DOKUMENT_PREFIX = "wahlhelfer-benachrichtigung";

  public static final String WAHLHELFER_ALS_LISTE_DOKUMENT_PREFIX = "wahlhelfer-als-liste";

  public static final String WAHLLOKAL_BESETZUNG_DOKUMENT_PREFIX = "wahllokal-besetzung";

  public static final String WAHLHELFEREINSATZORT_UEBERSICHT_DOKUMENT_PREFIX = "wahlhelfereinsatzort-uebersicht";

  public static final String GEBIET_UEBERSICHT_DOKUMENT_PREFIX = "gebiet-uebersicht";

  public static final String STANDORT_UEBERSICHT_DOKUMENT_PREFIX = "standort-uebersicht";

  public static final String BEKANNTMACHUNG_WAHLVORSCHLAEGE_DOKUMENT_PREFIX = "NICHTVERWENDEN";

  public static final String UNTERSTUETZER_UNTERSCHRIFT_DOKUMENT_PREFIX = "unterstuetzer-unterschrift";

  public static final String UNTERSTUETZER_STATUSUEBERSICHT_DOKUMENT_PREFIX = "unterstuetzer-statusuebersicht";

  public static final String FREMDKANDIDATUR_BESCHEINIGUNG_DOKUMENT_PREFIX = "fremdkandidatur-bescheinigung";

  public static final String WAHLVORSCHLAG_EMPFANGSQUITTUNG_DOKUMENT_PREFIX = "wahlvorschlag-empfangsquittung";

  public static final String WAHLVORSCHLAG_MAENGEL_DOKUMENT_PREFIX = "wahlvorschlag-maengel";

  public static final String WAHLVORSCHLAEGE_ALS_LISTE_MAENGEL_DOKUMENT_PREFIX = "wahlvorschlaege-als-liste";

  public static final String WAHLAUSSCHUSSMITGLIEDER_ALS_LISTE_DOKUMENT_PREFIX = "wahlausschussmitglieder-als-liste";

  public static final String KANDIDATUREN_ALS_LISTE_DOKUMENT_PREFIX = "kandidaturen-als-liste";

  public static final String WAHLBEWERBER_DOKUMENT_PREFIX = "wahlbewerber";

  public static final String WAHLVORSCHLAEGE_NACH_GEBIET_DOKUMENT_PREFIX = "wahlvorschlaege-nach-gebiet";

  public static final String GRUPPEN_MIT_WAHLVORSCHLAEGEN_ALS_LISTE_DOKUMENT_PREFIX = "gruppen-mit-wahlvorschlaegen-als-liste";

  public static final String STIMMZETTEL_DOKUMENT_PREFIX = "stimmzettel";

  public static final String STIMMEINGABE_DOKUMENT_PREFIX = "niederschrift-wahlbezirk";

  public static final String WAHLBUCH_DOKUMENT_PREFIX = "wahlbuch";

  public static final String WAHLBUCH_REFERENDUM_DOKUMENT_PREFIX = "wahlbuch-referendum";

  /**
   * @see DokumentVorlageArt#STIMMEINGABE_DOKUMENT_PREFIX
   * @deprecated
   */
  @Deprecated
  private static final String WAHLNIEDERSCHRIFT_V1_DOKUMENT_PREFIX = "wahlniederschrift-v1";

  public static final String ERSTE_SCHNELLMELDUNG_V2_DOKUMENT_PREFIX = "zusammenstellung-ergebnisse-v2";

  /**
   * @see DokumentVorlageArt#STIMMEINGABE_DOKUMENT_PREFIX
   * @deprecated
   */
  @Deprecated
  private static final String SCHNELLMELDUNG_V3_DOKUMENT_PREFIX = "schnellmeldung-v3";

  public static final String ZAEHLLISTE_LISTENSTIMMEN_V4_DOKUMENT_PREFIX = "zaehlliste-stimmen";

  public static final String ZWEITE_SCHNELLMELDUNG_V5_DOKUMENT_PREFIX = "zusammenstellung-ergebnisse-v5";

  public static final String ZWEITE_SCHNELLMELDUNG_V6_DOKUMENT_PREFIX = "zweite-schnellmeldung-v6";

  public static final String GESAMTERGEBNIS_V7_DOKUMENT_PREFIX = "gesamtergebnis-v7";

  public static final String BEKANNTMACHUNG_ERGEBNIS_DOKUMENT_PREFIX = "bekanntmachung-ergebnis";

  public static final String NIEDERSCHRIFT_WAHLAUSSCHUSS_DOKUMENT_PREFIX = "niederschrift-wahlausschuss";

  public static final String NIEDERSCHRIFT_WAHLAUSSCHUSS_SENVW_DOKUMENT_PREFIX = "niederschrift-senvw";

  public static final String KANDIDATUR_GEWAEHLT_DOKUMENT_PREFIX = "kandidatur-gewaehlt";

  public static final String GESAMT_ERGEBNIS_DOKUMENT_PREFIX = "gesamt-ergebnis";

  public static final String GESAMT_ERGEBNIS_VERGLEICH_DOKUMENT_PREFIX = "ergebnis-vergleich";

  public static final String INTERNET_PREASENTATION_VELOCITY_TEMPLATES_DOKUMENT_PREFIX = "internet-templates";

  public static final String INTERNET_PREASENTATION_TEMPLATES_DOKUMENT_PREFIX = "internet-praesentation";

  public static final String SYSTEM_AUFGABEN_DOKUMENT_PREFIX = "system-aufgaben";

  public static final String PRUEFKRITERIEN_TEMPLATES_DOKUMENT_PREFIX = "pruefkriterien";

  public static final String WAHLBENACHRICHTIGUNG_DOKUMENT_PREFIX = "wahlbenachrichtigung";

  public static final String WAHLBENACHRICHTIGUNG_ALS_LISTE_DOKUMENT_PREFIX = "wahlbenachrichtigung-als-liste";

  public static final String WAHLSCHEIN_DOKUMENT_PREFIX = "wahlschein";

  public static final String WAHLSCHEINE_ALS_LISTE_DOKUMENT_PREFIX = "wahlscheine-als-liste";

  public static final String WAEHLERVERZEICHNIS_EINTRAG_PREFIX = "waehlerverzeichniseintrag";

  public static final String WAHLSCHEINANTRAG_PREFIX = "wahlscheinantrag";

  public static final String LEERFORMULAR_PREFIX = "leerformular";

  public static final String KEEPME_PREFIX = "keepme";

  public static final String UNGUELTIGE_WAHLSCHEINE_PREFIX = "ungueltige-wahlscheine";

  // Sub-Templates
  public static final String PERSON_SUB_TEMPLATE = "person";

  public static final String WAHLAUSSCHUSSMITGLIED_SUB_TEMPLATE = "wahlausschussmitglied";

  public static final String KANDIDATUR_SUB_TEMPLATE = "kandidatur";

  public static final String LOS_SUB_TEMPLATE = "los";

  public static final String WAHLAUSSCHUSS_SUB_TEMPLATE = "wahlausschuss";

  public static final String WAHLHELFEREINSATZORT_SUB_TEMPLATE = "wahlhelfereinsatzort";

  public static final String GEBIET_MIT_HIERARCHIE_SUB_TEMPLATE = "gebiet-mit-hierarchie";

  public static final String GEBIET_MIT_ANSPRECHPARTNER_SUB_TEMPLATE = "gebiet-details";

  public static final String DOKUMENT_PERSON_WAHLHELFER_SUB_TEMPLATE = "person-wahlhelfer";

  public static final String CUSTOM_PARAMETER_SUB_TEMPLATE = "parameter";

  public static final String STUECKELUNG_EURO_SUB_TEMPLATE = "stueckelung-euro";

  public static final String WAHLHELFERSCHICHTEN_SUB_TEMPLATE = "wahlhelferschichten";

  public static final String DHONDT_SUB_TEMPLATE = "dhondt";

  DokumentVorlageArt() {
  }

  public boolean isNotwendigFuerKorrekteFunktionDerAnwendung() {
    return true;
  }

  protected boolean matchesDokumentVorlageArtPrefix(String fileName) {
    return collectDokumentVorlageArtPrefixes().stream().anyMatch(prefix -> startsWithIgnoreCase(trimToEmpty(fileName), prefix));
  }

  public String getDefaultDokumentVorlageArtPrefix() {
    if (collectDokumentVorlageArtPrefixes().isEmpty()) {
      return "";
    }

    return collectDokumentVorlageArtPrefixes().get(0);
  }

  protected abstract List<String> collectDokumentVorlageArtPrefixes();

  protected String extractDokumentVorlageName(String fileName) {
    String fileNameNormalized = trimToEmpty(fileName);

    for (String prefix : collectDokumentVorlageArtPrefixes()) {
      int indexOfPrefix = indexOfIgnoreCase(fileNameNormalized, prefix);

      if (indexOfPrefix >= 0) {
        return fileNameNormalized.substring(indexOfPrefix + prefix.length());
      }
    }

    return fileNameNormalized;
  }

  public boolean isInWahlhelferdatenbankanzeigen() {
    return false;
  }

  public boolean isZurAuswahlAnbieten() {
    return true;
  }

  public boolean isLeerformular() {
    return false;
  }

  @Nullable
  public static DokumentVorlageArt getDokumentVorlageArt(String fileName) {
    if (fileName != null && fileName.toLowerCase().endsWith(".ott")) {
      return LAYOUT;
    }

    return stream(DokumentVorlageArt.values()) //
        .filter(dokumentVorlageArt -> dokumentVorlageArt.matchesDokumentVorlageArtPrefix(fileName))
        .min((one, another) -> another.getDefaultDokumentVorlageArtPrefix().length() - one.getDefaultDokumentVorlageArtPrefix().length()) //
        .orElse(null);
  }

  public static String getDokumentVorlageName(String fileName) {
    return getDokumentVorlageName(fileName, getDokumentVorlageArt(fileName));
  }

  public static String getDokumentVorlageName(String fileName, @Nullable DokumentVorlageArt dokumentVorlageArt) {
    String result = fileName;

    try {
      if (dokumentVorlageArt != null && dokumentVorlageArt.matchesDokumentVorlageArtPrefix(fileName)) {
        result = dokumentVorlageArt.extractDokumentVorlageName(fileName);

        if ((result.indexOf('-') == 0 || result.indexOf('_') == 0) && result.length() > 1) {
          result = result.substring(1);
        }
      }

      // dreistelige Extension entfernen, wenn vorhanden
      if (result.lastIndexOf('.') == result.length() - 4 && result.length() > 4) {
        result = result.substring(0, result.length() - 4);
      }

      return result;
    } catch (Exception ex) {
      // wenn hier was schief geht sind nur unwichtige Bequemlichkeitsfunktionen betroffen, das sollte nicht zu Fehlern an der Oberfläche führen...
      LoggerFactory.getLogger(DokumentVorlageArt.class).warn("Fehler bei Dokumentvorlagen: " + ex.getMessage(), ex);

      return fileName;
    }
  }

  public static String getFileName(DokumentVorlage dokumentVorlage, FileType fileType) {
    String result = dokumentVorlage.getName() + "." + fileType.getFileExtension();

    DokumentVorlageArt dokumentVorlageArt = dokumentVorlage.getDokumentVorlageArt();

    if (nonNull(dokumentVorlageArt)) {
      result = dokumentVorlageArt.getDefaultDokumentVorlageArtPrefix() + "-" + result;
    }

    return result;
  }

  public boolean isActive() {
    return true;
  }
}
