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

import java.io.Serializable;
import java.util.Map;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.business.mandant.entity.MandantPK;
import de.ivu.elect.business.wahl.control.WahlMandantenAufteilenAsynchron;
import de.ivu.elect.business.wahl.control.WahlMandantenAufteilenStatusErmittler;
import de.ivu.elect.business.wahl.control.WahlMandantenAufteilenSynchron;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.WahlaufteilenResultContainer;
import de.ivu.elect.business.wahl.entity.WahlaufteilenStatusContainer;

@Stateless
public class WahlMandantenAufteilen implements Serializable {

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

  private static final long serialVersionUID = 1L;

  @Inject
  private transient WahlMandantenAufteilenStatusErmittler wahlMandantenAufteilenStatusErmittler;

  @Inject
  private transient WahldurchfuehrungDAO wahldurchfuehrungDAO;

  @Inject
  private transient WahlMandantenAufteilenSynchron wahlMandantenAufteilenSynchron;
  
  @Inject
  private transient WahlMandantenAufteilenAsynchron wahlMandantenAufteilenAsynchron;

  public Map<MandantPK, WahlaufteilenStatusContainer> bestimmeStatusFuerMandanten(Wahl wahlNotattached) {
    return wahlMandantenAufteilenStatusErmittler.bestimmeStatusFuerMandanten(wahlNotattached.getPk());
  }

  @Nullable // null=asynchron (dirty)
  public Map<MandantPK, WahlaufteilenResultContainer> aufteilen(Wahl wahlNotattached) {
    var wahl = wahldurchfuehrungDAO.findByPrimaryKey(wahlNotattached.getPk());

    // daktiviert mit ELECT-16175 // Zunächst Reihenfolgen herunterbrechen (ELECTKOM-911)
    // gruppeImGebietReihenfolgeAufUntergebieteUebernehmer.uebernehmeReihenfolgeAufUntergeordneteGebiet(wahl.getWurzelgebiet(wahldurchfuehrungsgebietDAO), false);

    var mandantPKWahlaufteilenResultContainerMap = wahlMandantenAufteilenStatusErmittler.bestimmeAufzuteilendeMandanten(wahl.getPk());
    if (mandantPKWahlaufteilenResultContainerMap.size() > wahlMandantenAufteilenSynchron.bestimmeAnzahlMandantenProTransaktion()) {
      LOG.info("Wahl asynchron aufteilen");
      wahlMandantenAufteilenAsynchron.aufteilen(wahl.getPk());
      LOG.info("Wahl asynchron aufteilen - gestartet");
      return null;
    }
    LOG.info("Wahl synchron aufteilen");
    return wahlMandantenAufteilenSynchron.aufteilen(wahl.getPk(), mandantPKWahlaufteilenResultContainerMap);
  }

  public void aufgeteilteWahlenLoeschen(Wahl wahlNotAttached) {
    LOG.info("Wahlen löschen asynchron");
    wahlMandantenAufteilenAsynchron.aufgeteilteWahlenLoeschen(wahlNotAttached.getPk());
    LOG.info("Wahlen löschen asynchron - gestartet");

  }

}
