
package de.ivu.elect.presentation.wahlvorschlagsperson.form;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;

import javax.inject.Inject;

import de.ivu.elect.business.anschrift.entity.Anschrift;
import de.ivu.elect.business.person.entity.Personendaten;
import de.ivu.elect.business.personenpruefung.control.wahlrecht.WahlvorschlagsPersonWahlrechtMatcher;
import de.ivu.elect.business.wahlvorschlagsperson.entity.WahlvorschlagsPerson;
import de.ivu.elect.business.wahlvorschlagsperson.entity.WahlvorschlagsPersonProperties;
import de.ivu.elect.business.wahlvorschlagsperson.entity.WahlvorschlagsPersonTyp;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.dynamicform.Property;
import de.ivu.elect.presentation.anschrift.form.AnschriftViewFormBuilder;
import de.ivu.elect.presentation.person.form.CommonPersonendatenViewFormBuilder;
import de.ivu.elect.presentation.person.form.PersonendatenPersonStatusNichtGeeignetBemerkungProperty;
import de.ivu.elect.presentation.personenregister.form.AbstractPersonenregisterPropertiesViewFormBuilder;

public class WahlvorschlagsPersonViewFormBuilder extends AbstractPersonenregisterPropertiesViewFormBuilder {

  private static final long serialVersionUID = 1L;

  @Inject
  protected transient WahlvorschlagsPersonWahlrechtMatcher wahlvorschlagsPersonWahlrechtMatcher;

  @Inject
  protected transient CommonPersonendatenViewFormBuilder personendatenViewFormBuilder;

  @Inject
  protected transient AnschriftViewFormBuilder anschriftViewFormBuilder;

  public WahlvorschlagsPersonViewFormBuilder() {
    super();
  }

  public void addWahlvorschlagsPersonProperties(FormBuilder formBuilder, WahlvorschlagsPerson wahlvorschlagsPerson, List<WahlvorschlagsPersonTyp> wahlvorschlagsPersonTypen,
      boolean propertiesReadonly) {
    WahlvorschlagsPersonProperties wahlvorschlagsPersonProperties = wahlvorschlagsPerson.getProperties();

    if (wahlvorschlagsPersonTypen.size() > 1) {
      formBuilder.addProperty(wahlvorschlagsPersonProperties.getWahlvorschlagsPersonTypProperty()) //
          .setValues(wahlvorschlagsPersonTypen) //
          .withReadonly(propertiesReadonly);
    }

    // Cf. UnterstuetzerViewFormBuilder#addReadonlyViewContextParametersProperties
    if (isDatumUnterschriftRelevant(wahlvorschlagsPerson)) {
      boolean datumUnterschriftReadonly = wahlvorschlagsPerson.isPersistent() || propertiesReadonly;

      formBuilder.addProperty(wahlvorschlagsPersonProperties.getDatumUnterschriftProperty()) //
          .withRequired(!datumUnterschriftReadonly) //
          .withReadonly(datumUnterschriftReadonly);
    }

    if (wahlvorschlagsPerson.isPersistent()) {
      formBuilder.addProperty(wahlvorschlagsPersonProperties.getEingangssequenznummerProperty()) //
          .withReadonly(propertiesReadonly);
    }
  }

  private boolean isDatumUnterschriftRelevant(WahlvorschlagsPerson wahlvorschlagsPerson) {
    return wahlvorschlagsPersonWahlrechtMatcher.isTagDerUnterschriftRelevant(wahlvorschlagsPerson);
  }

  public void addWahlvorschlagsPersonPersonendatenProperties(FormBuilder formBuilder, WahlvorschlagsPerson wahlvorschlagsPerson, boolean propertiesReadonly) {
    boolean ordnungsmerkmalPropertyAndWahlrechtsausschlussPropertyReadonly = propertiesReadonly || isPersonenregisterAbgeglichenAndNotPersonenregisterAbgleichUeberschreibbar(wahlvorschlagsPerson);

    WahlvorschlagsPersonProperties wahlvorschlagsPersonProperties = wahlvorschlagsPerson.getProperties();

    formBuilder.addProperty(wahlvorschlagsPersonProperties.getExternesOrdnungsmerkmalProperty()).withReadonly(ordnungsmerkmalPropertyAndWahlrechtsausschlussPropertyReadonly);

    formBuilder.addProperty(wahlvorschlagsPersonProperties.getTitelProperty()).withReadonly(propertiesReadonly);

    personendatenViewFormBuilder.addBasicPersonendatenProperties(formBuilder, wahlvorschlagsPerson, propertiesReadonly);
    personendatenViewFormBuilder.addStaatsangehoerigkeitProperties(formBuilder, wahlvorschlagsPerson, propertiesReadonly);

    formBuilder.addProperty(wahlvorschlagsPersonProperties.getWahlrechtsausschlussProperty()).withReadonly(ordnungsmerkmalPropertyAndWahlrechtsausschlussPropertyReadonly);

    if (wahlvorschlagsPerson.isPersistent()) {
      formBuilder.addProperty(wahlvorschlagsPersonProperties.getPersonStatusProperty()).readonly();

      if (wahlvorschlagsPerson.isUnterstuetzer()) {
        formBuilder.addProperty(new PersonendatenPersonStatusNichtGeeignetBemerkungProperty<>(wahlvorschlagsPerson));
      }
    }

    personendatenViewFormBuilder.addZuzugsdatenProperties(formBuilder, wahlvorschlagsPerson, propertiesReadonly);

    setWahlvorschlagsPersonPersonendatenPropertiesRequired(formBuilder, wahlvorschlagsPerson);
  }

