
package de.ivu.elect.business.datei.boundary;

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

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

import javax.annotation.Nonnull;
import javax.inject.Inject;

import de.ivu.elect.business.datei.entity.DateiExport;
import de.ivu.elect.business.exchange.entity.DateiExportArt;
import de.ivu.elect.business.mandant.entity.Mandant;
import de.ivu.elect.business.wahl.boundary.WahlterminExtendedDAO;
import de.ivu.elect.business.wahl.control.WahlExtendedAttacher;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.Wahltermin;

public class DateiExportSearch extends AbstractDateiExportSearch {

  @Inject
  private transient WahlExtendedAttacher wahlExtendedDAO;

  @Inject
  private transient WahlterminExtendedDAO wahlterminExtendedDAO;

  public DateiExportSearch() {
    super();
  }

  @Override
  protected List<DateiExport> querySearchResult(DateiExportSearchParameters searchParameters) {
    DateiExportArt dateiExportArt = searchParameters.getSelectedExportArt();

    if (dateiExportArt == null) {
      return emptyList();
    }

    // Sortierung nach Erstellungszeitpunkt bspw. für korrekte Anzeige in ELECTVAPP-1416 beibehalten!!!
    List<DateiExport> resultSortedByErstellungszeitpunktDesc;

    if (searchParameters.isSpecificPerWahl()) {
      resultSortedByErstellungszeitpunktDesc = getSearchResultSpecificPerWahlSortedByErstellungszeitpunktDesc(searchParameters, dateiExportArt);
    } else if (searchParameters.isSpecificPerWahltermin()) {
      resultSortedByErstellungszeitpunktDesc = getSearchResultSpecificPerWahlterminSortedByErstellungszeitpunktDesc(searchParameters, dateiExportArt);
    } else {
      Mandant mandant = searchParameters.getMandant();

      if (mandant == null) {
        return emptyList();
      }

      resultSortedByErstellungszeitpunktDesc = dao.findByDateiExportArtOrderBeiErstellungszeitpunktDesc(mandant, dateiExportArt);
    }

    for (DateiExport dateiExport : resultSortedByErstellungszeitpunktDesc) {
      dateiExport.getDatei().getDateiname(); // Eager-Loading für Arme...
    }

    Predicate< ? super DateiExport> searchResultPredicate = searchParameters.getSearchResultPredicate();

    if (searchResultPredicate != null) {
      return resultSortedByErstellungszeitpunktDesc.stream().filter(searchResultPredicate).collect(toList());
    }

    return resultSortedByErstellungszeitpunktDesc;
  }

  protected List<DateiExport> getSearchResultSpecificPerWahlSortedByErstellungszeitpunktDesc(DateiExportSearchParameters searchParameters, @Nonnull DateiExportArt dateiExportArt) {
    Wahl wahl = wahlExtendedDAO.attach(searchParameters.getSelectedWahlIfSpecificPerWahl());

    if (wahl == null) {
      return emptyList();
    }

    return dao.findByDateiExportArtAndWahlOrderBeiErstellungszeitpunktDesc(dateiExportArt, wahl, 1000000 /* willkürlich */);
  }

  protected List<DateiExport> getSearchResultSpecificPerWahlterminSortedByErstellungszeitpunktDesc(DateiExportSearchParameters searchParameters, @Nonnull DateiExportArt dateiExportArt) {
    Wahltermin wahltermin = wahlterminExtendedDAO.attach(searchParameters.getSelectedWahlterminIfSpecificPerWahltermin());

    if (wahltermin == null) {
      return emptyList();
    }

    return dao.findByDateiExportArtAndWahlterminOrderBeiErstellungszeitpunktDesc(dateiExportArt, wahltermin);
  }
}
