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

import static java.util.Objects.nonNull;

import java.util.Objects;

import javax.annotation.Nonnull;

import de.ivu.elect.business.kandidatur.entity.Direktkandidatur;
import de.ivu.elect.business.person.entity.Sperrmerkmal;
import de.ivu.elect.business.security.entity.EntityMitSperrmerkmal;

public abstract class AbstractDirektkandidat extends Wahlvorschlag implements DirektkandidatBase, EntityMitSperrmerkmal {

  private static final long serialVersionUID = 1L;

  public AbstractDirektkandidat() {
    super();
  }

  @Override
  @Nonnull
  public Sperrmerkmal getSperrmerkmal() {
    if (hasDirektkandidatur()) {
      return getDirektkandidatur().getSperrmerkmal();
    }

    return Sperrmerkmal.UNBEKANNT;
  }

  @Override
  public boolean hasSameWahlvorschlagArt(AbstractWahlvorschlag wahlvorschlag) {
    return nonNull(wahlvorschlag) && wahlvorschlag.isDirektkandidat();
  }

  public boolean isParteiWaehlergruppeOderVereinigung() {
    return getGruppeImGebiet().isParteiWaehlergruppeOderVereinigung();
  }

  public boolean isEinzelbewerber() {
    return getGruppeImGebiet().isEinzelbewerber();
  }

  public boolean isPartei() {
    return getGruppeImGebiet().isPartei();
  }

  public boolean isWaehlergruppe() {
    return getGruppeImGebiet().isWaehlergruppe();
  }

  public boolean isVereinigung() {
    return getGruppeImGebiet().isVereinigung();
  }

  public boolean hasDirektkandidatur() {
    return getDirektkandidatur() != null;
  }

  public Direktkandidatur getDirektkandidatur() {
    for (Direktkandidatur direktkandidatur : getDirektkandidatursByDirektkandidat()) {
      return direktkandidatur;
    }

    return null;
  }

  public void setDirektkandidatur(Direktkandidatur direktkandidatur) {
    removeAllDirektkandidaturByDirektkandidats();

    if (direktkandidatur != null) {
      addDirektkandidaturByDirektkandidat(direktkandidatur);
    }
  }

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

  @Override
  public Liste getListe() {
    throw new IllegalStateException("Ist Direktkandidat!");
  }

  @Override
  public boolean isDirektkandidat() {
    return true;
  }

  @Override
  public Direktkandidat getDirektkandidat() {
    return (Direktkandidat) this;
  }

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

  @Override
  public ReferendumOption getReferendumOption() {
    throw new IllegalStateException("Ist Direktkandidat!");
  }

  @Override
  protected void postSetWahlvorschlagStatus(WahlvorschlagStatus alterWert, WahlvorschlagStatus neuerWert) {
    if (neuerWert != null && wertHatSichGeaendert(alterWert, neuerWert) && hasDirektkandidatur()) {
      getDirektkandidatur().setKandidaturStatus(neuerWert.toKandidaturStatus());
    }
  }

  private <T> boolean wertHatSichGeaendert(T alterWert, T neuerWert) {
    return !Objects.equals(alterWert, neuerWert);
  }

  @Override
  protected void postSetKennwort(String alterWert, String neuerWert) {
    super.postSetKennwort(alterWert, neuerWert);

    // Da Einzelbewerber ihre eigene Gruppe bilden, sollte diese jeweils den gleichen Namen haben
    if (isEinzelbewerber() && neuerWert != null && !neuerWert.equals(alterWert)) {
      getGruppe().setName(neuerWert);
    }
  }

  @Override
  protected void postSetKurzname(String alterWert, String neuerWert) {
    super.postSetKurzname(alterWert, neuerWert);

    // Da Einzelbewerber ihre eigene Gruppe bilden, sollte diese jeweils den gleichen Kurznamen haben
    if (isEinzelbewerber()) {
      if (neuerWert != null && !neuerWert.equals(alterWert)) {
        getGruppe().setKurzname(neuerWert);
      } else if (neuerWert == null) {
        getGruppe().setKurzname(getKennwort()); // Bei Gruppe ist Kurzname nicht nullable
      }
    }
  }
}
