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

import static org.apache.commons.lang3.StringUtils.isNotBlank;

import java.util.ArrayList;
import java.util.List;

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

import de.ivu.elect.business.gebietsbaum.boundary.GebietExtendedDAO;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.veranstaltung.entity.QVeranstaltung;
import de.ivu.elect.business.veranstaltung.entity.Teilnahme;
import de.ivu.elect.business.veranstaltung.entity.Veranstaltung;
import de.ivu.elect.business.wahl.boundary.WahlExtendedDAO;
import de.ivu.elect.business.wahl.boundary.WahlterminExtendedDAO;
import de.ivu.elect.jee.entity.EagerLoadingCollector;
import de.ivu.elect.jee.entity.QueryDsl;

public class VeranstaltungSearch extends AbstractVeranstaltungSearch {

  @Inject
  private transient WahlExtendedDAO wahlExtendedDAO;

  @Inject
  private transient WahlterminExtendedDAO wahlterminExtendedDAO;

  @Inject
  private transient GebietExtendedDAO gebietExtendedDAO;

  @Inject
  private transient TeilnahmeSearch teilnahmeSearch;

  public VeranstaltungSearch() {
    super();
  }

  @Override
  protected List<Veranstaltung> querySearchResult(VeranstaltungSearchParameters searchParameters) {
    QueryDsl qdsl = dao.getQueryDsl();

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

    QVeranstaltung veranstaltungTabelle = QVeranstaltung.veranstaltung;
    qdsl.from(veranstaltungTabelle);
    qdsl.eq(veranstaltungTabelle.wahltermin, wahlterminExtendedDAO.attach(searchParameters.getWahltermin()));
    qdsl.eqIfNotNull(veranstaltungTabelle.wahl, wahlExtendedDAO.attach(searchParameters.getWahl()));

    qdsl.likeIfNotBlank(veranstaltungTabelle.bezeichnung, searchParameters.getBezeichnung());
    qdsl.likeIfNotBlank(veranstaltungTabelle.bemerkung, searchParameters.getBemerkung());
    qdsl.eqIfNotNull(veranstaltungTabelle.veranstaltungArt, searchParameters.getVeranstaltungArt());
    qdsl.eqIfNotNull(veranstaltungTabelle.schulungArt, searchParameters.getSchulungArt());
    qdsl.eqIfNotNull(veranstaltungTabelle.veranstaltungStatus, searchParameters.getVeranstaltungStatus());

    qdsl.orderBy(veranstaltungTabelle.beginn.asc());

    List<Veranstaltung> result = new ArrayList<>();

    for (Veranstaltung veranstaltung : qdsl.list(veranstaltungTabelle)) {
      Gebiet gebietMitglied = veranstaltung.getGebiet();

      if (gebietMitglied.equals(gebiet) || gebietMitglied.isUntergebietVon(gebiet)) {
        result.add(veranstaltung);
      }
    }

    return filterTeilnehmer(result, searchParameters);
  }

  private List<Veranstaltung> filterTeilnehmer(List<Veranstaltung> veranstaltungen, VeranstaltungSearchParameters searchParameters) {
    List<Veranstaltung> result = new ArrayList<>();

    if (searchParameters.hasVorgegebenePersonendaten() || isNotBlank(searchParameters.getVorname()) || isNotBlank(searchParameters.getFamilienname())) {
      for (Veranstaltung veranstaltung : veranstaltungen) {
        TeilnahmeSearchParameters teilnahmeSearchParameters = createTeilnahmeSearchParameters();
        teilnahmeSearchParameters.setVeranstaltung(veranstaltung);
        teilnahmeSearchParameters.setVorgegebenePersonendaten(searchParameters.getVorgegebenePersonendaten());

        if (!teilnahmeSearch.getSearchResult(teilnahmeSearchParameters, EagerLoadingCollector.<Teilnahme> create()).isEmpty()) {
          result.add(veranstaltung);
        }
      }

    } else {
      result = veranstaltungen;
    }
    return result;
  }

  @Nonnull
  protected TeilnahmeSearchParameters createTeilnahmeSearchParameters() {
    return new TeilnahmeSearchParameters();
  }
}
