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

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

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;

import de.ivu.elect.jee.presentation.dynamicform.AbstractPickListProperty;

public class ErgebnisKonfliktLosoptionPickListProperty extends AbstractPickListProperty<ErgebnisKonfliktLosoption> {

  private final AbstractErgebnisKonfliktLosoptionenCustomData ergebnisKonfliktCustomData;

  private final List<ErgebnisKonfliktLosoption> losoptionenAuswaehlbar;

  private final List<ErgebnisKonfliktLosoption> losoptionenGelost;

  private final Map<String, ErgebnisKonfliktLosoption> losoptionenPerPk;

  public ErgebnisKonfliktLosoptionPickListProperty(AbstractErgebnisKonfliktLosoptionenCustomData ergebnisKonfliktCustomData,
      List<ErgebnisKonfliktLosoption> losoptionenVerfuegbar, List<ErgebnisKonfliktLosoption> losoptionenGelost) {
    super();

    this.ergebnisKonfliktCustomData = ergebnisKonfliktCustomData;

    this.losoptionenGelost = losoptionenGelost;

    this.losoptionenAuswaehlbar = losoptionenVerfuegbar;
    this.losoptionenAuswaehlbar.removeAll(this.losoptionenGelost);

    this.losoptionenPerPk = createLosoptionenPerPk(this.losoptionenAuswaehlbar, this.losoptionenGelost);
  }

  @Override
  public Converter getDefaultConverter() {
    return new ErgebnisKonfliktLosoptionConverter();
  }

  private Map<String, ErgebnisKonfliktLosoption> getLosoptionenPerPk() {
    return losoptionenPerPk;
  }

  @Override
  protected List<ErgebnisKonfliktLosoption> getVerfuegbareElemente() {
    return losoptionenAuswaehlbar;
  }

  @Override
  protected List<ErgebnisKonfliktLosoption> getZugeordneteElemente() {
    return losoptionenGelost;
  }

  @Override
  protected void setzeZugeordneteElemente(List<ErgebnisKonfliktLosoption> target) {
    ergebnisKonfliktCustomData.setLosoptionenGelost(target);
  }

  @Override
  protected String getSourceCaptionMessageKey() {
    return "ergebnis.konflikt.losoption.property.source.caption";
  }

  @Override
  protected String getTargetCaptionMessageKey() {
    return "ergebnis.konflikt.losoption.property.target.caption";
  }

  @Override
  public String getItemLabel(ErgebnisKonfliktLosoption item) {
    if (item != null && item.hasLosoptionName()) {
      return item.getLosoptionName();
    }

    return "";
  }

  @Override
  public boolean getDefaultRequired() {
    return ergebnisKonfliktCustomData.getAnzahlZuLosen() > 0;
  }

  @Override
  public String getDefaultLabel() {
    return getMessage(AbstractErgebnisKonfliktLosoptionenCustomDataConstants.MESSAGE_KEY_LOSOPTION_MEHRZAHL);
  }

  public final class ErgebnisKonfliktLosoptionConverter implements Converter {

    @Override
    public String getAsString(FacesContext ctx, UIComponent component, Object value) {
      if (value instanceof ErgebnisKonfliktLosoption) {
        for (Entry<String, ErgebnisKonfliktLosoption> entry : getLosoptionenPerPk().entrySet()) {
          if (value.equals(entry.getValue())) {
            return entry.getKey();
          }
        }
      }

      return null;
    }

    @Override
    public Object getAsObject(FacesContext ctx, UIComponent component, String value) {
      if (isNotBlank(value)) {
        return getLosoptionenPerPk().get(value);
      }

      return null;
    }
  }

  private static Map<String, ErgebnisKonfliktLosoption> createLosoptionenPerPk(List<ErgebnisKonfliktLosoption> losoptionenAuswaehlbar,
      List<ErgebnisKonfliktLosoption> losoptionenGelost) {
    Map<String, ErgebnisKonfliktLosoption> result = new HashMap<>();

    mapLosoptionenPerPk(result, losoptionenAuswaehlbar);
    mapLosoptionenPerPk(result, losoptionenGelost);

    return result;
  }

  private static void mapLosoptionenPerPk(Map<String, ErgebnisKonfliktLosoption> result, List<ErgebnisKonfliktLosoption> losoptionen) {
    for (ErgebnisKonfliktLosoption losoption : losoptionen) {
      result.put(losoption.getPk().toString(), losoption);
    }
  }

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