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

import static java.util.Objects.nonNull;

import java.util.Collections;
import java.util.List;

import javax.inject.Inject;

import de.ivu.elect.business.person.entity.QPersonendaten;
import de.ivu.elect.business.veranstaltung.control.TeilnahmeComparatorFactory;
import de.ivu.elect.business.veranstaltung.entity.QTeilnahme;
import de.ivu.elect.business.veranstaltung.entity.Teilnahme;
import de.ivu.elect.business.veranstaltung.entity.Veranstaltung;
import de.ivu.elect.jee.entity.QueryDsl;

public class TeilnahmeSearch extends AbstractTeilnahmeSearch {

  @Inject
  private transient VeranstaltungExtendedDAO veranstaltungDao;

  @Inject
  private transient TeilnahmeComparatorFactory teilnahmeComparatorFactory;

  public TeilnahmeSearch() {
    super();
  }

  @Override
  protected List<Teilnahme> querySearchResult(TeilnahmeSearchParameters searchParameters) {
    QTeilnahme teilnahme = QTeilnahme.teilnahme;

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

    queryDsl.eq(teilnahme.veranstaltung, attach(searchParameters.getVeranstaltung()));

    queryDsl.eqIfNotNull(teilnahme.teilnehmerRolle, searchParameters.getTeilnehmerRolle());
    queryDsl.eqIfNotNull(teilnahme.teilnehmerStatus, searchParameters.getTeilnehmerStatus());

    QPersonendaten personendaten = teilnahme.personendaten;

    queryDsl.eqIfNotNull(teilnahme.personendaten.id, searchParameters.getPersonendaten().getId());

    if (nonNull(searchParameters.getPersonendatenArt())) {
      queryDsl.eqIfNotBlank(personendaten.discriminator, searchParameters.getPersonendatenArt().getTechnicalName());
    }

    queryDsl.likeNormalizedIfNotBlank(personendaten.familiennameNormalisiert, searchParameters.getTeilnehmerFamilienname());
    queryDsl.likeInAnyNormalizedIfNotBlank(personendaten.rufnameNormalisiert, personendaten.vornamenNormalisiert, searchParameters.getVornameSeparator(), searchParameters.getTeilnehmerVorname());
    queryDsl.joinFetch(teilnahme.personendaten);

    return sortiere(filterCustom(queryDsl.list(teilnahme), searchParameters));
  }

  protected List<Teilnahme> filterCustom(List<Teilnahme> list, TeilnahmeSearchParameters searchParameters) {
    return list;
  }

  protected List<Teilnahme> sortiere(List<Teilnahme> list) {
    Collections.sort(list, teilnahmeComparatorFactory.createTeilnahmeDefaultComparator());

    return list;
  }

  private Veranstaltung attach(Veranstaltung veranstaltung) {
    return veranstaltungDao.attach(veranstaltung);
  }
}
