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

import static java.util.Arrays.asList;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

import javax.annotation.Nullable;
import javax.inject.Inject;

import org.apache.deltaspike.core.api.scope.ConversationGroup;
import org.apache.deltaspike.core.api.scope.GroupedConversationScoped;

import de.ivu.elect.business.gebietsbaum.boundary.SearchParametersMitGebiet;
import de.ivu.elect.business.gebietsbaum.boundary.WahldurchfuehrungsgebietSessionSelect;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gebietsbaum.entity.GebietsartConstants;
import de.ivu.elect.business.mandant.entity.Mandant;
import de.ivu.elect.business.niederschrift.entity.Niederschrift;
import de.ivu.elect.business.niederschrift.entity.NiederschriftArt;
import de.ivu.elect.business.niederschrift.entity.NiederschriftConstants;
import de.ivu.elect.business.niederschrift.entity.NiederschriftStatus;
import de.ivu.elect.business.niederschrift.entity.NiederschriftStatusAenderung;
import de.ivu.elect.business.niederschrift.entity.NiederschriftStatusAenderungProperties;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiGebietsart;
import de.ivu.elect.jee.presentation.dynamicform.AbstractSelectManyProperty;
import de.ivu.elect.jee.presentation.dynamicform.AbstractTimestampProperty;
import de.ivu.elect.jee.presentation.dynamicform.LambdaEnumProperty;
import de.ivu.elect.jee.presentation.dynamicform.LambdaEnumSelectManyProperty;
import de.ivu.elect.jee.presentation.dynamicform.Property;

@GroupedConversationScoped
@ConversationGroup(AbstractNiederschriftSearchParameters.class)
public class NiederschriftSearchParameters extends AbstractNiederschriftSearchParameters implements SearchParametersMitGebiet {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient WahldurchfuehrungsgebietSessionSelect wahldurchfuehrungsgebietSessionSelect;

  private Mandant mandant;

  private Gebiet gebiet;

  private boolean includeUntergebiete;

  private Collection<NiederschriftArt> niederschriftArten;

  private transient Property niederschriftArtenProperty;

  private StimmeingabePlausiGebietsart niederschriftWahldurchfuehrungsgebietGebietsart;

  private transient Property niederschriftWahldurchfuehrungsgebietGebietsartProperty;

  private NiederschriftStatusAenderung neuesteNiederschriftStatusAenderungMin;

  private Collection<NiederschriftStatus> neuesteNiederschriftStatusAenderungMinStatus;

  private transient Property neuesteNiederschriftStatusAenderungMinStatusProperty;

  private NiederschriftStatusAenderung neuesteNiederschriftStatusAenderungMax;

  public NiederschriftSearchParameters() {
    super();

    this.niederschriftArten = new ArrayList<>();

    this.neuesteNiederschriftStatusAenderungMinStatus = new ArrayList<>();
  }

  public Mandant getMandant() {
    return mandant;
  }

  public void setMandant(Mandant mandant) {
    this.mandant = mandant;
  }

  @Nullable
  @Override
  public Gebiet getGebiet() {
    if (gebiet == null) {
      gebiet = wahldurchfuehrungsgebietSessionSelect.getEntity();
    }

    return gebiet;
  }

  @Override
  public void setGebiet(Gebiet gebiet) {
    this.gebiet = gebiet;
  }

  @Override
  public boolean isIncludeUntergebiete() {
    return includeUntergebiete;
  }

  @Override
  public void setIncludeUntergebiete(boolean includeUntergebiete) {
    this.includeUntergebiete = includeUntergebiete;
  }

  @Override
  public IncludeUntergebieteProperty getIncludeUntergebieteProperty() {
    return new IncludeUntergebieteProperty(this);
  }

  public Collection<NiederschriftArt> getNiederschriftArten() {
    return niederschriftArten;
  }

