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

import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;

import javax.annotation.Nullable;
import javax.enterprise.event.Observes;
import javax.enterprise.event.Reception;

import de.ivu.elect.business.veranstaltung.entity.*;
import de.ivu.elect.presentation.veranstaltung.form.AbstractSchulungArtProperty;
import de.ivu.elect.presentation.veranstaltung.form.VeranstaltungSearchParametersSchulungsArtProperty;
import org.apache.deltaspike.core.api.scope.ConversationGroup;
import org.apache.deltaspike.core.api.scope.GroupedConversationScoped;

import de.ivu.elect.business.gebietsbaum.boundary.GebietSelectChangeEvent;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.person.boundary.SearchParametersMitPersonendatenNamen;
import de.ivu.elect.business.person.entity.Personendaten;
import de.ivu.elect.business.person.entity.PersonendatenProperties;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.Wahltermin;
import de.ivu.elect.jee.entity.customdata.EmptyCustomData;
import de.ivu.elect.jee.presentation.dynamicform.Property;

@GroupedConversationScoped
@ConversationGroup(AbstractVeranstaltungSearchParameters.class)
public class VeranstaltungSearchParameters extends AbstractVeranstaltungSearchParameters implements SearchParametersMitPersonendatenNamen {

  private static final long serialVersionUID = 1L;

  private VeranstaltungSearchMode veranstaltungSearchMode;

  private Gebiet gebiet;

  private Wahl wahl;

  private Wahltermin wahltermin;

  private Veranstaltung veranstaltung;

  private Personendaten personendaten;

  public VeranstaltungSearchParameters() {
    super();

    this.veranstaltungSearchMode = VeranstaltungSearchMode.INITIALIZED;
  }

  public boolean isSearchByDefault() {
    return veranstaltungSearchMode.isSearchByDefault();
  }

  public void setSearchMode(VeranstaltungSearchMode veranstaltungSearchMode) {
    this.veranstaltungSearchMode = veranstaltungSearchMode;
  }

  public Gebiet getGebiet() {
    return gebiet;
  }

  public boolean hasVorgegebenePersonendaten() {
    return nonNull(getPersonendaten().getId());
  }

  public Personendaten getVorgegebenePersonendaten() {
    return getPersonendaten();
  }

  public void setVorgegebenePersonendaten(Personendaten personendaten) {
    getPersonendaten().setId(personendaten.getId());
    getPersonendaten().setRufname(personendaten.getRufname());
    getPersonendaten().setFamilienname(personendaten.getFamilienname());
  }

  public void resetVorgegebenePersonendaten() {
    personendaten = null;
  }

  @Override
  public String getFamilienname() {
    return getPersonendaten().getFamilienname();
  }

  @Override
  public void setFamilienname(String familienname) {
    getPersonendaten().setFamilienname(familienname);
  }

  @Override
  public Property getFamiliennameProperty() {
    Property property = getPersonendatenProperties().getFamiliennameProperty();
    property.setRequired(false);

    return property;
  }

  @Override
  public String getVorname() {
    return getPersonendaten().getRufname();
  }

  @Override
  public void setVorname(String vorname) {
    getPersonendaten().setRufname(vorname);
  }

  @Override
  public Property getVornameProperty() {
    Property property = getPersonendatenProperties().getRufnameProperty();
    property.setRequired(false);
    property.setLabel(getMessage(SearchParametersMitPersonendatenNamen.MESSAGE_KEY_VORNAME_EINZAHL));

    return property;
  }

  private PersonendatenProperties getPersonendatenProperties() {
    return getPersonendaten().getProperties();
  }

  private Personendaten getPersonendaten() {
    if (isNull(personendaten)) {
      personendaten = new Personendaten(EmptyCustomData.INSTANCE);
    }

    return personendaten;
  }

  public void setGebiet(Gebiet gebiet) {
    if (gebiet != null) {
      setWahltermin(gebiet.getWahltermin());
      setWahl(gebiet.getWahl());
    }

    this.gebiet = gebiet;
  }

  public Wahl getWahl() {
    return wahl;
  }

  public void setWahl(Wahl wahl) {
    this.wahl = wahl;

    if (wahl != null) {
      this.wahltermin = wahl.getWahltermin();
    }
  }

  public Wahltermin getWahltermin() {
    return wahltermin;
  }

  public void setWahltermin(Wahltermin wahltermin) {
    this.wahltermin = wahltermin;
  }

  private VeranstaltungProperties getVeranstaltungProperties() {
    return getVeranstaltung().getProperties();
  }

  private Veranstaltung getVeranstaltung() {
    if (veranstaltung == null) {
      veranstaltung = new Veranstaltung(EmptyCustomData.INSTANCE);
      veranstaltung.setVeranstaltungArt(null);
      veranstaltung.setSchulungArt(null);
      veranstaltung.setVeranstaltungStatus(null);
    }

    return veranstaltung;
  }

  public String getBezeichnung() {
    return getVeranstaltung().getBezeichnung();
  }

  public Property getBezeichnungProperty() {
    Property property = getVeranstaltungProperties().getBezeichnungProperty();
    property.setRequired(false);

    return property;
  }

  public VeranstaltungArt getVeranstaltungArt() {
    return getVeranstaltung().getVeranstaltungArt();
  }

  public Property getVeranstaltungArtProperty() {
    Property property = getVeranstaltungProperties().getVeranstaltungArtMitLeererAuswahlProperty();
    property.setRequired(false);

    return property;
  }

  public SchulungArt getSchulungArt() {
    return getVeranstaltung().getSchulungArt();
  }

  public void setSchulungArt(SchulungArt schulungArt) {
    getVeranstaltung().setSchulungArt(schulungArt);
  }

  public Property getSchulungArtProperty() {
    return new VeranstaltungSearchParametersSchulungsArtProperty(this);
  }

  @Nullable
  public String getBemerkung() {
    return getVeranstaltung().getBemerkung();
  }

  public Property getBemerkungProperty() {
    Property property = getVeranstaltungProperties().getBemerkungProperty();
    property.setRequired(false);

    return property;
  }

  public VeranstaltungStatus getVeranstaltungStatus() {
    return getVeranstaltung().getVeranstaltungStatus();
  }

  public Property getVeranstaltungStatusProperty() {
    Property property = getVeranstaltungProperties().getVeranstaltungStatusMitLeererAuswahlProperty();
    property.setRequired(false);

    return property;
  }

  @Override
  public void onGebietSelectChangeEvent(@Observes(notifyObserver = Reception.IF_EXISTS) GebietSelectChangeEvent event) {
    super.onGebietSelectChangeEvent(event);

    setGebiet(event.getNeueEntity());
  }

  @Override
  public void reset() {
    super.reset();

    gebiet = null;
    wahl = null;
    wahltermin = null;
    veranstaltung = null;

    resetVorgegebenePersonendaten();
  }
}
