
package de.ivu.elect.business.wahl.boundary;

import javax.ejb.Stateless;
import javax.inject.Inject;

import de.ivu.elect.business.ergebnis.entity.ZwischenergebnisBerechnenEvent;
import de.ivu.elect.business.replikation.boundary.ReplikationErzeugen;
import de.ivu.elect.business.stimmeingabe.boundary.ErgebniseingangKonfiguration;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingangsart;
import de.ivu.elect.business.wahl.entity.WahlErgebniseingangUebernahmeArt;
import de.ivu.elect.business.wahl.entity.Wahldurchfuehrung;

@Stateless
public class WahlErgebniseingangsartWechseln {

  @Inject
  private transient WahldurchfuehrungDAO wahldurchfuehrungDao;

  @Inject
  private transient ErgebniseingangKonfiguration ergebniseingangKonfiguration;

  @Inject
  private transient WahlErgebniseingangUebernahme wahlErgebniseingangUebernahme;

  @Inject
  private transient ZwischenergebnisBerechnenEvent zwischenergebnisBerechnenEvent;

  @Inject
  private transient ReplikationErzeugen replikationErzeugen;

  public WahlErgebniseingangsartWechseln() {
    super();
  }

  public boolean isWechselnAufEndgueltigeErfassungMoeglich(Wahldurchfuehrung wahldurchfuehrung) {
    return isWechselnAufErgebniseingangsartErfassungMoeglich(wahldurchfuehrung, Ergebniseingangsart.ENDGUELTIG);
  }

  public void wechselnAufEndgueltigeErfassung(Wahldurchfuehrung wahldurchfuehrung, WahlErgebniseingangUebernahmeArt wahlErgebniseingangUebernahmeArt) {
    if (isWechselnAufEndgueltigeErfassungMoeglich(wahldurchfuehrung)) {
      changeErgebniseingangsart(wahldurchfuehrung, Ergebniseingangsart.ENDGUELTIG, wahlErgebniseingangUebernahmeArt);

      if (wahlErgebniseingangUebernahmeArt.isAutomatischeErgebniseingangUebernahmeVonVorlaeufigNachEndgueltigMoeglich()
          && isUebernahmeVorlaeufigerErgebniseingaengeUnterstuetzt(wahldurchfuehrung).isAutomatischeErgebniseingangUebernahmeVonVorlaeufigNachEndgueltigMoeglich()) {
        wahlErgebniseingangUebernahme.tryCopyVorlaeufigeErgebniseingaenge(wahldurchfuehrung, wahlErgebniseingangUebernahmeArt);
      }

      // NOTE, dass die Zwischenergebnisberechnung nur auf die AKTUELLE Ergebniseingangsart geht und somit noch
      // unbetrachtete Ergebniseingänge (z.B. durch Import) vorhanden sein können, cf. ELECTMUC-252
      startZwischenergebnisberechnung();
    }
  }

  public boolean isWechselnAufVorlaeufigeErfassungMoeglich(Wahldurchfuehrung wahldurchfuehrung) {
    return isWechselnAufErgebniseingangsartErfassungMoeglich(wahldurchfuehrung, Ergebniseingangsart.VORLAEUFIG);
  }

  public void wechselnAufVorlaeufigeErfassung(Wahldurchfuehrung wahldurchfuehrung) {
    if (isWechselnAufVorlaeufigeErfassungMoeglich(wahldurchfuehrung)) {
      changeErgebniseingangsart(wahldurchfuehrung, Ergebniseingangsart.VORLAEUFIG, WahlErgebniseingangUebernahmeArt.DEAKTIVIERT);
    }
  }

  private void changeErgebniseingangsart(Wahldurchfuehrung wahldurchfuehrung, Ergebniseingangsart ergebniseingangsart, WahlErgebniseingangUebernahmeArt wahlErgebniseingangUebernahmeArt) {
    Wahldurchfuehrung attach = attach(wahldurchfuehrung);
    attach.setErgebniseingangsart(ergebniseingangsart);
    replikationErzeugen.replikationWechselVorlaeufigEndgueltig(attach, wahlErgebniseingangUebernahmeArt);
  }

  private Wahldurchfuehrung attach(Wahldurchfuehrung wahldurchfuehrungNotAttached) {
    return wahldurchfuehrungDao.attach(wahldurchfuehrungNotAttached);
  }

  public WahlErgebniseingangUebernahmeArt isUebernahmeVorlaeufigerErgebniseingaengeUnterstuetzt(Wahldurchfuehrung wahldurchfuehrung) {
    return wahldurchfuehrung.getWahlart().getErfassungUebernahmeArt();
  }

  private void startZwischenergebnisberechnung() {
    zwischenergebnisBerechnenEvent.sendChangeEvent();
  }

  private boolean isWechselnAufErgebniseingangsartErfassungMoeglich(Wahldurchfuehrung wahldurchfuehrung, Ergebniseingangsart ergebniseingangsart) {
    return ergebniseingangKonfiguration.isErgebniseingangsartUnterstuetzt(wahldurchfuehrung, ergebniseingangsart) && !equalsCurrentErgebniseingangsart(wahldurchfuehrung, ergebniseingangsart);
  }

  private boolean equalsCurrentErgebniseingangsart(Wahldurchfuehrung wahldurchfuehrung, Ergebniseingangsart ergebniseingangsart) {
    return ergebniseingangsart != null && wahldurchfuehrung != null && ergebniseingangsart.equals(attach(wahldurchfuehrung).getErgebniseingangsart());
  }
}