  protected FormBuilder setWahlvorschlagsPersonPersonendatenPropertiesRequired(FormBuilder formBuilder, WahlvorschlagsPerson wahlvorschlagsPerson) {
    return setPropertiesRequired(formBuilder, getWahlvorschlagsPersonPersonendatenPropertiesRequired(wahlvorschlagsPerson));
  }

  public Set<Class< ? extends Property>> getWahlvorschlagsPersonPersonendatenPropertiesRequired(WahlvorschlagsPerson wahlvorschlagsPerson) {
    return personendatenViewFormBuilder.getBasicPersonendatenPropertiesRequired(wahlvorschlagsPerson); // ELECTKOM-1455, Geburtsdatum KEIN Pflichtfeld...
  }

  public void addWahlvorschlagsPersonAnschriftProperties(FormBuilder formBuilder, WahlvorschlagsPerson wahlvorschlagsPerson, Anschrift anschrift, boolean propertiesReadonly) {
    anschriftViewFormBuilder.addPersonendatenAnschriftProperties(formBuilder, wahlvorschlagsPerson, anschrift, propertiesReadonly);

    setWahlvorschlagsPersonAnschriftPropertiesRequired(formBuilder, wahlvorschlagsPerson, anschrift);
  }

  protected FormBuilder setWahlvorschlagsPersonAnschriftPropertiesRequired(FormBuilder formBuilder, WahlvorschlagsPerson wahlvorschlagsPerson, Anschrift anschrift) {
    return setPropertiesRequired(formBuilder, getWahlvorschlagsPersonAnschriftPropertiesRequired(wahlvorschlagsPerson, anschrift));
  }

  public Set<Class< ? extends Property>> getWahlvorschlagsPersonAnschriftPropertiesRequired(WahlvorschlagsPerson wahlvorschlagsPerson, Anschrift anschrift) {
    return anschriftViewFormBuilder.getPersonendatenAnschriftPropertiesRequired(wahlvorschlagsPerson, anschrift);
  }

  public void addWahlvorschlagsPersonErreichbarkeitsdatenProperties(FormBuilder formBuilder, WahlvorschlagsPerson wahlvorschlagsPerson, boolean propertiesReadonly) {
    personendatenViewFormBuilder.addDefaultErreichbarkeitsdatenProperties(formBuilder, wahlvorschlagsPerson, propertiesReadonly);

    setWahlvorschlagsPersonErreichbarkeitsdatenPropertiesRequired(formBuilder, wahlvorschlagsPerson);
  }

  protected FormBuilder setWahlvorschlagsPersonErreichbarkeitsdatenPropertiesRequired(FormBuilder formBuilder, WahlvorschlagsPerson wahlvorschlagsPerson) {
    return setPropertiesRequired(formBuilder, getWahlvorschlagsPersonErreichbarkeitsdatenPropertiesRequired(wahlvorschlagsPerson));
  }

  public Set<Class< ? extends Property>> getWahlvorschlagsPersonErreichbarkeitsdatenPropertiesRequired(WahlvorschlagsPerson wahlvorschlagsPersonn) {
    return personendatenViewFormBuilder.getDefaultErreichbarkeitsdatenPropertiesRequired(wahlvorschlagsPersonn);
  }

  @Override
  public Collection<Class< ? extends Property>> getPersonenregisterPropertiesUebernommen(Personendaten personendaten) {
    Collection<Class< ? extends Property>> result = new ArrayList<>();

    // Cf. WahlvorschlagsPersonPersonenregisterPersonendatenMapper.
    result.addAll(personendatenViewFormBuilder.getDefaultPersonenregisterPropertiesUebernommen(personendaten));
    result.addAll(anschriftViewFormBuilder.getDefaultPersonenregisterPropertiesUebernommen(personendaten));

    return result;
  }
}
