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

import static java.util.stream.Collectors.toList;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;

import javax.inject.Inject;

import de.ivu.elect.business.datei.boundary.DateiExportSearchParameters;
import de.ivu.elect.business.datei.entity.DateiExport;
import de.ivu.elect.business.dokumente.control.ElectDokumentContext;
import de.ivu.elect.business.exchange.control.FileFormat;
import de.ivu.elect.business.gebietsbaum.boundary.GebietExtendedDAO;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.wahl.boundary.AbstractNlExportArtefaktNachSystemExportstatusBulkExporter;
import de.ivu.elect.business.wahl.boundary.NlExportArtefaktNachSystemExportstatus;
import de.ivu.elect.business.wahl.control.AbstractNlExportArtefaktNachSystemExportstatusExportContext;
import de.ivu.elect.business.wahl.control.NlExportArtefaktNachSystemExportstatusExportObject;
import de.ivu.elect.business.wahl.entity.AbstractWahlParameterLoader;
import de.ivu.elect.jee.presentation.redirect.Redirect;
import de.ivu.elect.presentation.dokumente.ElectDokumentContextGenerator;
import de.ivu.elect.presentation.exchange.AbstractExportSearchView;
import de.ivu.elect.presentation.wahl.menu.NlExportArtefaktNachSystemExportstatusSearchExportMenuItemEntry;

public abstract class AbstractNlExportArtefaktNachSystemExportstatusBulkExportView
    extends
      AbstractExportSearchView<NlExportArtefaktNachSystemExportstatusExportObject, AbstractNlExportArtefaktNachSystemExportstatusExportContext> {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient GebietExtendedDAO gebietExtendedDAO;

  @Inject
  private transient ElectDokumentContextGenerator electDokumentContextGenerator;

  @Inject
  private transient NlExportArtefaktNachSystemExportstatusSearchExportMenuItemEntry nlExportArtefaktNachSystemExportstatusSearchExportMenuItemEntry;

  private AbstractNlExportArtefaktNachSystemExportstatusExportContext context;

  protected AbstractNlExportArtefaktNachSystemExportstatusBulkExportView() {
    super();
  }

  public abstract void preRenderView();

  @Override
  public boolean isSupportedFileFormatsRendered() {
    return super.isSupportedFileFormatsRendered() && getSupportedFileFormats().size() != 1;
  }

  public String getPageTitle() {
    return getPageHeader();
  }

  public String getPageHeader() {
    String dateiExportName = getDateiExportName();

    String msgKey = dateiExportName + ".export.page.header"; // ELECT-10810

    if (!getMessages().isMessageKeyVorhanden(msgKey)) {
      msgKey = dateiExportName + ".export.label";

      if (!getMessages().isMessageKeyVorhanden(msgKey)) {
        msgKey = "entity.export.page.header";
      }
    }

    return getMessage(msgKey, getExportName());
  }

  public String getExportName() {
    return getMessage(getDateiExportName());
  }

  private String getDateiExportName() {
    return getExportDescription().getDateiExportName();
  }

  @Override
  public abstract AbstractNlExportArtefaktNachSystemExportstatusBulkExportDescription getExportDescription();

  @Override
  protected abstract AbstractNlExportArtefaktNachSystemExportstatusBulkExporter getExporter();

  @Override
  protected AbstractNlExportArtefaktNachSystemExportstatusExportContext getContext() {
    if (context == null) {
      context = createContext(electDokumentContextGenerator.createElectDokumentContext(), getWahlParameterLoader(), gebietExtendedDAO.findByWahl(getSelectedWahl()));
    }

    return context;
  }

  protected abstract AbstractNlExportArtefaktNachSystemExportstatusExportContext createContext(ElectDokumentContext electDokumentContext, AbstractWahlParameterLoader wahlParameterLoader,
      Collection<Gebiet> gebieteInWahl);

  protected void resetContext() {
    context = null;
    resetExportParameterModel(); // Wenn Context, dann auch DynaForm-Model...
  }

  @Override
  protected List<DateiExport> loadSearchResult(DateiExportSearchParameters dateiExportSearchParameters) {
    dateiExportSearchParameters.setSearchResultPredicate(getSearchResultPredicate(getSupportedFileFormats())); // ELECT-10277

    return super.loadSearchResult(dateiExportSearchParameters);
  }

  protected Predicate< ? super DateiExport> getSearchResultPredicate(List<FileFormat> fileFormatsSupported) {
    if (fileFormatsSupported.size() == 1) {
      FileFormat fileFormat = fileFormatsSupported.get(0);

      return dateiExport -> dateiExport != null && dateiExport.getDatei() != null && Objects.equals(dateiExport.getDatei().getFileFormat(), fileFormat);
    }

    return Objects::nonNull;
  }

  @Override
  @Redirect
  public String exportierenConfirmed() {
    getContext().resetBeforeExport(); // ELECT-11350

    preSelectFileFormat(getSupportedFileFormats());

    String outcome = super.exportierenConfirmed();

    resetContext(); // ELECT-12891

    return outcome;
  }

  @Override
  public boolean isNeedsDownload() {
    return super.isNeedsDownload() && !isNeedsRedirectToDownloads();
  }

  public boolean isNeedsRedirectToDownloads() {
    return getContext().getArtefakteInDateiExport().size() > 1;
  }

  public String getNeedsRedirectToDownloadsMessage() {
    List<String> artefaktFileNames = getContext().getArtefakteInDateiExport().stream() //
        .map(NlExportArtefaktNachSystemExportstatus::getOriginalDateiname) //
        .sorted() //
        .collect(toList());

    return getMessage("dokument.nach.system.exportstatus.export.redirect.message", artefaktFileNames.size(), String.join(", ", artefaktFileNames),
        String.join(System.lineSeparator(), artefaktFileNames));
  }

  @Redirect
  public String redirectToDownloads() {
    reset();

    return nlExportArtefaktNachSystemExportstatusSearchExportMenuItemEntry.getTargetViewId();
  }

  @Override
  protected void reset() {
    super.reset();

    resetContext();
  }
}
