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

import java.util.List;
import java.util.Map;
import java.util.Optional;

import javax.annotation.Nullable;

import de.ivu.elect.business.ergebnis.entity.AbstractKumulierteStimmen;
import de.ivu.elect.business.ergebnis.entity.Ergebnisart;
import de.ivu.elect.business.ergebnis.entity.Gewaehlt;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.person.entity.PersonendatenPK;
import de.ivu.elect.business.person.entity.PersonendatenUK;
import de.ivu.elect.business.stimmzettel.entity.EntityAufStimmzettelDaten;
import de.ivu.elect.business.wahlvorschlag.entity.Wahlvorschlag;
import de.ivu.elect.jee.entity.Entity;
import de.ivu.elect.jee.entity.EntityContainer;
import de.ivu.elect.jee.entity.EntityFachlichAbhaengigNode;
import de.ivu.elect.jee.entity.tk.EntityTK;
import de.ivu.elect.jee.protokollierung.VorherNachherWert;

public class KandidaturKumulierteStimmen extends AbstractKumulierteStimmen implements Entity<PersonendatenPK, PersonendatenUK> {

  private static final long serialVersionUID = 1L;

  private final Gebiet gebiet;

  private final Direktkandidatur direktkandidatur;

  private final Listenkandidatur listenkandidatur;

  private final Long anzahlListenstimmenAnteilAusWahlvorschlagstimmvergabe;

  private final Long anzahlListenstimmenAnteilAusEinzelstimmvergabe;

  private final Long anzahlListenstimmenNichtErgebnisrelevant;

  public KandidaturKumulierteStimmen(EntityAufStimmzettelDaten entityAufStimmzettelDaten, Gebiet gebiet, Direktkandidatur direktkandidatur, Long anzahlDirektstimmen, Listenkandidatur listenkandidatur,
      Long anzahlListenstimmen, Long anzahlListenstimmenAnteilAusEinzelstimmvergabe, Long anzahlListenstimmenAnteilAusWahlvorschlagstimmvergabe, Long anzahlListenstimmenNichtErgebnisrelevant) {
    super(entityAufStimmzettelDaten, anzahlDirektstimmen, anzahlListenstimmen);

    this.gebiet = gebiet;

    this.direktkandidatur = direktkandidatur;
    this.listenkandidatur = listenkandidatur;

    this.anzahlListenstimmenAnteilAusWahlvorschlagstimmvergabe = anzahlListenstimmenAnteilAusWahlvorschlagstimmvergabe;
    this.anzahlListenstimmenAnteilAusEinzelstimmvergabe = anzahlListenstimmenAnteilAusEinzelstimmvergabe;

    this.anzahlListenstimmenNichtErgebnisrelevant = anzahlListenstimmenNichtErgebnisrelevant;
  }

  @Nullable
  public Long getStimmzettelPosition() {
    if (getListenkandidatur() != null) {
      return getStimmzettelPosition(getListenkandidatur());
    }

    if (getDirektkandidatur() != null) {
      return getStimmzettelPosition(getDirektkandidatur());
    }

    return null;
  }

  public Gebiet getGebiet() {
    return gebiet;
  }

  public Wahlvorschlag getWahlvorschlag() {
    if (getDirektkandidatur() != null) {
      return getDirektkandidatur().getWahlvorschlag();
    }

    if (getListenkandidatur() != null) {
      return getListenkandidatur().getWahlvorschlag();
    }

    return null;
  }

  public Direktkandidatur getDirektkandidatur() {
    return direktkandidatur;
  }

  public Listenkandidatur getListenkandidatur() {
    return listenkandidatur;
  }

  public Optional<Gewaehlt> getGewaehlt(Kandidatur kandidatur, Ergebnisart ergebnisart) {
    if (kandidatur != null) {
      return kandidatur.getGewaehlteByErgebnisart(ergebnisart).stream().findAny();
    }

    return Optional.empty();
  }

  @Override
  public PersonendatenPK getPk() {
    if (getDirektkandidatur() != null) {
      return getDirektkandidatur().getPk();
    }

    return getListenkandidatur().getPk();
  }

  @Override
  public Long getId() {
    return getPk().getId();
  }

  @Override
  public PersonendatenUK getUk() {
    if (getDirektkandidatur() != null) {
      return getDirektkandidatur().getUk();
    }

    return getListenkandidatur().getUk();
  }

  @Override
  public Class< ? > getEntityClass() {
    throw new UnsupportedOperationException();
  }

  @Override
  public EntityTK getTk() {
    if (getDirektkandidatur() != null) {
      return getDirektkandidatur().getTk();
    }

    return getListenkandidatur().getTk();
  }

  @Override
  public String getEntityTechnicalName() {
    throw new UnsupportedOperationException();
  }

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

  @Override
  public Map<String, VorherNachherWert> getProtokollierteAttributeMitWerten() {
    throw new UnsupportedOperationException();
  }

  @Override
  public void resetProtokollierteAttribute() {
    throw new UnsupportedOperationException();
  }

  @Override
  public List<EntityFachlichAbhaengigNode> getFachlichAbhaengigeEntitaeten() {
    throw new UnsupportedOperationException();
  }

  @Override
  public boolean isInstanceOf(Class< ? > clazz) {
    return false;
  }

  @Override
  public <E> EntityContainer<E> castTo(Class<E> clazz) {
    throw new UnsupportedOperationException();
  }

  public String getName() {
    if (getDirektkandidatur() != null) {
      return getName(getDirektkandidatur());
    }

    return getName(getListenkandidatur());
  }

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

  public boolean isListenkandidaturVorhanden() {
    return getListenkandidatur() != null;
  }

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

  public Long getAnzahlListenstimmenAnteilAusWahlvorschlagstimmvergabe() {
    return anzahlListenstimmenAnteilAusWahlvorschlagstimmvergabe;
  }

  public Long getAnzahlListenstimmenAnteilAusEinzelstimmvergabe() {
    return anzahlListenstimmenAnteilAusEinzelstimmvergabe;
  }

  public boolean isAnzahlListenstimmenNichtErgebnisrelevantVorhanden() {
    return anzahlListenstimmenNichtErgebnisrelevant != null && anzahlListenstimmenNichtErgebnisrelevant > 0;
  }

  public Long getAnzahlListenstimmenNichtErgebnisrelevant() {
    return anzahlListenstimmenNichtErgebnisrelevant;
  }
}
