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

import java.io.Serializable;
import java.util.function.BooleanSupplier;

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

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

import de.ivu.elect.business.gebietsbaum.boundary.GebietDAO;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gebietsbaum.entity.GebietPK;
import de.ivu.elect.business.stimmeingabe.entity.ErgebniseingangErfasser;
import de.ivu.elect.business.stimmzettel.boundary.ErgebniseingangAusStimmzettelCreate;
import de.ivu.elect.business.stimmzettel.boundary.StimmzettelErfassung;
import de.ivu.elect.business.system.boundary.SystemLogWriter;
import de.ivu.elect.business.system.entity.SystemLogQuelle;
import de.ivu.elect.jee.faces.Messages;
import de.ivu.elect.presentation.gebietsbaum.GebietNummerFormatter;

@Stateless
public class StimmzettelImportErgebniseingangErzeugen implements Serializable {

  private static final long serialVersionUID = 1L;

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

  @Inject
  private transient GebietDAO gebietDAO;

  @Inject
  private transient StimmzettelErfassung stimmzettelErfassung;

  @Inject
  private transient ErgebniseingangAusStimmzettelCreate ergebniseingangAusStimmzettelCreate;

  @Inject
  private transient SystemLogWriter systemLogWriter;

  @Inject
  private transient Messages messages;

  @Inject
  private transient GebietNummerFormatter gebietNummerFormatter;

  public StimmzettelImportErgebniseingangErzeugen() {
    super();
  }

  @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
  public void erzeugeErgebniseingang(GebietPK gebietPK, ErgebniseingangErfasser erfasser, boolean eingangsherkunftIgnorieren, boolean anlegenWennBereitsEingangVorhanden) {
    if (gebietPK == null) {
      return;
    }

    Gebiet gebiet = gebietDAO.findByPrimaryKey(gebietPK);

    if (!gebiet.isErfassungsgebiet()) {
      return;
    }

    boolean angelegt = erzeugeErgebniseingangWennMoeglichUndStimmzettelVollstaendig(gebiet, erfasser, anlegenWennBereitsEingangVorhanden, () -> eingangsherkunftIgnorieren);

    if (angelegt) {
      if (anlegenWennBereitsEingangVorhanden) {
        systemLogWriter.writeInfoLogMessageFuerMandant(gebiet,
            messages.getMessageForMessageKey("stimmzettel.import.ergebniseinang.aktualisiert", gebietNummerFormatter.getDarstellung(gebiet), gebiet.getWahl().getName()),
            SystemLogQuelle.WAHLLOKALSYSTEM);
      } else {
        systemLogWriter.writeInfoLogMessageFuerMandant(gebiet,
            messages.getMessageForMessageKey("stimmzettel.import.ergebniseinang.erstellt", gebietNummerFormatter.getDarstellung(gebiet), gebiet.getWahl().getName()), SystemLogQuelle.WAHLLOKALSYSTEM);
      }
    }

    LOG.info("Ergebniseinang erstellt: " + gebiet + ", " + angelegt);
  }

  public boolean erzeugeErgebniseingangWennMoeglichUndStimmzettelVollstaendig(Gebiet gebiet, ErgebniseingangErfasser erfasser, boolean anlegenWennBereitsEingangVorhanden,
      BooleanSupplier eingangsherkunftIgnorieren) {
    if (!ergebniseingangAusStimmzettelCreate.isStimmeingabeMoeglich(gebiet, eingangsherkunftIgnorieren)) {
      LOG.warn("Stimmeingabe nicht möglich für Gebiet: " + gebiet);

      return false;
    }

    if (anlegenWennBereitsEingangVorhanden) {
      return ergebniseingangAusStimmzettelCreate.ergebniseingangAnlegenWennBereitsVorhanden(gebiet, erfasser, eingangsherkunftIgnorieren);
    } else if (stimmzettelErfassung.isErfassungAbgeschlossen(gebiet)) {
      Long anzahlNochZuErfassenderStimmzettel = stimmzettelErfassung.getAnzahlNochZuErfassenderStimmzettel(gebiet);

      LOG.info("Anzahl noch zu erfassender Stimmzettel für Gebiet: " + gebiet + ", " + anzahlNochZuErfassenderStimmzettel);

      if (anzahlNochZuErfassenderStimmzettel != null && anzahlNochZuErfassenderStimmzettel == 0) {
        LOG.info("Erstelle Ergebniseingang für Gebiet: " + gebiet);

        return ergebniseingangAusStimmzettelCreate.ergebniseingangAnlegen(gebiet, erfasser, eingangsherkunftIgnorieren);
      }
    }

    return false;
  }
}
