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

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.enterprise.event.Event;
import javax.enterprise.inject.Specializes;
import javax.inject.Inject;

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

import de.ivu.elect.business.dokumente.boundary.DefaultDokumentVorlagenInit;
import de.ivu.elect.business.entschaedigung.boundary.CoreEntschaedigungsartCreator;
import de.ivu.elect.business.ergebnis.control.ErgebnisCreate;
import de.ivu.elect.business.ergebnis.entity.Ergebnisart;
import de.ivu.elect.business.gruppe.boundary.GruppeDAO;
import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.gruppe.entity.SystemGruppe;
import de.ivu.elect.business.gruppe.entity.SystemGruppeEigenschaften;
import de.ivu.elect.business.personenpruefung.control.PersonPruefungKonfigurationInit;
import de.ivu.elect.business.stimmeingabe.boundary.plausi.DefaultStimmeingabePlausiKonfigurationCreator;
import de.ivu.elect.business.wahl.boundary.WahlCreateDefaultDokumentVorlageInitEvent;
import de.ivu.elect.business.wahl.entity.Wahl;


import static java.util.Arrays.asList;

@Specializes
public class CoreWahlPostCreate extends WahlPostCreate {

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

  @Inject
  private transient WahlParameterCreator wahlParameterCreator;

  @Inject
  private transient ErgebnisCreate ergebnisCreate;

  @Inject
  private transient CoreEntschaedigungsartCreator entschaedigungsartCreator;

  @Inject
  private transient GruppeDAO gruppeDAO;

  @Inject
  private transient SystemGruppeEigenschaften systemGruppenEigenschaften;

  @Inject
  private transient DefaultStimmeingabePlausiKonfigurationCreator defaultStimmeingabePlausiKonfigurationCreator;

  @Inject
  private transient DefaultDokumentVorlagenInit defaultDokumentVorlagenInit;

  @Inject
  private transient DokumentPlatzhalterAnWahlOderWahlterminUebernehmen dokumentPlatzhalterAnWahlOderWahlterminUebernehmen;

  @Inject
  private transient Event<WahlCreateDefaultDokumentVorlageInitEvent> wahlCreatePostDefaultDokumentVorlageInitEventEvent;

  @Inject
  private transient PersonPruefungKonfigurationInit personPruefungKonfigurationInit;

  public CoreWahlPostCreate() {
    super();
  }

  @Override
  public void postCreate(Wahl wahl) {
    super.postCreate(wahl);

    LOG.info("Core-Wahl-Post Create: Wahlparameter");
    initDefaultWahlParameter(wahl);
    LOG.info("Core-Wahl-Post Create: Ergebnisse");
    initDefaultErgebnisse(wahl);
    LOG.info("Core-Wahl-Post Create: Entschädigungsarten");
    initDefaultEntschaedigungsarten(wahl);
    LOG.info("Core-Wahl-Post Create: Stimmeingabeplausis");
    initDefaultStimmeingabePlausiKonfigurationen(wahl);
    LOG.info("Core-Wahl-Post Create: Dokumentvorlagen");
    initDefaultDokumentVorlagen(wahl);
    LOG.info("Core-Wahl-Post Create: Dokumentplatzhalter übernehmen");
    dokumentPlatzhalterAnWahlOderWahlterminUebernehmen.uebernehmeDokumentplatzhalterDefaults(wahl);
    LOG.info("Core-Wahl-Post Create: PersonPruefungKonfiguration");
    personPruefungKonfigurationInit.init(wahl);
    LOG.info("Core-Wahl-Post Create - done");
  }

  private void initDefaultDokumentVorlagen(Wahl wahl) {
    LOG.info("initDefaultDokumentVorlagen: " + wahl + ", " + wahl.getWahlCreateDokumenteUebernehmen() + ", " + wahl.getWahlart().getDokumentvorlagen());
    if (wahl.getWahlCreateDokumenteUebernehmen().isAusWahlartUebernehmem() && wahl.getWahlart().getDokumentvorlagen().isVorlagenVorhanden()) {
      defaultDokumentVorlagenInit.initDefaultDokumentVorlagen(wahl, false /*egal bei Neuanlage der Wahl*/);
      wahlCreatePostDefaultDokumentVorlageInitEventEvent.fire(new WahlCreateDefaultDokumentVorlageInitEvent(wahl));
    } else {
      LOG.info("initDefaultDokumentVorlagen - keine Dokumentvorlagen anlegen");

    }
  }

  private void initDefaultWahlParameter(Wahl wahl) {
    wahlParameterCreator.initWahlParameters(wahl);
  }

  private void initDefaultErgebnisse(Wahl wahl) {
    for (Ergebnisart ergebnisart : getAnzulegendeErgebnisArten()) {
      ergebnisCreate.createIfNotExists(wahl, ergebnisart);
    }
  }

  protected List<Ergebnisart> getAnzulegendeErgebnisArten() {
    return Collections.emptyList();
  }

  private void initDefaultEntschaedigungsarten(Wahl wahl) {
    entschaedigungsartCreator.initDefaultEntschaedigungsarten(wahl);
  }

  private void initDefaultStimmeingabePlausiKonfigurationen(Wahl wahl) {
    defaultStimmeingabePlausiKonfigurationCreator.initDefaultStimmeingabePlausiKonfigurationen(wahl);
  }

  protected List<Ergebnisart> getAnzulegendeErgebnisArtenWus() {
    return Arrays.asList(Ergebnisart.ENDGUELTIG, Ergebnisart.VORPERIODE);
  }

  protected List<Ergebnisart> getAnzulegendeErgebnisArtenWas() {
    return asList(Ergebnisart.ENDGUELTIG, Ergebnisart.VORLAEUFIG, Ergebnisart.VORPERIODE, Ergebnisart.ZWISCHENERGEBNIS);
  }

  protected void createSystemGruppen(Wahl wahl) {
    long letzeRelativePosition = 0L;

    for (SystemGruppe systemGruppe : SystemGruppe.values()) {
      Gruppe gruppe = createGruppe(wahl, systemGruppe, letzeRelativePosition);
      gruppeDAO.persist(gruppe);
      letzeRelativePosition = gruppe.getRelativePosition();
    }
  }

  protected Gruppe createGruppe(Wahl wahl, SystemGruppe systemGruppe, long letzeRelativePosition) {
    Gruppe gruppeAusSystemGruppe = systemGruppenEigenschaften.createGruppeAusSystemGruppe(systemGruppe, wahl);

    if (gruppeAusSystemGruppe.getRelativePosition() == null && gruppeAusSystemGruppe.getSchluessel() != null) {
      try {
        gruppeAusSystemGruppe.setRelativePosition(Long.parseLong(gruppeAusSystemGruppe.getSchluessel()));
      } catch (NumberFormatException nfe) {
        // ignorieren
      }
    }
    if (gruppeAusSystemGruppe.getRelativePosition() == null) {
      gruppeAusSystemGruppe.setRelativePosition(letzeRelativePosition + 1);
    }

    return gruppeAusSystemGruppe;
  }
}
