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

import static java.util.Arrays.stream;
import static java.util.stream.Collectors.joining;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.trimToEmpty;

import java.text.MessageFormat;

import javax.annotation.Nullable;

import de.ivu.elect.business.datei.entity.FileType;
import de.ivu.elect.business.dokumente.entity.DokumentVorlageArt;
import de.ivu.elect.business.exchange.control.FileKonfiguration;
import de.ivu.elect.business.gebietsbaum.boundary.WahlverwaltungGebietInformation;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebiet;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.Wahltermin;
import de.ivu.elect.jee.faces.Messages;
import de.ivu.elect.presentation.dokumente.exchange.DokumentBulkExportSearchEntryTemplate;
import de.ivu.elect.util.FileUtil;

public interface ErgebnisdokumentTyp extends DokumentBulkExportSearchEntryTemplate {

  String name();

  @Override
  default String getKuerzel(Wahl wahl, Wahltermin wahltermin, Messages messages) {
    String msgKey = "ErgebnisdokumentTyp." + getDefaultKuerzel() + ".kuerzel";
    String msgKeyWahlart = msgKey + "." + getWahlartNameNormalized(wahl);

    if (messages.isMessageKeyVorhanden(msgKeyWahlart)) {
      return messages.getMessageForMessageKey(msgKeyWahlart);
    }

    if (messages.isMessageKeyVorhanden(msgKey)) {
      return messages.getMessageForMessageKey(msgKey);
    }

    return getDefaultKuerzel();
  }

  String getDefaultKuerzel();

  @Override
  default String getBezeichnung(Wahl wahl, Wahltermin wahltermin, Messages messages) {
    String msgKey = "ErgebnisdokumentTyp." + getDefaultKuerzel() + ".bezeichnung";
    String msgKeyWahlart = msgKey + "." + getWahlartNameNormalized(wahl);

    if (messages.isMessageKeyVorhanden(msgKeyWahlart)) {
      return messages.getMessageForMessageKey(msgKeyWahlart);
    }

    if (messages.isMessageKeyVorhanden(msgKey)) {
      return messages.getMessageForMessageKey(msgKey);
    }

    return getDefaultBezeichnung();
  }

  String getDefaultBezeichnung();

  @Override
  default String getBeschreibung(Wahl wahl, Wahltermin wahltermin, Messages messages) {
    String msgKey = "ErgebnisdokumentTyp." + getDefaultKuerzel() + ".beschreibung";
    String msgKeyWahlart = msgKey + "." + getWahlartNameNormalized(wahl);

    if (messages.isMessageKeyVorhanden(msgKeyWahlart)) {
      return messages.getMessageForMessageKey(msgKeyWahlart);
    }

    if (messages.isMessageKeyVorhanden(msgKey)) {
      return messages.getMessageForMessageKey(msgKey);
    }

    return getDefaultBeschreibung();
  }

  String getDefaultBeschreibung();

  default String createDokumentVorlageName(Wahl wahl, Wahltermin wahltermin, Messages messages, DokumentVorlageArt dokumentVorlageArt, String... dokumentVorlageNameInfixes) {
    String format = "{0}{1} {2}";
    String formatMsgKey = "ErgebnisdokumentTyp." + getDefaultKuerzel() + ".dokument.vorlage.name.format." + dokumentVorlageArt.name();
    String formatMsgKeyWahlart = formatMsgKey + "." + getWahlartNameNormalized(wahl);

    if (messages.isMessageKeyVorhanden(formatMsgKeyWahlart)) {
      format = messages.getMessageForMessageKey(formatMsgKeyWahlart);
    }

    if (messages.isMessageKeyVorhanden(formatMsgKey)) {
      format = messages.getMessageForMessageKey(formatMsgKey);
    }

    String dokumentVorlageArtPrefix = dokumentVorlageArt.getDefaultDokumentVorlageArtPrefix() + "-";

    String infixes = "";

    if (dokumentVorlageNameInfixes != null && dokumentVorlageNameInfixes.length > 0) {
      infixes += "(" + stream(dokumentVorlageNameInfixes).collect(joining(", ")) + ")";
    }

    return trimToEmpty(MessageFormat.format(format, dokumentVorlageArtPrefix, getBezeichnung(wahl, wahltermin, messages), infixes)) + "." + FileType.ODT.getFileExtension();
  }

  boolean isErgebnisErsteSchnellmeldung();

  boolean isErgebnisWahlniederschrift();

  boolean isErgebnisGesamtergebnis();

  default String getFileNamePrefix(Wahl wahl, Wahltermin wahltermin, Messages messages) {
    return getKuerzel(wahl, wahltermin, messages).toLowerCase() + ".";
  }

  static <E> String createFileName(Wahl wahl, Wahltermin wahltermin, Messages messages, ErgebnisdokumentTyp ergebnisdokumentTyp, E entity, FileType fileType) {
    return createFileName(wahl, wahltermin, messages, null, ergebnisdokumentTyp, entity, fileType);
  }

  static <E> String createFileName(Wahl wahl, Wahltermin wahltermin, Messages messages, @Nullable FileKonfiguration fileKonfiguration, ErgebnisdokumentTyp ergebnisdokumentTyp, E entity,
      FileType fileType) {
    String fileNamePrefix = ergebnisdokumentTyp.getFileNamePrefix(wahl, wahltermin, messages);

    if (entity instanceof WahlverwaltungGebietInformation) {
      WahlverwaltungGebietInformation wahlverwaltungGebietInformation = (WahlverwaltungGebietInformation) entity;

      if (fileKonfiguration == null) {
        return fileNamePrefix + wahlverwaltungGebietInformation.createFileName(fileType);
      }

      return fileNamePrefix + wahlverwaltungGebietInformation.createFileName(fileKonfiguration, fileType);
    }

    String fileNameInfix = "";

    if (entity instanceof Gebiet) {
      Gebiet gebiet = (Gebiet) entity;

      fileNameInfix = gebiet.getNummer() + "-" + gebiet.getName();
    }

    if (entity instanceof GruppeImGebiet) {
      GruppeImGebiet gruppeImGebiet = (GruppeImGebiet) entity;

      Gebiet gebiet = gruppeImGebiet.getGebiet();
      Gruppe gruppe = gruppeImGebiet.getGruppe();

      fileNameInfix = gebiet.getNummer() + "-" + gebiet.getName() + "-" + gruppe.getSchluessel();
    }

    if (isNotBlank(fileNameInfix)) {
      return fileNamePrefix + FileUtil.normalizeZipEntryName(fileNameInfix) + "." + fileType.getFileExtension();
    }

    throw new IllegalArgumentException("Dateiname kann nicht erzeugt werden [ergebnisdokumentTyp = " + ergebnisdokumentTyp + ", entity = " + entity + ", fileType = " + fileType + "]");
  }

  default String getWahlartNameNormalized(Wahl wahl) {
    if (wahl != null && wahl.getWahlart() != null) {
      return wahl.getWahlart().getWahlartNameNormalized();
    }

    return "";
  }
}
