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

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

import javax.faces.validator.Validator;
import javax.inject.Inject;

import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.gruppe.entity.GruppeArt;
import de.ivu.elect.business.gruppe.entity.GruppeProperties;
import de.ivu.elect.business.gruppe.entity.PolitischeGruppe;
import de.ivu.elect.business.gruppe.entity.PolitischeGruppeProperties;
import de.ivu.elect.business.gruppe.entity.ReferendumVorlageConstants;
import de.ivu.elect.business.kandidatur.entity.WaehlerBenannteKandidaturen;
import de.ivu.elect.business.wahlvorschlag.entity.WahlvorschlagConstants;
import de.ivu.elect.jee.presentation.dynamicform.AbstractStringProperty;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.dynamicform.PropertyType;
import de.ivu.elect.presentation.ViewFormBuilder;

public class GruppeViewFormBuilder extends ViewFormBuilder {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient UniqueGruppeSchluesselFacesValidator uniqueGruppeSchluesselValidator;

  public GruppeViewFormBuilder() {
    super();
  }

  public void addProperties(FormBuilder formBuilder, Gruppe gruppe, boolean propertiesAufGebietenReadonly, boolean globalReadonly) {
    boolean propertiesBearbeitbarNurInitialReadonly = globalReadonly || gruppe.isPersistent();
    boolean propertiesBearbeitbarNachErfassungReadonly = globalReadonly;
    boolean propertiesBearbeitbarNachErfassungOderAufGebietenReadonly = globalReadonly || propertiesAufGebietenReadonly;

    addGruppeSchluesselProperty(formBuilder, gruppe, globalReadonly);

    for (Validator validator : getGruppeSchluesselValidator()) {
      formBuilder.withValidatorAndPk(validator, gruppe.getPk());
    }

    GruppeProperties gruppeProperties = gruppe.getProperties();

    boolean gruppeArtWechselbar = !globalReadonly && (!gruppe.isPersistent() || propertiesBearbeitbarNurInitialReadonly && gruppe.getGruppeArt().isPolitischeGruppierungKeinEinzelkandidat());

    formBuilder.addProperty(gruppeProperties.getGruppeArtProperty()).setValues(getGruppeArtOptions()).withReadonly(!gruppeArtWechselbar);

    addNamenProperty(formBuilder, gruppe, gruppeProperties.getNameProperty(), gruppeProperties.getKurznameProperty(), gruppeProperties.getZusatzbezeichnungProperty(),
        propertiesBearbeitbarNachErfassungOderAufGebietenReadonly);

    // ELECT-2633
    if (!gruppe.isReferendumVorlage()) {
      formBuilder.addProperty(gruppeProperties.getVorgegebenePositionProperty()).withReadonly(propertiesBearbeitbarNachErfassungOderAufGebietenReadonly);

      formBuilder.addProperty(gruppeProperties.getFarbeProperty()) //
          .withType(PropertyType.INPUT_COLOR) //
          .withReadonly(propertiesBearbeitbarNachErfassungReadonly) //
          .required(); // ELECTSL-34

      if (gruppe.isPolitischeGruppe()) {
        formBuilder.addProperty(gruppeProperties.getInPraesentationProperty()).withReadonly(propertiesBearbeitbarNachErfassungReadonly);
        formBuilder.addProperty(gruppeProperties.getPrivilegiertProperty()).withReadonly(propertiesBearbeitbarNachErfassungReadonly);

        if (!gruppe.isPersistent() || gruppe.isPartei()) {
          PolitischeGruppeProperties politischeGruppeProperties = gruppe.castTo(PolitischeGruppe.class).getEntity().getProperties();

          formBuilder.addProperty(politischeGruppeProperties.getMinderheitProperty()).withReadonly(propertiesBearbeitbarNachErfassungReadonly);
        }
      }
    }
  }

  protected void addGruppeSchluesselProperty(FormBuilder formBuilder, Gruppe gruppe, boolean globalReadonly) {
    formBuilder.addProperty(gruppe.getProperties().getSchluesselProperty()).withReadonly(globalReadonly || isGruppeSchluesselReadonly(gruppe));
  }

  protected boolean isGruppeSchluesselReadonly(Gruppe gruppe) {
    return gruppe.isSystemGruppe() || WaehlerBenannteKandidaturen.isWaehlerBenannteListeGruppe(gruppe);
  }

  protected void addNamenProperty(FormBuilder formBuilder, Gruppe gruppe, AbstractStringProperty nameProperty, AbstractStringProperty kurznameProperty,
      AbstractStringProperty zusatzbezeichnungProperty, boolean readonly) {
    formBuilder.addProperty(nameProperty).withReadonly(readonly);

    // Cf. ELECT-352
    if (gruppe.isEinzelbewerber()) {
      formBuilder.withLabel(getMessage(WahlvorschlagConstants.MESSAGE_KEY_KENNWORT_EINZAHL));
    } else if (gruppe.isReferendumVorlage()) {
      formBuilder.withLabel(getMessage(ReferendumVorlageConstants.MESSAGE_KEY_NAME_EINZAHL));
      formBuilder.withType(PropertyType.INPUT_TEXTAREA);
    }

    formBuilder.addProperty(kurznameProperty).withReadonly(readonly);
    if (isAddZusatzbezeichnungProperty()) {
      formBuilder.addProperty(zusatzbezeichnungProperty).withReadonly(readonly);
    }
  }

  protected boolean isAddZusatzbezeichnungProperty() {
    return true;
  }

  protected List<GruppeArt> getGruppeArtOptions() {
    // NOTE, dass andere GruppeArten NUR IMPLIZIT angelegt werden, bspw. Einzelbewerber beim Anlegen einer Einzelkandidatur!
    return new ArrayList<>(GruppeArt.GRUPPE_ARTEN_POLITISCHE_GRUPPIERUNG_KEIN_EINZELKANDIDAT);
  }

  // ELECT-1460
  protected List<Validator> getGruppeSchluesselValidator() {
    return Collections.singletonList(uniqueGruppeSchluesselValidator);
  }
}