  public void setNiederschriftArten(Collection<NiederschriftArt> niederschriftArten) {
    this.niederschriftArten = niederschriftArten;
  }

  public Property getNiederschriftArtenProperty() {
    if (niederschriftArtenProperty == null) {
      niederschriftArtenProperty = new LambdaEnumSelectManyProperty<>(AbstractSelectManyProperty.CHECKBOX_MENU, getMessage(NiederschriftConstants.MESSAGE_KEY_NIEDERSCHRIFT_ART_EINZAHL), false,
          this::setNiederschriftArten, this::getNiederschriftArten, NiederschriftArt.class, asList(NiederschriftArt.values()));
    }

    return niederschriftArtenProperty;
  }

  public StimmeingabePlausiGebietsart getNiederschriftWahldurchfuehrungsgebietGebietsart() {
    return niederschriftWahldurchfuehrungsgebietGebietsart;
  }

  public void setNiederschriftWahldurchfuehrungsgebietGebietsart(StimmeingabePlausiGebietsart gebietsart) {
    this.niederschriftWahldurchfuehrungsgebietGebietsart = gebietsart;
  }

  public Property getNiederschriftWahldurchfuehrungsgebietGebietsartProperty() {
    if (niederschriftWahldurchfuehrungsgebietGebietsartProperty == null) {
      niederschriftWahldurchfuehrungsgebietGebietsartProperty = new LambdaEnumProperty<>(getMessage(GebietsartConstants.MESSAGE_KEY_ENTITY_EINZAHL), false,
          this::setNiederschriftWahldurchfuehrungsgebietGebietsart, this::getNiederschriftWahldurchfuehrungsgebietGebietsart, StimmeingabePlausiGebietsart.class,
          asList(StimmeingabePlausiGebietsart.URNENWAHLBEZIRK, StimmeingabePlausiGebietsart.BRIEFWAHLBEZIRK), true);
    }

    return niederschriftWahldurchfuehrungsgebietGebietsartProperty;
  }

  public Collection<NiederschriftStatus> getNeuesteNiederschriftStatusAenderungStatus() {
    return neuesteNiederschriftStatusAenderungMinStatus;
  }

  public void setNeuesteNiederschriftStatusAenderungStatus(Collection<NiederschriftStatus> status) {
    this.neuesteNiederschriftStatusAenderungMinStatus = status;
  }

  public Property getNeuesteNiederschriftStatusAenderungStatusProperty() {
    if (neuesteNiederschriftStatusAenderungMinStatusProperty == null) {
      neuesteNiederschriftStatusAenderungMinStatusProperty = new LambdaEnumSelectManyProperty<>(AbstractSelectManyProperty.CHECKBOX_MENU,
          getMessage("niederschrift.search.table.neuester.status.column"), false, this::setNeuesteNiederschriftStatusAenderungStatus, this::getNeuesteNiederschriftStatusAenderungStatus,
          NiederschriftStatus.class, asList(NiederschriftStatus.values()));
    }

    return neuesteNiederschriftStatusAenderungMinStatusProperty;
  }

  public String getNeuesteNiederschriftStatusAenderungRaum() {
    return getNeuesteNiederschriftStatusAenderungMin().getRaum();
  }

  public void setNeuesteNiederschriftStatusAenderungRaum(String raum) {
    getNeuesteNiederschriftStatusAenderungMin().setRaum(raum);
  }

  public Property getNeuesteNiederschriftStatusAenderungRaumProperty() {
    Property property = getNiederschriftStatusAenderungMinProperties().getRaumProperty();
    property.setLabel(getMessage("niederschrift.search.table.neuester.raum.column"));
    property.setRequired(false);

    return property;
  }

  public String getNeuesteNiederschriftStatusAenderungBesitzer() {
    return getNeuesteNiederschriftStatusAenderungMin().getBesitzer();
  }

  public void setNeuesteNiederschriftStatusAenderungBesitzer(String besitzer) {
    getNeuesteNiederschriftStatusAenderungMin().setBesitzer(besitzer);
  }

