
package de.ivu.elect.presentation.stimmeingabe;

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

import javax.inject.Inject;
import javax.inject.Named;

import org.apache.deltaspike.core.api.scope.ConversationGroup;
import org.apache.deltaspike.core.api.scope.GroupedConversationScoped;

import de.ivu.elect.business.dokumente.boundary.AbstractDokumentGenerator;
import de.ivu.elect.business.ergebnis.control.ErgebnisExchangeContext;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.stimmeingabe.boundary.StimmeingabeDocumentByErgebniseingangDokumentGenerator;
import de.ivu.elect.business.stimmeingabe.control.StimmeingabeDocumentByErgebniseingangExportContext;
import de.ivu.elect.business.stimmeingabe.control.WasStimmeingabeDocumentByErgebniseingangExportObject;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingang;
import de.ivu.elect.business.stimmeingabe.entity.ErgebniseingangGruppierung;
import de.ivu.elect.business.wahl.boundary.WahldurchfuehrungSessionSelect;
import de.ivu.elect.business.wahl.entity.Wahldurchfuehrung;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.dynamicform.LambdaEnumProperty;
import de.ivu.elect.jee.presentation.dynamicform.ReadOnlyLongProperty;
import de.ivu.elect.jee.presentation.redirect.Redirect;
import de.ivu.elect.presentation.View;
import de.ivu.elect.presentation.dokumente.AbstractDokumentErzeugenView;
import de.ivu.elect.presentation.dokumente.ElectDokumentContextGenerator;

@GroupedConversationScoped
@ConversationGroup(ErgebniseingangDokumentErzeugenView.class)
@Named(ErgebniseingangDokumentErzeugenView.COMPONENT_NAME)
@View(viewId = ErgebniseingangDokumentErzeugenView.VIEW_ID, useCase = UseCasePermission.DOKUMENT_ERZEUGEN_NIEDERSCHRIFT)
public class ErgebniseingangDokumentErzeugenView
    extends
      AbstractDokumentErzeugenView</* List<WasStimmeingabeDocumentByErgebniseingangExportObject> Import von java.util.List führt zu WELD Bug (!!) */Object, StimmeingabeDocumentByErgebniseingangExportContext> {

  private static final long serialVersionUID = 1L;

  public static final String COMPONENT_NAME = "ergebniseingangDokumentErzeugenView";

  public static final String VIEW_ID = "/stimmeingabe/ergebniseingang-dokument-erzeugen-view.xhtml";

  @Inject
  private transient WahldurchfuehrungSessionSelect wahldurchfuehrungSessionSelect;

  @Inject
  private transient ElectDokumentContextGenerator electDokumentContextGenerator;

  @Inject
  private transient StimmeingabeDocumentByErgebniseingangDokumentGenerator stimmeingabeDocumentByErgebniseingangDokumentGenerator;


  private ErgebniseingangGruppierung ergebniseingangGruppierung =ErgebniseingangGruppierung.OHNE;

  public ErgebniseingangDokumentErzeugenView() {
    super();
  }

  @Override
  public String getViewId() {
    return VIEW_ID;
  }

  @Override
  protected UseCasePermission getRequiredPermission() {
    return UseCasePermission.DOKUMENT_ERZEUGEN_NIEDERSCHRIFT;
  }

  @Redirect
  public String initErgebniseingang(Ergebniseingang ergebniseingang) {
    return initErgebniseingaenge(Collections.singletonList(ergebniseingang));
  }

  @Redirect
  public String initErgebniseingaenge(List<Ergebniseingang> ergebniseingaenge) {
    List<WasStimmeingabeDocumentByErgebniseingangExportObject> exportObjects =
        ergebniseingaenge.stream().map(WasStimmeingabeDocumentByErgebniseingangExportObject::new).collect(Collectors.toList());

    exportObjects.forEach(exportObject -> exportObject.getErgebniseingaenge().forEach(Ergebniseingang::getPk));

    return super.init((List) exportObjects); // Generics Quatsch
  }

  @Override
  protected AbstractDokumentGenerator<Object, StimmeingabeDocumentByErgebniseingangExportContext> getDokumentGenerator() {
    return (AbstractDokumentGenerator) stimmeingabeDocumentByErgebniseingangDokumentGenerator;
  }

  @Override
  protected void addDokumentParameterProperties(FormBuilder formBuilder) {
    // Add nothing...
    List<Object> entities = getEntities();
    if (entities != null) {
      formBuilder.addProperty(new ReadOnlyLongProperty(getMessage("ergebniseingang.dokument.anzahl.ergebniseingaenge"), ( long) entities.size()));
    }

    formBuilder.addProperty(new LambdaEnumProperty<>(getMessage("ergebniseingang.dokument.gruppierung"), true, this::setErgebniseingangGruppierung,
        this::getErgebniseingangGruppierung,
        ErgebniseingangGruppierung.class, Arrays.asList(ErgebniseingangGruppierung.values()) ));

  }

  @Override
  protected StimmeingabeDocumentByErgebniseingangExportContext getContext() {
    Wahldurchfuehrung wahldurchfuehrung = wahldurchfuehrungSessionSelect.getEntity();
    boolean sectionsNurEinzelnesWahldurchfuehrungsgebietExcluded = false; // ELECT-9443, Abschnitte "Zähliste elektronisch", "Stimmzettel per Beschluss", etc. sind nur bei der Generierung für EIN einzelnes Gebiet relevant, cf. WesNiederschriftErzeugen#createContext!

    StimmeingabeDocumentByErgebniseingangExportContext stimmeingabeDocumentByErgebniseingangExportContext = new StimmeingabeDocumentByErgebniseingangExportContext(
        electDokumentContextGenerator.createElectDokumentContext(),
        new ErgebnisExchangeContext(wahldurchfuehrung, getSelectedGebiet(), ErgebnisExchangeContext.KANDIDATUR_FORMAT_DARSTELLUNG_NOT_CONFIGURED),
        wahldurchfuehrung.getErgebniseingangsart(),
        getSelectedDokumentVorlage(), false, sectionsNurEinzelnesWahldurchfuehrungsgebietExcluded, sectionsNurEinzelnesWahldurchfuehrungsgebietExcluded, false);


    stimmeingabeDocumentByErgebniseingangExportContext.put(ErgebniseingangGruppierung.class.getName(), getErgebniseingangGruppierung());
    return stimmeingabeDocumentByErgebniseingangExportContext;
  }

  public ErgebniseingangGruppierung getErgebniseingangGruppierung() {
    return ergebniseingangGruppierung;
  }

  public void setErgebniseingangGruppierung(ErgebniseingangGruppierung ergebniseingangGruppierung) {
    this.ergebniseingangGruppierung = ergebniseingangGruppierung;
  }


  @Override
  protected void resetDokumentParameterModel() {
    super.resetDokumentParameterModel();
    this.ergebniseingangGruppierung = ErgebniseingangGruppierung.OHNE;
  }
}
