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

import static org.apache.commons.lang3.StringUtils.isNotBlank;

import java.util.Collection;
import java.util.HashSet;

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

import de.ivu.elect.business.ergebnis.entity.Gewaehlt;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gruppe.entity.GruppeConstants;
import de.ivu.elect.business.gruppe.entity.PolitischeGruppe;
import de.ivu.elect.business.kandidatur.entity.Direktkandidatur;
import de.ivu.elect.business.kandidatur.entity.Kandidatur;
import de.ivu.elect.business.kandidatur.entity.KandidaturProperties;
import de.ivu.elect.business.kandidatur.entity.Listenkandidatur;
import de.ivu.elect.business.kandidatur.entity.WaehlerBenannteKandidaturen;
import de.ivu.elect.business.person.entity.Personendaten;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahlvorschlag.entity.Direktkandidat;
import de.ivu.elect.business.wahlvorschlag.entity.Liste;
import de.ivu.elect.business.wahlvorschlag.entity.WahlvorschlagConstants;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.dynamicform.Property;
import de.ivu.elect.presentation.personenregister.form.AbstractPersonenregisterPropertiesViewFormBuilder;
import de.ivu.elect.presentation.wahlvorschlag.form.WahlvorschlagViewFormBuilder;

public class WaehlerBenannteKandidaturViewFormBuilder extends AbstractPersonenregisterPropertiesViewFormBuilder {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient WahlvorschlagViewFormBuilder wahlvorschlagViewFormBuilder;

  @Inject
  private transient KandidaturViewFormBuilder kandidaturViewFormBuilder;

  @Inject
  private transient EinzelbewerberKandidaturViewFormBuilder einzelbewerberKandidaturViewFormBuilder;

  @Inject
  private transient ListenkandidaturViewFormBuilder listenkandidaturViewFormBuilder;

  public WaehlerBenannteKandidaturViewFormBuilder() {
    super();
  }

  public String getEntityEinzahlMessage(@Nullable Gebiet gebiet) {
    return getMessage(WaehlerBenannteKandidaturen.MSG_KEY_WAEHLER_BENANNTE_KANDIDATUR_EINZAHL);
  }

  public void addProperties(FormBuilder formBuilder, Direktkandidatur direktkandidatur, boolean readonly) {
    PolitischeGruppe politischeGruppe = direktkandidatur.getGruppe();

    if (isNotBlank(politischeGruppe.getSchluessel())) {
      formBuilder.addSeparator(GruppeConstants.MESSAGE_KEY_ENTITY_EINZAHL);
      formBuilder.addProperty(politischeGruppe.getProperties().getSchluesselProperty()).readonly();
    }

    Direktkandidat direktkandidat = direktkandidatur.getDirektkandidat();

    formBuilder.addSeparator(WahlvorschlagConstants.MESSAGE_KEY_ENTITY_EINZAHL);
    wahlvorschlagViewFormBuilder.addNamenProperties(formBuilder, direktkandidat, null, isWahlvorschlagKennwortRequired());

    einzelbewerberKandidaturViewFormBuilder.addEinzelkandidaturProperties(formBuilder, direktkandidatur, readonly);
    einzelbewerberKandidaturViewFormBuilder.addEinzelkandidaturGewaehltVorperiodeProperties(formBuilder, direktkandidatur, direktkandidatur.getGewaehltVorperiode(), readonly);

    updateProperties(formBuilder, direktkandidatur, readonly);
  }

  public void addProperties(FormBuilder formBuilder, Listenkandidatur listenkandidatur, boolean readonly) {
    listenkandidaturViewFormBuilder.addKandidaturProperties(formBuilder, listenkandidatur, readonly);
    listenkandidaturViewFormBuilder.addGewaehltVorperiodeProperties(formBuilder, listenkandidatur, listenkandidatur.getGewaehltVorperiode(), readonly);

    updateProperties(formBuilder, listenkandidatur, readonly);
  }

  protected boolean isWahlvorschlagKennwortRequired() {
    return false; // ELECT-14262, optional, da ggf. automatisch ergänzt -> cf. WaehlerBenannterWahlvorschlagBoundaryCreate#saveWaehlerBenannterDirektkandidat!
  }

  private void updateProperties(FormBuilder formBuilder, Kandidatur kandidatur, boolean readonly) {
    KandidaturProperties kandidaturProperties = kandidatur.getProperties();

    Collection<Property> listenkandidaturPropertiesOptional = new HashSet<>();

    // Wähler neigen vermutlich nicht dazu, das Geburtsdatum ihres Wunschkandidaten aufzuschreiben...
    listenkandidaturPropertiesOptional.add(kandidaturProperties.getGeburtsdatumProperty());

    // ELECTDD-536
    listenkandidaturPropertiesOptional.add(kandidaturProperties.getVornamenProperty());
    listenkandidaturPropertiesOptional.add(kandidaturProperties.getRufnameProperty());

    for (Property property : listenkandidaturPropertiesOptional) {
      if (formBuilder.containsProperty(property)) {
        formBuilder.selectProperty(property).optional();
      }
    }
  }

  public Gewaehlt createGewaehltVorperiode(Wahl wahl) {
    return kandidaturViewFormBuilder.createGewaehltVorperiode(wahl);
  }

  @Override
  public Collection<Class< ? extends Property>> getPersonenregisterPropertiesUebernommen(Personendaten personendaten) {
    return kandidaturViewFormBuilder.getPersonenregisterPropertiesUebernommen(personendaten);
  }

  public void preSaveEntity(Direktkandidatur direktkandidatur) {
    einzelbewerberKandidaturViewFormBuilder.preSaveEntity(direktkandidatur);
  }

  public void preSaveEntity(Listenkandidatur listenkandidatur) {
    listenkandidaturViewFormBuilder.preSaveEntity(listenkandidatur);
  }

  public boolean isWaehlerBenannteDirektkandidatur(Direktkandidatur direktkandidatur) {
    return WaehlerBenannteKandidaturen.isWaehlerBenannteDirektkandidatur(direktkandidatur);
  }

  public boolean isWaehlerBenannteListe(Liste liste) {
    return WaehlerBenannteKandidaturen.isWaehlerBenannteListe(liste);
  }

  public boolean isWaehlerBenannteListenkandidatur(Listenkandidatur listenkandidatur) {
    return WaehlerBenannteKandidaturen.isWaehlerBenannteListenkandidatur(listenkandidatur);
  }

  public boolean isWaehlerBenannteListenkandidaturSonstige(Kandidatur kandidatur) {
    return WaehlerBenannteKandidaturen.isWaehlerBenannteListenkandidaturSonstige(getMessages(), kandidatur);
  }
}
