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

import de.ivu.elect.business.ergebnis.boundary.ErgebnisBerechnenAusloesenEvent;
import de.ivu.elect.business.ergebnis.boundary.ErgebnisDAO;
import de.ivu.elect.business.ergebnis.entity.Ergebnis;
import de.ivu.elect.business.ergebniskonflikt.boundary.ErgebnisKonfliktDAO;
import de.ivu.elect.business.ergebniskonflikt.entity.ErgebnisKonflikt;
import de.ivu.elect.business.gebietsbaum.boundary.GebietDAO;
import de.ivu.elect.business.gebietsbaum.control.EntityMitWurzelgebietDAO;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingabestatus;
import de.ivu.elect.business.wahl.entity.NlWahlPhase;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.Wahldurchfuehrung;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

@Stateless
@Specializes
public class NlWasWahlprozess extends NlWahlprozess {

  private static final Logger LOG = LoggerFactory.getLogger(NlWasWahlprozess.class);

  @Inject
  private transient GebietDAO gebietDAO;

  @Inject
  private transient ErgebnisKonfliktDAO ergebnisKonfliktDAO;

  @Inject
  private transient ErgebnisDAO ergebnisDAO;

  @Inject
  private transient ErgebnisBerechnenAusloesenEvent ergebnisBerechnenAusloesenEvent;

  @Override
  protected void setzePhase(NlWahlPhase nlWahlPhase, Wahl wahl) {
    Wahldurchfuehrung wahldurchfuehrung = wahl.castTo(Wahldurchfuehrung.class).getEntity();
    Gebiet wurzelgebiet = wahl.getWurzelgebiet(EntityMitWurzelgebietDAO.fromDao(gebietDAO));
    if (wurzelgebiet != null) {
      wurzelgebiet.castTo(Wahldurchfuehrungsgebiet.class).getEntity()
          .setErgebniseingabestatus(bestimmeErfassungsstatus(nlWahlPhase), wahldurchfuehrung.getErgebniseingangsart());
    }

    NlWahlPhase phaseBisher = bestimmeNlWahlPhaseBisher(wahl);

    if (nlWahlPhase.isAbschluss()) {
      LOG.info("Von " + phaseBisher + " nach " + nlWahlPhase);
      boolean ergebnisBerechnen = false;
      if (phaseBisher.isSitzberechnung()) {
        // ELECTVAPP-263 von Phase 4 -> 3 Losentscheide löschen

        for (Ergebnis ergebnis : ergebnisDAO.findByWahl(wahl)) {
          for (ErgebnisKonflikt ergebnisKonflikt : ergebnisKonfliktDAO.findByErgebnisOrderById(ergebnis)) {
            LOG.info("Lösche Losentscheid: " + ergebnisKonflikt);
            ergebnisKonfliktDAO.remove(ergebnisKonflikt);
            ergebnisBerechnen = true;
          }
        }
      } else if (phaseBisher.isErfassung()) {
        //ELECT-10800
        ergebnisBerechnen = true;
      }

      if (ergebnisBerechnen) {
        ergebnisBerechnenAusloesenEvent.sendErgebnisBerechnenAusloesenEvent(wahl, false);
      }
    }

    super.setzePhase(nlWahlPhase, wahl);
  }

  private Ergebniseingabestatus bestimmeErfassungsstatus(NlWahlPhase nlWahlPhase) {

    //  Hier mal aus Faulheit per switch
    switch (nlWahlPhase) {
      case INITIAL:
      case ERFASSUNG:
        return Ergebniseingabestatus.EINGABE_MOEGLICH;
      case ABSCHLUSS:
      case SITZBERECHNUNG:
        return Ergebniseingabestatus.ABGESCHLOSSEN;
      case FREIGABE:
        return Ergebniseingabestatus.FREIGEGEBEN;

    }

    throw new IllegalArgumentException("Implement me: " + nlWahlPhase);

  }
}
