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

import java.util.Collection;
import java.util.List;

import de.ivu.elect.business.benutzerverwaltung.boundary.AbstractBenutzerDAO;
import de.ivu.elect.business.benutzerverwaltung.entity.Benutzer;
import de.ivu.elect.business.gebietsbaum.entity.EntityMitGebiet;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.person.entity.PersonStatus;
import de.ivu.elect.business.person.entity.Personendaten;
import de.ivu.elect.business.security.entity.EntityMitSperrmerkmal;
import de.ivu.elect.business.unterstuetzer.control.UnterstuetzerEingangssequenznummer;
import de.ivu.elect.business.unterstuetzer.entity.EintragungslisteEintrag;
import de.ivu.elect.business.unterstuetzer.entity.EintragungslisteEintragGueltigkeit;
import de.ivu.elect.business.wahlvorschlag.entity.EntityMitWahlvorschlag;
import de.ivu.elect.jee.entity.customdata.CustomData;
import de.ivu.elect.jee.entity.customdata.EmptyCustomData;

public abstract class AbstractWahlvorschlagsPerson extends Personendaten implements WahlvorschlagsPersonBase, EntityMitWahlvorschlag, EntityMitGebiet, EntityMitSperrmerkmal {

  private static final long serialVersionUID = 1L;

  public AbstractWahlvorschlagsPerson() {
    super();
  }

  public AbstractWahlvorschlagsPerson(CustomData customData) {
    super(customData);
  }

  @Override
  protected void postSetPersonStatus(PersonStatus alterWert, PersonStatus neuerWert) {
    if (PersonStatus.GEEIGNET.equals(neuerWert)) {
      getEintragungslisteEintraege().forEach(eintragungslisteEintrag -> eintragungslisteEintrag.setGueltigkeit(EintragungslisteEintragGueltigkeit.GUELTIG));
    } else if (PersonStatus.MANUELL_ZU_PRUEFENDER_KONFLIKT_VORHANDEN.equals(neuerWert)) {
      getEintragungslisteEintraege().forEach(eintragungslisteEintrag -> eintragungslisteEintrag.setGueltigkeit(EintragungslisteEintragGueltigkeit.UNGUELTIG_PERSONENDATEN_MANUELL_ZU_PRUEFEN));
    }
  }

  @Override
  public Gebiet getGebiet() {
    if (hasWahlvorschlag()) {
      return getWahlvorschlag().getGebiet();
    }

    return super.getGebiet();
  }

  public Gruppe getGruppe() {
    if (hasWahlvorschlag()) {
      return getWahlvorschlag().getGruppe();
    }

    return null;
  }

  @Override
  public boolean hasWahl() {
    return getWahl() != null;
  }

  @Override
  public boolean hasWahlvorschlag() {
    return getWahlvorschlag() != null;
  }

  public boolean isAllgemeineWahlvorschlagsPerson() {
    return !isIndividuelleWahlvorschlagsPerson();
  }

  public boolean isIndividuelleWahlvorschlagsPerson() {
    return getKandidatur() != null;
  }

  public boolean hasEingangssequenznummer() {
    return getEingangssequenznummer() != null;
  }

  public void setEingangssequenznummer(UnterstuetzerEingangssequenznummer eingangssequenznummer) {
    setEingangssequenznummer(eingangssequenznummer.getSequenznummer());
  }

  public boolean isWahlvorschlagsPersonTyp(WahlvorschlagsPersonTyp wahlvorschlagsPersonTyp) {
    if (wahlvorschlagsPersonTyp == null) {
      return getWahlvorschlagsPersonTyp() == null;
    }

    return wahlvorschlagsPersonTyp.equals(getWahlvorschlagsPersonTyp());
  }

  public boolean isUnterstuetzer() {
    return isWahlvorschlagsPersonTyp(WahlvorschlagsPersonTyp.UNTERSTUETZER);
  }

  public boolean isUnterstuetzerErfasstAufEintragungsliste() {
    if (hasWahl()) { // ELECTMUC-1824
      return getWahl().isWahlMitUnterstuetzerAufEintragungslisten();
    }

    return false;
  }

  public Long getAnzahlEintragungslisteEintraegePerEintragungslisteErwartet() {
    if (hasWahl()) {
      return getWahl().getAnzahlUnterstuetzerPerEintragungsliste();
    }

    return 0L;
  }

  public boolean hasEintragungslisteEintrag() {
    return !getEintragungslisteEintraege().isEmpty();
  }

  public EintragungslisteEintrag getEintragungslisteEintrag() {
    if (hasEintragungslisteEintrag()) {
      Collection<EintragungslisteEintrag> eintragungslisteEintraege = getEintragungslisteEintraege();

      if (eintragungslisteEintraege.size() > 1) {
        throw new IllegalStateException("Einzelner Eintrag auf Eintragungsliste erwartet, aber " + eintragungslisteEintraege.size() + " Einträge gefunden");
      }

      return eintragungslisteEintraege.iterator().next();
    }

    return null;
  }

  public void setEintragungslisteEintrag(EintragungslisteEintrag eintragungslisteEintrag) {
    removeAllEintragungslisteEintraege();

    if (eintragungslisteEintrag != null) {
      addEintragungslisteEintrag(eintragungslisteEintrag);
    }
  }

  public Collection<EintragungslisteEintrag> getEintragungslisteEintraege() {
    return getEintragungslisteEintragsByWahlvorschlagsPerson();
  }

  private void addEintragungslisteEintrag(EintragungslisteEintrag eintragungslisteEintrag) {
    addEintragungslisteEintragByWahlvorschlagsPerson(eintragungslisteEintrag);
  }

  private void removeAllEintragungslisteEintraege() {
    removeAllEintragungslisteEintragByWahlvorschlagsPersons();
  }

  // ELECT-8970
  public Benutzer findErstellungErfasser(AbstractBenutzerDAO benutzerDAO) {

    List<Benutzer> byBenutzerkennungUpper = benutzerDAO.findByBenutzerkennungUpper(getMandant(), getErstellungErfasserKennung());
    if (byBenutzerkennungUpper.size() == 1) {
      return byBenutzerkennungUpper.get(0);
    }

    Benutzer benutzer = new Benutzer(EmptyCustomData.INSTANCE);
    benutzer.setBenutzerkennung(getErstellungErfasserKennung());
    benutzer.setFamilienname(getErstellungErfasserFamilienname());
    benutzer.setVorname(getErstellungErfasserVorname());

    return benutzer;
  }

  public String getErstellungErfasserKennung() {
    return getErstellungErfasser();
  }

  public String getErstellungErfasserFamilienname() {
    return getErstellungErfasserKennung(); // Solange nicht in DB hinterlegt -> Legacy-Wert zur Anzeige.
  }

  public String getErstellungErfasserVorname() {
    return "";
  }
}
