
package de.ivu.elect.presentation.gebietsbaum;

import java.io.Serializable;
import java.util.function.Function;

import javax.annotation.Nullable;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.inject.Named;

import org.apache.commons.lang3.StringUtils;

import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gebietsbaum.entity.GebietConstants;
import de.ivu.elect.jee.faces.Messages;


import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;

@Named
@ApplicationScoped // ELECT-7845
public class GebietNummerFormatter implements Serializable {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient Messages messages;

  public GebietNummerFormatter() {
    super();
  }

  @Deprecated // liefert die konfigurierten Darstellung und NICHT unbedingt den Namen mit Nummer
  public String getNameMitNummer(@Nullable Gebiet gebiet) {
    return getDarstellung(gebiet);
  }

  @Deprecated // liefert, falls gewünscht, NICHT die konfigurierte Darstellung, sonder den Namen und Nummer
  public String getNameMitNummerExplizit(@Nullable Gebiet gebiet) {
    if (gebiet == null) {
      return EMPTY;
    }

    return getNameMitNummer(gebiet.getName(), getNummer(gebiet));
  }

  @Deprecated // liefert, falls gewünscht, NICHT die konfigurierte Darstellung, sonder den Namen und Nummer
  public String getNameMitBezirksnummerExplizit(@Nullable Gebiet gebiet) {
    if (gebiet == null) {
      return EMPTY;
    }

    return getNameMitNummer(gebiet.getName(), getNummerBezirk(gebiet));
  }

  @Deprecated // sinnvoller ist wahrscheinlich in (fast) jedem Fall, die konfigurierte Darstellung de.ivu.elect.presentation.gebietsbaum.GebietNummerFormatter.getDarstellung zu verwenden
  public String getNameMitNummer(String name, String nummer) {
    if (isBlank(name)) {
      return nummer;
    }

    if (isBlank(nummer)) {
      return name;
    }

    return formatNameMitNummer(name, nummer);
  }


  public String getNameMitKuerzelWennVorhanden(Gebiet gebiet) {
    if (StringUtils.isNotBlank(gebiet.getKuerzel())) {
      return gebiet.getKuerzel() + " - " + gebiet.getName();
    }

    return gebiet.getName();
  }

  public String getName(Gebiet gebiet) {
    if (gebiet == null || isBlank(gebiet.getName())) {
      return EMPTY;
    }
    return gebiet.getName();
  }

  protected String formatNameMitNummer(String name, String nummer) {
    // sinnvoll, erst die nummer, dann der Name, siehe auch ELECTDD-226 - Gebietsnummer im Gebietsbaum zuerst anzeigen war: Suche nach Wahlbezirken optimieren
    return String.format("%s - %s", nummer, name);
  }

  public String getNummerBezirk(Gebiet gebiet) {
    if (gebiet == null) {
      return EMPTY;
    }

    return gebiet.getNummerBezirkFallsGesetzt();
  }

  public String getNummer(Gebiet gebiet) {
    if (gebiet == null) {
      return EMPTY;
    }

    return gebiet.getNummer();
  }

  public String getDarstellung(Gebiet gebiet) {
    if (gebiet == null) {
      return EMPTY;
    }

    return gebiet.getDarstellung();
  }

  public String getDetailMitMarkierungen(Gebiet gebiet, Function<Gebiet, String> getter) {
    return getDetailMitMarkierungen(gebiet, getter, " (" + getMessage(GebietConstants.MESSAGE_KEY_AUSWAHLBEZIRK_EINZAHL) + ")");
  }

  public String getDetailMitMarkierungenIcons(Gebiet gebiet, Function<Gebiet, String> getter) {
    return getDetailMitMarkierungen(gebiet, getter, "*");
  }

  private String getDetailMitMarkierungen(Gebiet gebiet, Function<Gebiet, String> getter, String markierungAuswahlbezirk) {
    if (gebiet != null) {
      String value = getter.apply(gebiet);

      if (isNotBlank(value)) {
        if (Boolean.TRUE.equals(gebiet.getAuswahlbezirk())) {
          return value + markierungAuswahlbezirk; // ELECTKOM-549, ELECT-9109
        }
      }

      return value;
    }

    return EMPTY;
  }

  private String getMessage(String msgKey, Object... params) {
    return getMessages().getMessageForMessageKey(msgKey, params);
  }

  protected Messages getMessages() {
    return messages;
  }
}
