
package de.ivu.elect.presentation.verteilung;

import static java.util.stream.Collectors.joining;
import static org.apache.commons.lang3.StringUtils.isNotBlank;

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

import de.ivu.elect.business.verteilung.boundary.VerteilungContext;
import de.ivu.elect.business.verteilung.boundary.VerteilungTeilnehmer;
import de.ivu.elect.business.verteilung.boundary.VerteilungTeilnehmerErgebnis;
import de.ivu.elect.jee.presentation.dynamicform.AdvancedDynaFormModel;
import de.ivu.elect.jee.presentation.dynamictable.AbstractColumnBuilder;
import de.ivu.elect.presentation.verteilung.table.AbstractVerteilungBerechnenViewVerteilungResultColumnBuilder;

public class VerteilungBerechnenViewVerteilungResult extends AbstractVerteilungBerechnenViewResult {

  private final AbstractVerteilungBerechnenViewVerteilungResultColumnBuilder verteilungBerechnenViewVerteilungColumnBuilder;

  public VerteilungBerechnenViewVerteilungResult(VerteilungBerechnenViewContext context, VerteilungBerechnenViewErgebnis ergebnis,
      AbstractVerteilungBerechnenViewVerteilungResultColumnBuilder verteilungBerechnenViewVerteilungColumnBuilder) {
    super(context, ergebnis);

    this.verteilungBerechnenViewVerteilungColumnBuilder = verteilungBerechnenViewVerteilungColumnBuilder;
  }

  public List<VerteilungBerechnenViewVerteilungSchritt> getSchritte() {
    List<VerteilungBerechnenViewVerteilungSchritt> result = new ArrayList<>();

    getErgebnis().ifPresent(ergebnis -> {
      VerteilungContext context = ergebnis.getContext();

      List<String> teilnehmerErgebnisseBeschreibung = new ArrayList<>();

      ergebnis.findTeilnehmerErgebnisTeilnehmerIsInMehrheitssicherung().ifPresent(teilnehmerErgebnisTeilnehmerIsInMehrheitssicherung -> {
        // Hinweis auf fehlende Mehrheitssicherung immer anzeigen...
        teilnehmerErgebnisseBeschreibung.add(context.getMessage("ElectVerteilungAlgorithmus.mehrheitssicherung.anzahl.sitze", 1L,
            teilnehmerErgebnisTeilnehmerIsInMehrheitssicherung.getTeilnehmer().getLabel(), teilnehmerErgebnisTeilnehmerIsInMehrheitssicherung.getAnzahlStimmen()));

        VerteilungBerechnenViewMehrheitssicherung mehrheitssicherung = getMehrheitssicherung();

        if (!VerteilungBerechnenViewMehrheitssicherung.OHNE.equals(mehrheitssicherung)) {
          String mehrheitssicherungBeschreibung = mehrheitssicherung.formatBeschreibung(getContext(), teilnehmerErgebnisTeilnehmerIsInMehrheitssicherung);

          if (isNotBlank(mehrheitssicherungBeschreibung)) {
            teilnehmerErgebnisseBeschreibung.add(mehrheitssicherungBeschreibung);
          }
        }
      });

      List<VerteilungTeilnehmerErgebnis> teilnehmerErgebnisseTeilnehmerIsInLosverfahren = ergebnis.collectTeilnehmerErgebnisseTeilnehmerIsInLosverfahren();

      if (!teilnehmerErgebnisseTeilnehmerIsInLosverfahren.isEmpty()) {
        teilnehmerErgebnisseBeschreibung.add(context.getMessage("ElectVerteilungAlgorithmus.losverfahren.anzahl.sitze", teilnehmerErgebnisseTeilnehmerIsInLosverfahren.size(),
            teilnehmerErgebnisseTeilnehmerIsInLosverfahren.stream().map(VerteilungTeilnehmerErgebnis::getTeilnehmer).map(VerteilungTeilnehmer::getLabel).collect(joining(", ")),
            ergebnis.getAnzahlSitzeVerteiltInLosverfahren()));
      }

      result.add(new VerteilungBerechnenViewVerteilungSchritt(context, ergebnis.collectTeilnehmerErgebnisse(), teilnehmerErgebnisseBeschreibung));
    });

    return result;
  }

  public class VerteilungBerechnenViewVerteilungSchritt {

    private final VerteilungContext context;

    private final List<VerteilungBerechnenViewTeilnehmerErgebnis> teilnehmerErgebnisse;

    private final List<String> teilnehmerErgebnisseBeschreibung;

    public VerteilungBerechnenViewVerteilungSchritt(VerteilungContext context, List<VerteilungBerechnenViewTeilnehmerErgebnis> teilnehmerErgebnisse, List<String> teilnehmerErgebnisseBeschreibung) {
      super();

      this.context = context;

      this.teilnehmerErgebnisse = teilnehmerErgebnisse;
      this.teilnehmerErgebnisseBeschreibung = teilnehmerErgebnisseBeschreibung;
    }

    public List<VerteilungBerechnenViewTeilnehmerErgebnis> getTeilnehmerErgebnisse() {
      List<VerteilungBerechnenViewTeilnehmerErgebnis> result = new ArrayList<>();
      result.addAll(teilnehmerErgebnisse);

      return result;
    }

    public String getTeilnehmerErgebnisseBemerkung() {
      return verteilungBerechnenViewVerteilungColumnBuilder.collectColumnTooltips(teilnehmerErgebnisse).stream().collect(joining(", "));
    }

    public AbstractColumnBuilder<VerteilungBerechnenViewTeilnehmerErgebnis> getTeilnehmerErgebnisseColumnBuilder() {
      return verteilungBerechnenViewVerteilungColumnBuilder;
    }

    public boolean isTeilnehmerErgebnisseModelRendered() {
      return getTeilnehmerErgebnisseModel().isAnyPropertyAdded();
    }

    public AdvancedDynaFormModel getTeilnehmerErgebnisseModel() {
      return createResultModel(teilnehmerErgebnisseBeschreibung);
    }
  }
}
