
package de.ivu.elect.presentation.stimmeingabe.exchange;

import java.util.List;

import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Named;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;

import de.ivu.elect.business.dokumente.entity.DokumentVorlage;
import de.ivu.elect.business.dokumente.entity.DokumentVorlageArt;
import de.ivu.elect.business.ergebnis.boundary.ErgebnisExtendedDAO;
import de.ivu.elect.business.ergebnis.control.ErgebnisExchangeContext;
import de.ivu.elect.business.ergebnis.entity.Ergebnis;
import de.ivu.elect.business.ergebnis.entity.Ergebnisart;
import de.ivu.elect.business.exchange.control.AbstractExporter;
import de.ivu.elect.business.gebietsbaum.boundary.GebietExtendedDAO;
import de.ivu.elect.business.gebietsbaum.control.EntityMitWurzelgebietDAO;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.stimmeingabe.boundary.StimmeingabeDocumentByErgebnisDatenExporter;
import de.ivu.elect.business.stimmeingabe.control.StimmeingabeDocumentByErgebnisDatenExportContext;
import de.ivu.elect.business.stimmeingabe.control.StimmeingabeDocumentByErgebnisDatenExportObject;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.presentation.View;
import de.ivu.elect.presentation.ergebnis.ErgebnisStatusInfo;
import de.ivu.elect.presentation.ergebnis.ViewHavingErgebnisStatusInfo;
import de.ivu.elect.presentation.exchange.AbstractDokumentExportSearchView;
import de.ivu.elect.presentation.hilfe.OnlineHilfeId;

@OnlineHilfeId(value = "277", mehrfachVergebenOk = true)
@Named(StimmeingabeDocumentByErgebnisDatenExportView.COMPONENT_NAME)
@View(viewId = StimmeingabeDocumentByErgebnisDatenExportView.VIEW_ID, useCase = UseCasePermission.DOKUMENT_ERZEUGEN_NIEDERSCHRIFT)
public class StimmeingabeDocumentByErgebnisDatenExportView extends AbstractDokumentExportSearchView<StimmeingabeDocumentByErgebnisDatenExportObject, StimmeingabeDocumentByErgebnisDatenExportContext>
    implements
      ViewHavingErgebnisStatusInfo {

  private static final long serialVersionUID = 1L;

  public static final String COMPONENT_NAME = "stimmeingabeDocumentByErgebnisDatenExportView";

  public static final String VIEW_ID = "/stimmeingabe/stimmeingabe-document-by-ergebnis-daten-export.xhtml";

  @Inject
  private transient GebietExtendedDAO gebietDao;

  @Inject
  private transient ErgebnisExtendedDAO ergebnisDao;

  @Inject
  private transient StimmeingabeDocumentByErgebnisDatenExportDescription exportDescription;

  @Inject
  private transient StimmeingabeDocumentByErgebnisDatenExporter exporter;

  private boolean eingabenExcluded = true;

  public StimmeingabeDocumentByErgebnisDatenExportView() {
    super();
  }

  public String getPageTitle() {
    return getMessage("stimmeingabe.document.export.page.title");
  }

  public String getPageHeader() {
    return getMessage("stimmeingabe.document.export.by.ergebnis.daten.page.header", getSelectedGebietNameFormatted());
  }

  @Override
  public DokumentVorlageArt getDokumentVorlageArt() {
    return getExportDescription().getDokumentVorlageArt();
  }

  @Override
  protected boolean isDokumentVorlageRequired() {
    return true;
  }

  @Override
  public StimmeingabeDocumentByErgebnisDatenExportDescription getExportDescription() {
    return exportDescription;
  }

  @Override
  protected AbstractExporter<StimmeingabeDocumentByErgebnisDatenExportObject, StimmeingabeDocumentByErgebnisDatenExportContext> getExporter() {
    return exporter;
  }

  public UploadedFile getUploadedFile() {
    return null;
  }

  @Override
  protected StimmeingabeDocumentByErgebnisDatenExportContext getContext() {
    Wahl wahl = null;

    if (isWahlSelected()) {
      wahl = getSelectedWahl();
    }

    boolean sectionsNurEinzelnesWahldurchfuehrungsgebietExcluded = true; // ELECT-9443, Abschnitte "Zähliste elektronisch", "Stimmzettel per Beschluss", etc. sind nur bei der Generierung für EIN einzelnes Gebiet relevant, cf. ErgebniseingangDokumentErzeugenView#getContext, WesNiederschriftErzeugen#createContext!

    return createContext(new ErgebnisExchangeContext(wahl, getSelectedGebiet(), ErgebnisExchangeContext.KANDIDATUR_FORMAT_DARSTELLUNG_NOT_CONFIGURED), getSelectedErgebnisart(), getDokumentVorlage(),
        false, sectionsNurEinzelnesWahldurchfuehrungsgebietExcluded, sectionsNurEinzelnesWahldurchfuehrungsgebietExcluded, isEingabenExcluded());
  }

  public StimmeingabeDocumentByErgebnisDatenExportContext createContext(ErgebnisExchangeContext ergebnisExchangeContext, Ergebnisart ergebnisart, DokumentVorlage dokumentVorlage,
      boolean documentFuerWahlgebietRequired, boolean sectionErfassteStimmzettelExcluded, boolean sectionZaehllisteElektronischExcluded, boolean eingabenExcluded) {
    Ergebnis ergebnis = getErgebnis(ergebnisExchangeContext.getWahl(), ergebnisart);

    Gebiet wurzelgebiet = null;

    if (ergebnis != null) {
      wurzelgebiet = ergebnis.getWahl().getWurzelgebiet(EntityMitWurzelgebietDAO.fromDao(gebietDao));
    }

    return new StimmeingabeDocumentByErgebnisDatenExportContext(createElectDokumentContext(), ergebnisExchangeContext, ergebnis, wurzelgebiet, dokumentVorlage, documentFuerWahlgebietRequired,
        sectionErfassteStimmzettelExcluded, sectionZaehllisteElektronischExcluded, eingabenExcluded);
  }

  protected boolean isEingabenExcluded() {
    return eingabenExcluded;
  }

  protected void setEingabenExcluded(Boolean eingabenExcluded) {
    this.eingabenExcluded = Boolean.TRUE.equals(eingabenExcluded);
  }

  protected Ergebnisart getSelectedErgebnisart() {
    // NOTE, dass ENDGUELTIG gesetzt sein muss, um im WUS ein Ergebnis zu finden, cf. WasStimmeingabeDocumentByErgebnisDatenExportView#getSelectedErgebnisart!
    return Ergebnisart.ENDGUELTIG;
  }

  @Override
  public ErgebnisStatusInfo getErgebnisStatusInfo() {
    return ErgebnisStatusInfo.EMPTY; // To be overridden!
  }

  @Nullable
  private Ergebnis getErgebnis(Wahl wahl, Ergebnisart ergebnisart) {
    if (wahl != null) {
      List<Ergebnis> ergebnisse = ergebnisDao.findByWahlAndErgebnisart(wahl, ergebnisart);

      if (ergebnisse.isEmpty()) {
        return null;
      }

      return ergebnisse.get(0);
    }

    return null;
  }

  public Boolean isUploadMoeglich() {
    return false;
  }

  public void handleFileUpload(FileUploadEvent event) {
  }

  public String getAllowedTypes() {
    return "";
  }

  public String getAllowedTypeNames() {
    return "";
  }
}
