
package de.ivu.elect.presentation.wahlvorschlag.table;

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

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

import de.ivu.elect.business.WusFeaturesAktiviert;
import de.ivu.elect.business.gebietsbaum.boundary.GebietSessionSelect;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.kandidatur.boundary.EinzelbewerberKandidaturKonfiguration;
import de.ivu.elect.business.stimmzettel.boundary.EntityAufStimmzettelDatenExtendedDAOFactory;
import de.ivu.elect.business.stimmzettel.entity.EntityAufStimmzettelDaten;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahlvorschlag.entity.Liste;
import de.ivu.elect.jee.presentation.dynamictable.AbstractColumnBuilder;
import de.ivu.elect.jee.presentation.dynamictable.ColumnEntry;
import de.ivu.elect.presentation.wahl.CurrentWahlZulassungspruefungExtended;

/**
 * Wegen Vererbung @Named JBoss 7 / Wildfly
 */
public class BasisListeColumnBuilder extends AbstractColumnBuilder<Liste> {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient GebietSessionSelect gebietSelect;

  @Inject
  private transient EntityAufStimmzettelDatenExtendedDAOFactory entityAufStimmzettelDatenExtendedDAOFactory;

  @Inject
  private transient CurrentWahlZulassungspruefungExtended currentWahlZulassungspruefung;

  @Inject
  private transient EinzelbewerberKandidaturKonfiguration einzelbewerberKandidaturKonfiguration;

  @Inject
  private transient WusFeaturesAktiviert wusFeaturesAktiviert;

  protected AbstractWahlvorschlagColumn<Liste> listeStimmzettelPositionColumn;

  protected AbstractWahlvorschlagColumn<Liste> listeIsEinzelbewerberColumn;

  protected AbstractWahlvorschlagColumn<Liste> listeWahlvorschlagStatusColumn;

  protected AbstractWahlvorschlagColumn<Liste> listeGruppeKurznameColumn;

  protected AbstractWahlvorschlagColumn<Liste> listeKurznameColumn;

  protected AbstractWahlvorschlagColumn<Liste> listeKennwortColumn;

  protected AbstractWahlvorschlagColumn<Liste> listeAnzahlNennungenGesamtColumn;

  protected AbstractWahlvorschlagColumn<Liste> listeListenverbindungColumn;

  protected AbstractWahlvorschlagColumn<Liste> listeAnzahlenListenkandidaturPerKandidaturStatusColumn;

  protected AbstractWahlvorschlagColumn<Liste> listeNichtzulassungsgruendeColumn;

  private EntityAufStimmzettelDaten entityAufStimmzettelDaten;

  public BasisListeColumnBuilder() {
    super();
  }

  @Override
  public void initColumns() {
    listeStimmzettelPositionColumn = new WahlvorschlagStimmzettelPositionColumn<>(getMessages(), getIcons(), getSelectedGebiet(), getEntityAufStimmzettelDaten());

    listeIsEinzelbewerberColumn = new WahlvorschlagIsEinzelbewerberColumn<>(getMessages());

    listeWahlvorschlagStatusColumn = new WahlvorschlagStatusMitIconColumn<>(getMessages(), getIcons(), getEntityAufStimmzettelDaten(), getCurrentWahlZulassungspruefung());

    listeGruppeKurznameColumn = new WahlvorschlagGruppeKurznameColumn<>(getMessages());

    listeKennwortColumn = AbstractWahlvorschlagColumn.createWahlvorschlagKennwortColumn(getMessages());
    listeKurznameColumn = new WahlvorschlagKurznameColumn<>(AbstractWahlvorschlagColumn.createWahlvorschlagKurznameColumn(getMessages()));

    listeAnzahlenListenkandidaturPerKandidaturStatusColumn = new ListeAnzahlenListenkandidaturPerKandidaturStatusColumn(getMessages(), getUserLocale(), getCurrentWahlZulassungspruefung());

    listeAnzahlNennungenGesamtColumn = new ListeAnzahlNennungenGesamtColumn(getMessages(), getUserLocale());

    listeListenverbindungColumn = new ListeListenverbindungColumn(getMessages());

    listeNichtzulassungsgruendeColumn = new WahlvorschlagNichtzulassungsgruendeColumn<>(getMessages(), getEntityAufStimmzettelDaten(), getCurrentWahlZulassungspruefung());
  }

  @Override
  public List<ColumnEntry< ? super Liste>> getColumnEntriesSorted() {
    List<ColumnEntry< ? super Liste>> result = new ArrayList<>();

    result.add(listeStimmzettelPositionColumn);

    if (isEinzelbewerberErfassbar()) {
      result.add(listeIsEinzelbewerberColumn);
    }

    result.add(listeWahlvorschlagStatusColumn);

    result.add(listeGruppeKurznameColumn);

    result.add(listeKennwortColumn);
    result.add(listeKurznameColumn);

    result.add(listeAnzahlenListenkandidaturPerKandidaturStatusColumn); // ELECT-9146

    if (isWahlMitMehrfachnennungen()) { // ELECT-15217
      addListeNennungenColumnEntries(result);
    }

    if (isWahlMitListenverbindungen()) {
      addListeListenverbindungColumnEntries(result);
    }

    addColumnEntriesZulassungspruefung(result);

    return result;
  }

  protected void addListeNennungenColumnEntries(List<ColumnEntry< ? super Liste>> result) {
    result.add(listeAnzahlNennungenGesamtColumn);
  }

  protected void addListeListenverbindungColumnEntries(List<ColumnEntry< ? super Liste>> result) {
    result.add(listeListenverbindungColumn);
  }

  protected void addColumnEntriesZulassungspruefung(List<ColumnEntry< ? super Liste>> result) {
    if (wusFeaturesAktiviert.isWusOderWusWasZusammen() /*ELECT-12684*/) {
      result.add(listeNichtzulassungsgruendeColumn); // ELECT-12381, cf. BasisDirektkandidaturColumnBuilder#direktkandidaturNichtzulassungsgruendeColumn, BasisListenkandidaturColumnBuilder#listenkandidaturNichtzulassungsgruendeColumn!!!
    }
  }

  private boolean isWahlMitMehrfachnennungen() {
    Wahl wahl = getSelectedWahl();

    return wahl != null && wahl.isWahlMitMehrfachnennungen();
  }

  private boolean isWahlMitListenverbindungen() {
    Wahl wahl = getSelectedWahl();

    return wahl != null && wahl.isWahlMitListenverbindungenErlaubt();
  }

  @Nullable
  protected Wahl getSelectedWahl() {
    if (gebietSelect.isSelected()) {
      return getSelectedGebiet().getWahl();
    }

    return null;
  }

  protected Gebiet getSelectedGebiet() {
    return gebietSelect.getEntity();
  }

  protected EntityAufStimmzettelDaten getEntityAufStimmzettelDaten() {
    if (entityAufStimmzettelDaten == null) {
      entityAufStimmzettelDaten = entityAufStimmzettelDatenExtendedDAOFactory.getEntityAufStimmzettelDaten();
    }

    return entityAufStimmzettelDaten;
  }

  protected CurrentWahlZulassungspruefungExtended getCurrentWahlZulassungspruefung() {
    return currentWahlZulassungspruefung;
  }

  private boolean isEinzelbewerberErfassbar() {
    return getEinzelbewerberKandidaturKonfiguration().isEinzelbewerberListenkandidaturAnlegenZulaessig(getSelectedGebiet());
  }

  protected EinzelbewerberKandidaturKonfiguration getEinzelbewerberKandidaturKonfiguration() {
    return einzelbewerberKandidaturKonfiguration;
  }
}
