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

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

import javax.inject.Inject;

import de.ivu.elect.business.gebietsbaum.boundary.GebietExtendedDAO;
import de.ivu.elect.business.gebietsbaum.control.GebietByBreadthFirstComparator;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.wahlvorschlag.entity.Liste;
import de.ivu.elect.business.wahlvorschlag.entity.QListe;
import de.ivu.elect.jee.entity.QueryDsl;

public class ListeSearch extends AbstractListeSearch {

  @Inject
  private transient GebietExtendedDAO gebietDao;

  @Inject
  protected transient WahlvorschlagSearchResultSorter wahlvorschlagSearchResultSorter;

  public ListeSearch() {
    super();
  }

  @Override
  protected List<Liste> querySearchResult(ListeSearchParameters searchParameters) {
    QListe liste = QListe.liste;

    QueryDsl queryDsl = dao.getQueryDsl();
    queryDsl.from(liste);

    Gebiet gebiet = gebietDao.attach(searchParameters.getGebiet());

    if (!searchParameters.isListenUebergeordneterGebieteAnzeigen()) {
      queryDsl.eq(liste.gruppeImGebiet.gebiet, gebiet);
    }

    queryDsl.likeIfNotBlank(liste.kennwort, searchParameters.getKennwort());
    queryDsl.likeIfNotBlank(liste.kurzname, searchParameters.getKurzname());
    queryDsl.eqIfNotNull(liste.wahlvorschlagStatus, searchParameters.getWahlvorschlagStatus());

    List<Liste> result = queryDsl.list(liste);

    if (searchParameters.isListenUebergeordneterGebieteAnzeigen()) {
      result = filterGebietUndDrueber(result, gebiet);
    }

    if (searchParameters.getGruppe()!=null) {
      result = filterGruppe(searchParameters.getGruppe(), result);
    }

    wahlvorschlagSearchResultSorter.sort(gebiet, result);

    return result;
  }

  private List<Liste> filterGruppe(Gruppe gruppe, List<Liste> result) {
    return result.stream().filter(l->gruppe.equals(l.getGruppe())).collect(Collectors.toList());
  }

  private List<Liste> filterGebietUndDrueber(List<Liste> zufiltern, Gebiet gebiet) {
    return zufiltern.stream().filter(liste -> liste.getGebiet().isInGebietshierarchieUebergeordnetesGebietVon(gebiet))
        .collect(Collectors.toList());
  }
}
