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

import static java.util.Arrays.stream;
import static java.util.Collections.emptyList;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.strip;
import static org.apache.commons.lang3.StringUtils.stripToEmpty;

import java.util.Collection;
import java.util.HashSet;

import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;

import de.ivu.elect.business.anschrift.entity.AnschriftConstants;
import de.ivu.elect.jee.faces.Messages;
import de.ivu.elect.presentation.anschrift.table.ZusammengesetzteAnschrift;

public class ZusammengesetzteAnschriftFormatter {

  private static final String MSG_KEY_PREFIX = "zusammengesetzte.anschrift";

  public static final String ATTRIBUTE_WOHNUNGSGEBER = AnschriftConstants.MESSAGE_KEY_ZUSTELLANWEISUNG_EINZAHL;

  public static final String ATTRIBUTE_STRASSENNAME = AnschriftConstants.MESSAGE_KEY_STRASSE_EINZAHL;

  public static final String ATTRIBUTE_HAUSNUMMER = AnschriftConstants.MESSAGE_KEY_HAUSNUMMER_EINZAHL;

  public static final String ATTRIBUTE_BUCHSTABE = "entity.einzahl.ANSCHRIFT.BUCHSTABE";

  public static final String ATTRIBUTE_ZUSATZ = AnschriftConstants.MESSAGE_KEY_HAUSNUMMERZUSATZ_EINZAHL;

  public static final String ATTRIBUTE_WOHNUNGSNUMMER = AnschriftConstants.MESSAGE_KEY_WOHNUNGSNUMMER_EINZAHL;

  public static final String ATTRIBUTE_PLZ = AnschriftConstants.MESSAGE_KEY_PLZ_EINZAHL;

  public static final String ATTRIBUTE_ORT = AnschriftConstants.MESSAGE_KEY_ORT_EINZAHL;

  public static final String ATTRIBUTE_ORTSTEIL = AnschriftConstants.MESSAGE_KEY_ORTSTEIL_EINZAHL;

  public static final String ATTRIBUTE_STAAT = AnschriftConstants.MESSAGE_KEY_STAAT_EINZAHL;

  @Inject
  protected transient Messages messages;

  public ZusammengesetzteAnschriftFormatter() {
    super();
  }

  public String formatVollstaendig(ZusammengesetzteAnschrift anschrift) {
    return format(buildMsgKey(anschrift, emptyList()), anschrift);
  }

  public String formatStaatIgnored(ZusammengesetzteAnschrift anschrift) {
    return formatOhne(anschrift, ZusammengesetzteAnschriftFormatter.ATTRIBUTE_STAAT);
  }

  public String formatOhne(ZusammengesetzteAnschrift anschrift, String oneIgnored, String... moreIgnored) {
    Collection<String> attributesIgnored = new HashSet<>();

    if (isNotBlank(oneIgnored)) {
      attributesIgnored.add(oneIgnored);
    }

    if (moreIgnored != null) {
      stream(moreIgnored).filter(StringUtils::isNotBlank).forEach(attributesIgnored::add);
    }

    return formatOhne(anschrift, attributesIgnored);
  }

  public String formatOhne(ZusammengesetzteAnschrift anschrift, Collection<String> attributesIgnored) {
    return format(buildMsgKey(anschrift, attributesIgnored), anschrift);
  }

  private String format(String msgKey, ZusammengesetzteAnschrift anschrift) {
    return getMessage(msgKey, //
        stripToEmpty(anschrift.getWohnungsgeber()), //
        strip(anschrift.getStrassenname()), //
        stripToEmpty(anschrift.getHausnummer()), //
        stripToEmpty(anschrift.getBuchstabe()), //
        stripToEmpty(anschrift.getZusatz()), //
        stripToEmpty(anschrift.getWohnungsnummer()), //
        strip(anschrift.getPlz()), //
        strip(anschrift.getOrt()), //
        stripToEmpty(anschrift.getOrtsteil()), //
        strip(anschrift.getStaat()));
  }

  protected String buildMsgKey(ZusammengesetzteAnschrift anschrift, Collection<String> attributesIgnored) {
    String msgKey = "";

    if (!attributesIgnored.contains(ATTRIBUTE_WOHNUNGSGEBER) && anschrift.hasWohnungsgeber()) {
      msgKey += ".wohnungsgeber";
    }

    if (!attributesIgnored.contains(ATTRIBUTE_STRASSENNAME) && anschrift.hasStrassenname()) {
      msgKey += ".strasse";
    }

    if (!attributesIgnored.contains(ATTRIBUTE_HAUSNUMMER) && anschrift.hasHausnummer()) {
      msgKey += ".hausnummer";
    }

    if (!attributesIgnored.contains(ATTRIBUTE_BUCHSTABE) && anschrift.hasBuchstabe()) {
      msgKey += ".buchstabe";
    }

    if (!attributesIgnored.contains(ATTRIBUTE_ZUSATZ) && anschrift.hasZusatz()) {
      msgKey += ".zusatz";
    }

    if (!attributesIgnored.contains(ATTRIBUTE_WOHNUNGSNUMMER) && anschrift.hasWohnungsnummer()) {
      msgKey += ".wohnungsnummer";
    }

    if (!attributesIgnored.contains(ATTRIBUTE_PLZ) && anschrift.hasPlz()) {
      msgKey += ".plz";
    }

    if (!attributesIgnored.contains(ATTRIBUTE_ORT) && anschrift.hasOrt()) {
      msgKey += ".ort";
    }

    if (!attributesIgnored.contains(ATTRIBUTE_ORTSTEIL) && anschrift.hasOrtsteil()) {
      msgKey += ".ortsteil";
    }

    if (!attributesIgnored.contains(ATTRIBUTE_STAAT) && anschrift.hasStaat()) {
      msgKey += ".staat";
    }

    if (isNotBlank(msgKey)) {
      return MSG_KEY_PREFIX + msgKey;
    }

    return "";
  }

  protected String getMessage(String msgKey, Object... params) {
    return messages.getMessageForMessageKey(msgKey, params);
  }
}
