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

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

import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Named;

import de.ivu.elect.business.ergebnis.boundary.ErgebnisSessionSelect;
import de.ivu.elect.business.ergebnis.entity.Ergebnis;
import de.ivu.elect.business.ergebnis.entity.Stimmenart;
import de.ivu.elect.business.gruppe.entity.SystemGruppeEigenschaften;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabeAuffaelligkeit;
import de.ivu.elect.jee.faces.UserLocale;
import de.ivu.elect.jee.presentation.dynamictable.AbstractColumnBuilder;
import de.ivu.elect.jee.presentation.dynamictable.ColumnEntry;
import de.ivu.elect.presentation.auffaelligkeit.table.AuffaelligkeitNachBenfordTestColumn;
import de.ivu.elect.presentation.auffaelligkeit.table.StimmeingabeAuffaelligkeitAbweichungSummeColumn;
import de.ivu.elect.presentation.auffaelligkeit.table.StimmeingabeAuffaelligkeitBemerkungenColumn;
import de.ivu.elect.presentation.auffaelligkeit.table.StimmeingabeAuffaelligkeitErfasserColumn;
import de.ivu.elect.presentation.auffaelligkeit.table.StimmeingabeAuffaelligkeitGebietsnameColumn;
import de.ivu.elect.presentation.auffaelligkeit.table.StimmeingabeAuffaelligkeitGebietsnummerColumn;

@Named(StimmeingabeAuffaelligkeitColumnBuilder.COMPONENT_NAME)
public class StimmeingabeAuffaelligkeitColumnBuilder extends AbstractColumnBuilder<StimmeingabeAuffaelligkeit> {

  private static final long serialVersionUID = 1L;

  public static final String COMPONENT_NAME = "stimmeingabeAuffaelligkeitColumnBuilder";

  @Inject
  private transient SystemGruppeEigenschaften systemGruppeEigenschaften;

  private StimmeingabeAuffaelligkeitGebietsnameColumn gebietsnameColumn;

  private StimmeingabeAuffaelligkeitGebietsnummerColumn gebietsnummerColumn;

  private StimmeingabeAuffaelligkeitErfasserColumn erfasserColumn;

  private List<StimmeingabeAuffaelligkeitAbweichungSummeColumn> abweichungSummeColumns;

  @Inject
  private transient ErgebnisSessionSelect ergebnisSelect;

  @Inject
  private transient UserLocale userLocale;


  private StimmeingabeAuffaelligkeitBemerkungenColumn bemerkungenColumn;

  private AuffaelligkeitNachBenfordTestColumn benfordTestErgebnisColumn;

  public StimmeingabeAuffaelligkeitColumnBuilder() {
    super();
  }

  @Override
  protected void initColumns() {
    gebietsnameColumn = new StimmeingabeAuffaelligkeitGebietsnameColumn(getMessages());
    gebietsnummerColumn = new StimmeingabeAuffaelligkeitGebietsnummerColumn(getMessages());
    erfasserColumn = new StimmeingabeAuffaelligkeitErfasserColumn(getMessages());
    List<Stimmenart> stimmenarten = getStimmenarten();
    abweichungSummeColumns = new ArrayList<>();
    for (Stimmenart stimmenart : stimmenarten) {
      abweichungSummeColumns.add(new StimmeingabeAuffaelligkeitAbweichungSummeColumn(getMessages(), stimmenart));
    }

    bemerkungenColumn = new StimmeingabeAuffaelligkeitBemerkungenColumn(userLocale.getLocale(), getMessages());
    benfordTestErgebnisColumn = new AuffaelligkeitNachBenfordTestColumn(getMessages());
  }

  @Nonnull
  private List<Stimmenart> getStimmenarten() {
    List<Stimmenart> result = new ArrayList<>();
    if (isWahlMitDirektkandidatengebieten()) {
      result.add(Stimmenart.DIREKTSTIMME);
    }
    if (isWahlMitListengebieten()) {
      result.add(Stimmenart.LISTENSTIMME);
    }
    return result;
  }

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

    result.add(gebietsnameColumn);
    result.add(gebietsnummerColumn);
    result.addAll(abweichungSummeColumns);
    result.add(erfasserColumn);
    result.add(bemerkungenColumn);
    result.add(benfordTestErgebnisColumn);

    return result;
  }

  private boolean isWahlMitDirektkandidatengebieten() {
    if (isErgebnisSelected()) {
      return getErgebnis().getWahl().isWahlMitDirektkandidatengebieten();
    }

    return false;
  }

  private boolean isWahlMitListengebieten() {
    if (isErgebnisSelected()) {
      return getErgebnis().getWahl().isWahlMitListengebieten();
    }

    return false;
  }

  private boolean isErgebnisSelected() {
    return ergebnisSelect.isSelected();
  }

  private Ergebnis getErgebnis() {
    return ergebnisSelect.getEntity();
  }
}
