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

import static java.util.Objects.isNull;

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

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.wahl.boundary.WahlExtendedDAO;
import de.ivu.elect.business.wahlausschuss.control.WahlausschussmitgliedDefaultComparator;
import de.ivu.elect.business.wahlausschuss.entity.QWahlausschussmitglied;
import de.ivu.elect.business.wahlausschuss.entity.Wahlausschussmitglied;
import de.ivu.elect.business.wahlausschuss.entity.WahlausschussmitgliedVerterterFilterKriterium;
import de.ivu.elect.jee.entity.QueryDsl;

public class WahlausschussmitgliedSearch extends AbstractWahlausschussmitgliedSearch {

  @Inject
  private transient WahlExtendedDAO wahlDao;

  @Inject
  private transient GebietExtendedDAO gebietDao;

  public WahlausschussmitgliedSearch() {
    super();
  }

  @Override
  protected List<Wahlausschussmitglied> querySearchResult(WahlausschussmitgliedSearchParameters searchParameters) {
    QWahlausschussmitglied wahlausschussmitgliedTabelle = QWahlausschussmitglied.wahlausschussmitglied;

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

    queryDsl.eq(wahlausschussmitgliedTabelle.wahl, wahlDao.attach(searchParameters.getSelectedWahl()));
    queryDsl.eqIfNotNull(wahlausschussmitgliedTabelle.wahlausschussrolle, searchParameters.getWahlausschussrolle());

    List<Wahlausschussmitglied> result = queryDsl.list(wahlausschussmitgliedTabelle);

    result = filterByGebiet(searchParameters, result);
    result = filterByVertretung(searchParameters, result);

    result = sort(result);

    return result;
  }

  private List<Wahlausschussmitglied> filterByGebiet(WahlausschussmitgliedSearchParameters searchParameters, List<Wahlausschussmitglied> result) {
    Gebiet gebietSelected = gebietDao.attach(searchParameters.getGebiet());

    if (isNull(gebietSelected)) {
      return result;
    }

    List<Wahlausschussmitglied> resultFiltered = new ArrayList<>();

    for (Wahlausschussmitglied wahlausschussmitglied : result) {
      Gebiet gebiet = wahlausschussmitglied.getGebiet();

      if (gebiet.equals(gebietSelected) || gebiet.isUntergebietVon(gebietSelected)) {
        resultFiltered.add(wahlausschussmitglied);
      }
    }

    return resultFiltered;
  }

  private List<Wahlausschussmitglied> filterByVertretung(WahlausschussmitgliedSearchParameters searchParameters, List<Wahlausschussmitglied> result) {
    WahlausschussmitgliedVerterterFilterKriterium wahlausschussmitgliedVerterterFilterKriterium = searchParameters.getVerterterFilterKriterium();

    if (isNull(wahlausschussmitgliedVerterterFilterKriterium)) {
      return result;
    }

    List<Wahlausschussmitglied> resultFiltered = new ArrayList<>();

    for (Wahlausschussmitglied wahlausschussmitglied : result) {
      if (wahlausschussmitgliedVerterterFilterKriterium.matches(wahlausschussmitglied)) {
        resultFiltered.add(wahlausschussmitglied);
      }
    }

    return resultFiltered;
  }

  private List<Wahlausschussmitglied> sort(List<Wahlausschussmitglied> result) {
    Collections.sort(result, new WahlausschussmitgliedDefaultComparator());

    return result;
  }
}
