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

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

import javax.inject.Inject;
import javax.inject.Named;

import de.ivu.elect.business.anschrift.boundary.ZusammengesetzteAnschriftFormatter;
import de.ivu.elect.business.anschrift.entity.AnschriftConstants;
import de.ivu.elect.business.gebietsbaum.boundary.GebietExtendedDAO;
import de.ivu.elect.business.stimmeingabe.boundary.LetzterEingangLoader;
import de.ivu.elect.business.wahl.boundary.WahlExtendedDAO;
import de.ivu.elect.business.wahl.boundary.WahlSessionSelect;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.WahlParameterExtendedLoader;
import de.ivu.elect.business.wahl.entity.WahlParameterWerte;
import de.ivu.elect.business.wahllokalsystem.boundary.WahllokalsystemStatusExtendedDAO;
import de.ivu.elect.business.wahllokalsystem.entity.WahllokalsystemStatus;
import de.ivu.elect.jee.presentation.dynamictable.AbstractColumnBuilder;
import de.ivu.elect.jee.presentation.dynamictable.ColumnEntry;
import de.ivu.elect.jee.presentation.dynamictable.ColumnType;
import de.ivu.elect.presentation.anschrift.table.EntityMitAnschriftZusammengesetzteAnschriftColumn;
import de.ivu.elect.presentation.gebietsbaum.GebietNummerFormatter;

@Named(WahllokalsystemStatusColumnBuilder.COMPONENT_NAME)
public class WahllokalsystemStatusColumnBuilder extends AbstractColumnBuilder<WahllokalsystemStatus> {

  public static final String COMPONENT_NAME = "wahllokalsystemStatusColumnBuilder";

  private static final long serialVersionUID = 1L;

  @Inject
  private transient WahllokalsystemStatusExtendedDAO wahllokalsystemStatusExtendedDAO;

  @Inject
  private transient GebietNummerFormatter gebietNummerFormatter;

  @Inject
  private transient WahlSessionSelect wahlSessionSelect;

  @Inject
  private transient GebietExtendedDAO gebietExtendedDAO;

  @Inject
  private transient WahlExtendedDAO wahlExtendedDAO;

  @Inject
  private transient ZusammengesetzteAnschriftFormatter zusammengesetzteAnschriftFormatter;

  @Inject
  private transient WahlParameterExtendedLoader wahlParameterExtendedLoader;

  @Inject
  private transient LetzterEingangLoader letzterEingangLoader;

  private transient AbstractWahllokalsystemStatusColumn<WahllokalsystemStatus> gebietColumn;

  private WahllokalsystemStatusLetzteMeldungColumn wahllokalsystemStatusLetzteMeldungColumn;

  private AbstractWahllokalsystemStatusColumn<WahllokalsystemStatus> wahllokalsystemStatusLetzteAbmeldungColumn;

  private WahllokalsystemStatusAnzahlWaehlerColumn wahllokalsystemStatusAnzahlWaehlerColumn;

  private WahllokalsystemStatusDokumenteColumn wahllokalsystemStatusDokumenteColumn;

  private List<WahllokalsystemStatusDokumenteColumn> wahllokalsystemStatusDokumenteColumnWeitereWahlen;

  private AbstractWahllokalsystemStatusColumn<WahllokalsystemStatus> wahllokalsystemStatusAusstattungColumn;

  private AbstractWahllokalsystemStatusColumn<WahllokalsystemStatus> wahllokalsystemStatusBemerkungColumn;

  private WahllokalsystemOnlineStatusColumn wahllokalsystemOnlineStatusColumn;

  private WahllokalsystemStatusAnschriftColumn wahllokalsystemStatusAnschriftColumn;

  @Override
  protected void initColumns() {

    gebietColumn = AbstractWahllokalsystemStatusColumn.createGebietColumn(messages, ColumnType.STRING,
        wahllokalsystemStatus -> gebietNummerFormatter.getNameMitNummer(wahllokalsystemStatusExtendedDAO.attach(wahllokalsystemStatus).getGebiet()));

    wahllokalsystemStatusAusstattungColumn = AbstractWahllokalsystemStatusColumn.createWahllokalsystemStatusAusstattungColumn(messages);
    wahllokalsystemStatusBemerkungColumn = AbstractWahllokalsystemStatusColumn.createWahllokalsystemStatusBemerkungColumn(messages);

    Date now = new Date();
    Long onlineTimeout = getOnlineTimeout();
    wahllokalsystemOnlineStatusColumn = new WahllokalsystemOnlineStatusColumn(messages, now, onlineTimeout);
    wahllokalsystemStatusLetzteMeldungColumn = new WahllokalsystemStatusLetzteMeldungColumn(messages, icons, now, onlineTimeout);

    wahllokalsystemStatusLetzteAbmeldungColumn = AbstractWahllokalsystemStatusColumn.createWahllokalsystemStatusLetzteAbmeldungColumn(messages);
    wahllokalsystemStatusAnzahlWaehlerColumn = new WahllokalsystemStatusAnzahlWaehlerColumn(messages, userLocale);
    Wahl selectedWahl = getSelectedWahl();
    wahllokalsystemStatusDokumenteColumn = createStatusDokumenteColumn(selectedWahl);
    wahllokalsystemStatusDokumenteColumnWeitereWahlen = new ArrayList<>();
    if (selectedWahl != null) {
      for (Wahl weitereWahl : selectedWahl.getWeitereWahlenAmWahltermin()) {
        wahllokalsystemStatusDokumenteColumnWeitereWahlen.add(createStatusDokumenteColumn(weitereWahl));
      }
    }

    wahllokalsystemStatusAnschriftColumn = new WahllokalsystemStatusAnschriftColumn(messages, AnschriftConstants.MESSAGE_KEY_ENTITY_EINZAHL,
        new EntityMitAnschriftZusammengesetzteAnschriftColumn<>("GebietZusammengesetzteAnschriftColumn", messages, zusammengesetzteAnschriftFormatter));
  }

  private WahllokalsystemStatusDokumenteColumn createStatusDokumenteColumn(Wahl wahl) {
    return new WahllokalsystemStatusDokumenteColumn(messages, userLocale, wahl, wahllokalsystemStatusExtendedDAO, gebietExtendedDAO, wahlExtendedDAO, letzterEingangLoader);
  }

  private Wahl getSelectedWahl() {
    return wahlSessionSelect.getEntity();
  }

  private Long getOnlineTimeout() {
    Wahl entity = getSelectedWahl();
    if (entity == null) {
      return null;
    }
    return wahlParameterExtendedLoader.resolveLongValue(entity, WahlParameterWerte.WAHLLOKALSYSTEM_STATUS_OFFLINE_TIMEOUT_IN_SECONDS);
  }

  @Override
  protected List<ColumnEntry< ? super WahllokalsystemStatus>> getColumnEntriesSorted() {
    List<ColumnEntry< ? super WahllokalsystemStatus>> result = new ArrayList<>();
    result.add(gebietColumn);
    result.add(wahllokalsystemStatusAusstattungColumn);
    result.add(wahllokalsystemOnlineStatusColumn);
    result.add(wahllokalsystemStatusLetzteMeldungColumn);
    result.add(wahllokalsystemStatusLetzteAbmeldungColumn);
    result.add(wahllokalsystemStatusAnzahlWaehlerColumn);
    result.add(wahllokalsystemStatusDokumenteColumn);
    result.addAll(wahllokalsystemStatusDokumenteColumnWeitereWahlen);
    result.add(wahllokalsystemStatusAnschriftColumn);
    result.add(wahllokalsystemStatusBemerkungColumn);

    return result;
  }
}