  public Property getNeuesteNiederschriftStatusAenderungBesitzerProperty() {
    Property property = getNiederschriftStatusAenderungMinProperties().getBesitzerProperty();
    property.setLabel(getMessage("niederschrift.search.table.neuester.besitzer.column"));
    property.setRequired(false);

    return property;
  }

  public Date getNeuesteNiederschriftStatusAenderungZeitstempelMin() {
    return getNeuesteNiederschriftStatusAenderungMin().getZeitstempel();
  }

  public void setNeuesteNiederschriftStatusAenderungZeitstempelMin(Date date) {
    getNeuesteNiederschriftStatusAenderungMin().setZeitstempel(date);
  }

  public AbstractTimestampProperty getNeuesteNiederschriftStatusAenderungZeitstempelMinProperty() {
    AbstractTimestampProperty property = getNiederschriftStatusAenderungMinProperties().getZeitstempelProperty();
    property.setLabel(getMessage("niederschrift.search.letzte.aenderung.min"));
    property.setRequired(false);

    return property;
  }

  public Date getNeuesteNiederschriftStatusAenderungZeitstempelMax() {
    return getNiederschriftStatusAenderungMax().getZeitstempel();
  }

  public void setNeuesteNiederschriftStatusAenderungZeitstempelMax(Date date) {
    getNiederschriftStatusAenderungMax().setZeitstempel(date);
  }

  public AbstractTimestampProperty getNeuesteNiederschriftStatusAenderungZeitstempelMaxProperty() {
    AbstractTimestampProperty property = getNiederschriftStatusAenderungMaxProperties().getZeitstempelProperty();
    property.setLabel(getMessage("niederschrift.search.letzte.aenderung.max"));
    property.setRequired(false);

    return property;
  }

  private NiederschriftStatusAenderungProperties getNiederschriftStatusAenderungMinProperties() {
    return getNeuesteNiederschriftStatusAenderungMin().getProperties();
  }

  private NiederschriftStatusAenderung getNeuesteNiederschriftStatusAenderungMin() {
    if (neuesteNiederschriftStatusAenderungMin == null) {
      neuesteNiederschriftStatusAenderungMin = createNiederschiftStatusAenderung();
    }

    return neuesteNiederschriftStatusAenderungMin;
  }

  private NiederschriftStatusAenderungProperties getNiederschriftStatusAenderungMaxProperties() {
    return getNiederschriftStatusAenderungMax().getProperties();
  }

  private NiederschriftStatusAenderung getNiederschriftStatusAenderungMax() {
    if (neuesteNiederschriftStatusAenderungMax == null) {
      neuesteNiederschriftStatusAenderungMax = createNiederschiftStatusAenderung();
    }

    return neuesteNiederschriftStatusAenderungMax;
  }

  private NiederschriftStatusAenderung createNiederschiftStatusAenderung() {
    Niederschrift niederschrift = new Niederschrift();
    niederschrift.setNiederschriftArt(null);

    NiederschriftStatusAenderung niederschriftStatusAenderung = new NiederschriftStatusAenderung();
    niederschriftStatusAenderung.setZeitstempel(null);
    niederschriftStatusAenderung.setStatus(null);
    niederschriftStatusAenderung.setNiederschriftOhneUpdateBeziehung(niederschrift);

    return niederschriftStatusAenderung;
  }

  @Override
  public void reset() {
    mandant = null;

    gebiet = null;
    includeUntergebiete = false;

    niederschriftArten = new ArrayList<>();
    niederschriftWahldurchfuehrungsgebietGebietsart = null;

    neuesteNiederschriftStatusAenderungMinStatus = new ArrayList<>();

    neuesteNiederschriftStatusAenderungMin = null;
    neuesteNiederschriftStatusAenderungMax = null;

    super.reset();
  }
}
