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

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

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;

import de.ivu.elect.business.ergebnis.entity.Stimmenart;
import de.ivu.elect.business.wahlvorschlag.entity.ReferendumOption;
import de.ivu.elect.jee.entity.tk.EntityTK;
import de.ivu.elect.jee.presentation.dynamicform.AbstractStringProperty;

/**
 * Eine Zeile in der GUI zur Eingabe von Stimmen für eine Option eines Referendums.
 */
public class StimmeingabeReferendumOptionStimmen extends AbstractStimmeingabeStimmen {

  private static final long serialVersionUID = 1L;

  private final String kennung;
  private final String bezeichnung;

  private final Stimmeingabe stimmeingabe;

  private final String stimmeingabeKennung;
  private final String stimmeingabeBezeichnung;

  private boolean isStimmeingabeZwischensummeAnzahlUngueltigeGesamt = false;
  private boolean isStimmeingabeZwischensummeAnzahlGueltigeGesamt = false;
  private boolean isStimmeingabeZwischensummeAnzahlUebrigeGesamt = false;
  private boolean isStimmeingabeZwischensummeAnzahlAbgegebeneGesamt = false;

  private final List<Stimmeingabefehler> stimmeingabefehlerLetzterErgebniseingang;

  private final Set<String> stimmeingabeStyleClasses;

  public StimmeingabeReferendumOptionStimmen(String kennung, String bezeichnung, Stimmeingabe stimmeingabe, String stimmeingabeKennung, String stimmeingabeBezeichnung,
      List<Stimmeingabefehler> stimmeingabefehlerLetzterErgebniseingang) {
    super();

    this.kennung = kennung;
    this.bezeichnung = bezeichnung;

    this.stimmeingabe = stimmeingabe;
    this.stimmeingabeKennung = stimmeingabeKennung;
    this.stimmeingabeBezeichnung = stimmeingabeBezeichnung;
    this.stimmeingabefehlerLetzterErgebniseingang = stimmeingabefehlerLetzterErgebniseingang;

    this.stimmeingabeStyleClasses = new HashSet<>();
  }

  @Override
  public String getKennung() {
    return kennung;
  }

  @Override
  public String getBezeichnung() {
    return bezeichnung;
  }

  public boolean hasAnzahl() {
    return hasStimmeingabe() && getStimmeingabe().hasAnzahlGroesserGleichNull();
  }

  public Long getAnzahl() {
    return getStimmeingabe().getAnzahl();
  }

  public boolean isAnzahlEingabeRendered() {
    return hasStimmeingabe();
  }

  public boolean hasAnzahlEingabe() {
    return isNotBlank(getAnzahlEingabe());
  }

  public String getAnzahlEingabeOrDefault(String defaultValue) {
    if (hasStimmeingabe()) {
      return defaultIfBlank(getAnzahlEingabe(), defaultValue);
    }

    return "";
  }

  public String getAnzahlEingabe() {
    return getStimmeingabeAnzahlEingabeProperty().getValue();
  }

  public void setAnzahlEingabe(String value) {
    getStimmeingabeAnzahlEingabeProperty().setValue(value);
  }

  private AbstractStringProperty getStimmeingabeAnzahlEingabeProperty() {
    return getStimmeingabe().getProperties().getAnzahlEingabeProperty();
  }

  private boolean hasStimmeingabe() {
    return getStimmeingabe() != null;
  }

  public Stimmeingabe getStimmeingabe() {
    return stimmeingabe;
  }

  public ReferendumOption getReferendumOption() {
    return getStimmeingabe().getReferendumOption();
  }

  @Override
  public Collection<Stimmeingabe> getStimmeingaben() {
    if (hasStimmeingabe()) {
      return Collections.singleton(getStimmeingabe());
    }

    return Collections.emptyList();
  }

  public String getStimmeingabeKennung() {
    return stimmeingabeKennung;
  }

  public String getStimmeingabeBezeichnung() {
    return stimmeingabeBezeichnung;
  }

  public String getStimmeingabeStyleClass() {
    return getStimmeingabeStyleClass(getStimmeingabefehlerLetzterErgebniseingang()) + " " + stimmeingabeStyleClasses.stream().filter(StringUtils::isNotBlank).collect(joining(" ")) + " ";
  }

  public void addStimmeingabeStyleClass(String styleClass) {
    stimmeingabeStyleClasses.add(styleClass);
  }

  @Override
  public String getRowStyleClass() {
    String result = super.getRowStyleClass();

    Stimmenart stimmenart = getStimmenart();

    if (stimmenart != null) {
      result += " " + stimmenart.name() + " ";
    }

    return result;
  }

  public Stimmenart getStimmenart() {
    if (hasStimmeingabe()) {
      return getStimmeingabe().getStimmenart();
    }

    return null;
  }

  @Override
  public List<Stimmeingabefehler> getStimmeingabefehlerLetzterErgebniseingang() {
    return stimmeingabefehlerLetzterErgebniseingang;
  }

  public boolean isStimmeingabeZwischensummeAnzahlUngueltigeGesamt() {
    return isStimmeingabeZwischensummeAnzahlUngueltigeGesamt;
  }

  public void setStimmeingabeZwischensummeAnzahlUngueltigeGesamt(boolean stimmeingabeZwischensummeAnzahlUngueltigeGesamt) {
    isStimmeingabeZwischensummeAnzahlUngueltigeGesamt = stimmeingabeZwischensummeAnzahlUngueltigeGesamt;
  }

  public boolean isStimmeingabeZwischensummeAnzahlGueltigeGesamt() {
    return isStimmeingabeZwischensummeAnzahlGueltigeGesamt;
  }

  public void setStimmeingabeZwischensummeAnzahlGueltigeGesamt(boolean stimmeingabeZwischensummeAnzahlGueltigeGesamt) {
    isStimmeingabeZwischensummeAnzahlGueltigeGesamt = stimmeingabeZwischensummeAnzahlGueltigeGesamt;
  }

  public boolean isStimmeingabeZwischensummeAnzahlUebrigeGesamt() {
    return isStimmeingabeZwischensummeAnzahlUebrigeGesamt;
  }

  public void setStimmeingabeZwischensummeAnzahlUebrigeGesamt(boolean stimmeingabeZwischensummeAnzahlUebrigeGesamt) {
    isStimmeingabeZwischensummeAnzahlUebrigeGesamt = stimmeingabeZwischensummeAnzahlUebrigeGesamt;
  }

  public boolean isStimmeingabeZwischensummeAnzahlAbgegebeneGesamt() {
    return isStimmeingabeZwischensummeAnzahlAbgegebeneGesamt;
  }

  public void setStimmeingabeZwischensummeAnzahlAbgegebeneGesamt(boolean stimmeingabeZwischensummeAnzahlAbgegebeneGesamt) {
    isStimmeingabeZwischensummeAnzahlAbgegebeneGesamt = stimmeingabeZwischensummeAnzahlAbgegebeneGesamt;
  }

  @Override
  public boolean hasTk(EntityTK tk) {
    return hasStimmeingabe() && getStimmeingabe().getTk().equals(tk);
  }

  @Override
  public String getBaseClassName() {
    return getClass().getName();
  }
}
