
package de.ivu.elect.business.ergebnis.control;

import static java.util.Objects.nonNull;

import javax.enterprise.event.Observes;
import javax.enterprise.event.Reception;
import javax.inject.Inject;

import de.ivu.elect.business.ergebnis.boundary.ErgebnisSelectChangeEvent;
import de.ivu.elect.business.ergebnis.entity.Ergebnis;
import de.ivu.elect.business.ergebnis.entity.Ergebnisart;
import de.ivu.elect.business.ergebnis.entity.Stimmabgabeart;
import de.ivu.elect.business.gebietsbaum.boundary.GebietSelectChangeEvent;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gebietsbaum.entity.Gebietsgruppierung;
import de.ivu.elect.business.search.control.AbstractElectSearchParameters;
import de.ivu.elect.business.wahl.boundary.WahlSelectChangeEvent;
import de.ivu.elect.business.wahl.boundary.WahlterminSelectChangeEvent;

public abstract class AbstractKumulierteStimmenSearchParameters extends AbstractElectSearchParameters {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient StimmenSearchParameterDefault stimmenSearchParameterDefault;

  private Gebiet gebietSelected;

  private Ergebnis ergebnisSelected;

  private Stimmabgabeart stimmabgabeart;

  private Ergebnisart ergebnisartFuerDifferenz;

  private Gebietsgruppierung gebietsgruppierung;

  public AbstractKumulierteStimmenSearchParameters() {
    super();

    this.stimmabgabeart = null;
    this.ergebnisartFuerDifferenz = null;
    this.gebietsgruppierung = null;
  }

  public Gebiet getGebietSelected() {
    return gebietSelected;
  }

  public void setGebietSelected(Gebiet gebietSelected) {
    this.gebietSelected = gebietSelected;
  }

  public Ergebnis getErgebnisSelected() {
    return ergebnisSelected;
  }

  public void setErgebnisSelected(Ergebnis ergebnisSelected) {
    this.ergebnisSelected = ergebnisSelected;
  }

  public Ergebnisart getErgebnisartFuerDifferenz() {
    if (ergebnisartFuerDifferenz == null) {
      ergebnisartFuerDifferenz = stimmenSearchParameterDefault.getErgebnisartFuerDifferenz();
    }

    return ergebnisartFuerDifferenz;
  }

  public void setErgebnisartFuerDifferenz(Ergebnisart ergebnisartFuerDifferenz) {
    this.ergebnisartFuerDifferenz = ergebnisartFuerDifferenz;
  }

  public Stimmabgabeart getStimmabgabeart() {
    if (stimmabgabeart == null) {
      stimmabgabeart = stimmenSearchParameterDefault.getStimmabgabeart();
    }

    return stimmabgabeart;
  }

  public void setStimmabgabeart(Stimmabgabeart stimmabgabeart) {
    this.stimmabgabeart = stimmabgabeart;
  }

  public boolean hasGebietsgruppierung() {
    return nonNull(getGebietsgruppierung());
  }

  public Gebietsgruppierung getGebietsgruppierung() {
    return gebietsgruppierung;
  }

  public void setGebietsgruppierung(Gebietsgruppierung gebietsgruppierung) {
    this.gebietsgruppierung = gebietsgruppierung;
  }

  public boolean isSystemGruppeUebrigeIncludesEinzelbewerber() {
    // WASDE-2051 Wird anscheinend nicht per Property gesetzt und ist abhängig vom ausgewählten Gebiet. Daher immer berechnen und nicht cachen.
    return stimmenSearchParameterDefault.getSystemGruppeUebrigeIncludesEinzelbewerber(getGebietSelected());
  }

  @Override
  public void reset() {
    super.reset();

    this.stimmabgabeart = null;
    this.ergebnisartFuerDifferenz = null;
    this.gebietsgruppierung = null;
  }

  // NOTE ELECT-2231, ELECT-2250, dass Suchparameter von der zur Bearbeitung ausgewählten Wahl bzw. dem ausgewählten Wahltermin abhängig sind.
  public void onWahlSelectChangeEvent(@Observes(notifyObserver = Reception.IF_EXISTS) WahlSelectChangeEvent event) {
    reset();
  }

  public void onWahlterminSelectChangeEvent(@Observes(notifyObserver = Reception.IF_EXISTS) WahlterminSelectChangeEvent event) {
    reset();
  }

  // ELECT-8469
  public void onErgebnisSelectChangeEvent(@Observes(notifyObserver = Reception.IF_EXISTS) ErgebnisSelectChangeEvent event) {
    reset();

    setErgebnisSelected(event.getNeueEntity());
  }

  // NOTE ELECTMUC-208, ELECTMUC-882, dass Suchparameter ggf. (!) vom ausgewählten Gebiet abhängig sind. Wird dieses gewechselt müssen
  // NICHT alle Werte des Suchparameter, zumindest aber die Pagination, zurückgesetzt werden!
  public void onGebietSelectChangeEvent(@Observes(notifyObserver = Reception.IF_EXISTS) GebietSelectChangeEvent event) {
    resetFirst();

    setGebietSelected(event.getNeueEntity());
  }
}
