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

import de.ivu.elect.business.ergebnis.entity.Gewaehlt;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.kandidatur.entity.KandidaturGewaehlt;
import de.ivu.elect.jee.faces.Messages;
import de.ivu.elect.jee.presentation.dynamictable.ColumnType;

import javax.annotation.Nullable;

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

// Cf. AbstractKandidaturKumulierteStimmenGewaehltRangColumn!
public class KandidaturGewaehltGewaehltRangColumn extends AbstractKandidaturGewaehltGewaehltColumn {

  private static final long serialVersionUID = 1L;

  private static final String MSG_KEY_PREFIX = "kumulierte.stimmen.search.page.abstand.rang.position.";

  private final Gebiet gebietSelected;

  public KandidaturGewaehltGewaehltRangColumn(@Nullable Gebiet gebietSelected, Messages messages) {
    super(messages);

    this.gebietSelected = gebietSelected;
  }

  // ELECTMUC-2783
  private boolean isGebietMitWahlgebietInGebietshierarchieUntergeordnet(Gebiet gebiet) {
    return gebiet != null && gebiet.isWahlOderDirektwahlOderListenwahlgebietOderHatEntprechendesUntergebiet()
        || gebiet == null && gebietSelected != null && gebietSelected.isWahlOderDirektwahlOderListenwahlgebietOderHatEntprechendesUntergebiet();
  }

  @Override
  public ColumnType getType() {
    return ColumnType.LONG;
  }

  @Override
  public String getHeader() {
    return getMessage(MSG_KEY_PREFIX + "header");
  }

  @Override
  @Nullable
  public Long getValue(Gewaehlt gewaehlt) {
    if (gewaehlt != null && gewaehlt.getRang() > 0L) { // ELECT-9300
      return gewaehlt.getRang();
    }

    return null;
  }

  @Override // ELECT-8802
  public String getTooltip(KandidaturGewaehlt kandidaturGewaehlt) {
    String defaultTooltip = getDefaultTooltip(kandidaturGewaehlt);

    if (kandidaturGewaehlt != null) {
      return getTooltipByAbstandStimmzettelPositionGewaehltRang(gebietSelected, getStimmzettelPosition(kandidaturGewaehlt), getRang(kandidaturGewaehlt), defaultTooltip);
    }

    return defaultTooltip;
  }

  protected String getDefaultTooltip(KandidaturGewaehlt kandidaturGewaehlt) {
    return super.getTooltip(kandidaturGewaehlt);
  }

  public String getTooltipByAbstandStimmzettelPositionGewaehltRang(Gebiet gebiet, Long stimmzettelPosition, Long gewaehltRang, String defaultTooltip) {
    if (isGebietMitWahlgebietInGebietshierarchieUntergeordnet(gebiet) && exceedsAbstandStimmzettelPositionGewaehltRang(stimmzettelPosition, gewaehltRang)) {
      return trimToEmpty(defaultTooltip) + " " + getMessage(MSG_KEY_PREFIX + "tooltip");
    }

    return defaultTooltip;
  }

  @Override // ELECT-8802
  public String getStyleClass(KandidaturGewaehlt kandidaturGewaehlt) {
    String defaultStyleClass = getDefaultStyleClass(kandidaturGewaehlt);

    if (kandidaturGewaehlt != null) {
      return getStyleClassByAbstandStimmzettelPositionGewaehltRang(gebietSelected, getStimmzettelPosition(kandidaturGewaehlt), getRang(kandidaturGewaehlt), defaultStyleClass);
    }

    return defaultStyleClass;
  }

  protected String getDefaultStyleClass(KandidaturGewaehlt kandidaturGewaehlt) {
    return super.getStyleClass(kandidaturGewaehlt);
  }

  public String getStyleClassByAbstandStimmzettelPositionGewaehltRang(Gebiet gebiet, Long stimmzettelPosition, Long gewaehltRang, String defaultStyleClass) {
    if (isGebietMitWahlgebietInGebietshierarchieUntergeordnet(gebiet) && exceedsAbstandStimmzettelPositionGewaehltRang(stimmzettelPosition, gewaehltRang)) {
      return trimToEmpty(defaultStyleClass) + " ui-messages-error";
    }

    return defaultStyleClass;
  }

  private boolean exceedsAbstandStimmzettelPositionGewaehltRang(Long stimmzettelPosition, Long gewaehltRang) {
    return stimmzettelPosition != null && gewaehltRang != null && Math.abs(stimmzettelPosition - gewaehltRang) > 1;
  }

  private Long getStimmzettelPosition(KandidaturGewaehlt kandidaturGewaehlt) {
    return kandidaturGewaehlt.getStimmzettelPosition();
  }

  private Long getRang(KandidaturGewaehlt kandidaturGewaehlt) {
    return getValue(kandidaturGewaehlt.getGewaehlt());
  }
}
