
package de.ivu.elect.presentation.verteilung.table;

import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
import static org.apache.commons.lang3.StringUtils.trimToEmpty;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.function.BiFunction;

import de.ivu.elect.business.verteilung.boundary.VerteilungContext;
import de.ivu.elect.business.verteilung.boundary.VerteilungQuotient;
import de.ivu.elect.jee.faces.Messages;
import de.ivu.elect.jee.presentation.dynamictable.ColumnType;
import de.ivu.elect.presentation.table.DefaultColumnEntry;
import de.ivu.elect.presentation.verteilung.VerteilungBerechnenViewTeilnehmerErgebnis;

public abstract class AbstractVerteilungBerechnenViewTeilnehmerErgebnisQuotientColumn extends DefaultColumnEntry<VerteilungBerechnenViewTeilnehmerErgebnis> {

  private static final long serialVersionUID = 1L;

  private static final String MARKER_SITZGEWINN = "*";

  private static final String MARKER_RELEVANT_IN_LOSVERFAHREN = "?";

  private static final String MARKER_AUSGEWAEHLT = "*";

  private final boolean markSitzgewinn;

  private final boolean markRelevantInLosverfahren;

  private final boolean markAusgewaehlt;

  protected AbstractVerteilungBerechnenViewTeilnehmerErgebnisQuotientColumn(String id, Messages messages, Locale locale, String headerMsgKey,
      BiFunction<VerteilungContext, VerteilungQuotient, String> quotientFormatter, boolean markSitzgewinn, boolean markRelevantInLosverfahren, boolean markAusgewaehlt) {
    super(id, messages, headerMsgKey, ColumnType.COLLECTION, teilnehmerErgebnis -> teilnehmerErgebnis.getQuotientenRelevant().stream().map(quotient -> {
      String result = "";

      if (markRelevantInLosverfahren && quotient.isRelevantInLosverfahren()) {
        result += " " + MARKER_RELEVANT_IN_LOSVERFAHREN;
      }

      if (markSitzgewinn && quotient.isSitzgewinn()) {
        result += " " + MARKER_SITZGEWINN;
      }

      if (markAusgewaehlt && quotient.isAusgewaehlt()) {
        result += " " + MARKER_AUSGEWAEHLT;
      }

      // Wert nach hinten, da Spalte rechtsbündig (numerische Werte) angezeigt werden...
      result += " " + quotientFormatter.apply(teilnehmerErgebnis.getVerteilungContext(), quotient);

      return result;
    }).collect(toList()));

    this.markSitzgewinn = markSitzgewinn;
    this.markRelevantInLosverfahren = markRelevantInLosverfahren;
    this.markAusgewaehlt = markAusgewaehlt;
  }

  @Override
  public String getStyleClass() {
    return trimToEmpty(super.getStyleClass()) + " ui-dt-anzahl";
  }

  @Override
  public String getTooltip(VerteilungBerechnenViewTeilnehmerErgebnis teilnehmerErgebnis) {
    String result = "";

    if (teilnehmerErgebnis != null) {
      result = collectTooltips(teilnehmerErgebnis).stream().collect(joining(TOOLTIP_LINE_SEPARATOR));
    }

    return defaultIfBlank(result, super.getTooltip(teilnehmerErgebnis));
  }

  public List<String> collectTooltips(VerteilungBerechnenViewTeilnehmerErgebnis teilnehmerErgebnis) {
    List<String> result = new ArrayList<>();

    List<VerteilungQuotient> quotienten = teilnehmerErgebnis.getQuotientenRelevant();

    if (markSitzgewinn && quotienten.stream().anyMatch(VerteilungQuotient::isSitzgewinn)) {
      result.add(getMessage("AbstractVerteilungBerechnenViewTeilnehmerErgebnisQuotientColumn.tooltip.sitzgewinn", MARKER_SITZGEWINN));
    }

    if (markRelevantInLosverfahren && quotienten.stream().anyMatch(VerteilungQuotient::isRelevantInLosverfahren)) {
      result.add(getMessage("AbstractVerteilungBerechnenViewTeilnehmerErgebnisQuotientColumn.tooltip.losverfahren", MARKER_RELEVANT_IN_LOSVERFAHREN));
    }

    if (markAusgewaehlt && quotienten.stream().anyMatch(VerteilungQuotient::isAusgewaehlt)) {
      result.add(getMessage("AbstractVerteilungBerechnenViewTeilnehmerErgebnisQuotientColumn.tooltip.ausgewaehlt", MARKER_AUSGEWAEHLT));
    }

    return result;
  }
}
