
package de.ivu.elect.business.stimmeingabe.boundary;

import static de.ivu.elect.jee.entity.EntityUtil.castTo;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;

import java.util.List;

import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingabestufe;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingangsart;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingangsfehlerstatus;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.WahlartErgebnisart;
import de.ivu.elect.business.wahl.entity.Wahldurchfuehrung;

public class ErgebniseingangKonfiguration {

  public ErgebniseingangKonfiguration() {
    super();
  }

  public Ergebniseingangsart getErgebniseingangsartInitial(Wahl wahl) {
    List<Ergebniseingangsart> ergebniseingangsarten = collectErgebniseingangsarten(wahl);

    if (wahl != null && wahl.isInstanceOf(Wahldurchfuehrung.class)) {
      Ergebniseingangsart ergebniseingangsartPreset = castTo(wahl, Wahldurchfuehrung.class).getErgebniseingangsart();

      if (ergebniseingangsarten.contains(ergebniseingangsartPreset)) { // ELECT-10898
        return ergebniseingangsartPreset;
      }
    }

    return ergebniseingangsarten.stream().findFirst().orElse(Ergebniseingangsart.VORLAEUFIG);
  }

  public boolean isWechselErgebniseingangsartenUnterstuetzt(Wahl wahl) {
    List<Ergebniseingangsart> ergebniseingangsarten = collectErgebniseingangsarten(wahl);

    return ergebniseingangsarten.size() > 1 || ergebniseingangsarten.size() == 1 && wahl != null && wahl.isInstanceOf(Wahldurchfuehrung.class)
        && !ergebniseingangsarten.get(0).equalsErgebnisart(castTo(wahl, Wahldurchfuehrung.class).getErgebniseingangsart());
  }

  public boolean isErgebniseingangsartVorlaeufigUnterstuetzt(Wahl wahl) {
    return isErgebniseingangsartUnterstuetzt(wahl, Ergebniseingangsart.VORLAEUFIG);
  }

  public boolean isErgebniseingangsartEndgueltigUnterstuetzt(Wahl wahl) {
    return isErgebniseingangsartUnterstuetzt(wahl, Ergebniseingangsart.ENDGUELTIG);
  }

  public boolean isErgebniseingangsartUnterstuetzt(Wahl wahl, WahlartErgebnisart ergebnisart) {
    return ergebnisart != null && (ergebnisart.isVorlaeufig() && isErgebniseingangsartVorlaeufigUnterstuetzt(wahl) || ergebnisart.isEndgueltig() && isErgebniseingangsartEndgueltigUnterstuetzt(wahl));
  }

  public boolean isErgebniseingangsartUnterstuetzt(Wahl wahl, Ergebniseingangsart ergebniseingangsart) {
    return collectErgebniseingangsarten(wahl).contains(ergebniseingangsart);
  }

  public List<Ergebniseingangsart> collectErgebniseingangsarten(Wahl wahl) {
    return asList(Ergebniseingangsart.values());
  }

  public Ergebniseingabestufe getErgebniseingabestufeInitial(Wahl wahl) {
    return collectErgebniseingabestufen(wahl).stream().findFirst().orElse(Ergebniseingabestufe.ENDSTUFE);
  }

  public boolean isWechselErgebniseingabestufenUnterstuetzt(Wahl wahl) {
    return collectErgebniseingabestufen(wahl).size() > 1;
  }

  public boolean isErgebniseingabestufeUnterstuetzt(Wahl wahl, Ergebniseingabestufe... ergebniseingabestufen) {
    return ergebniseingabestufen != null && ergebniseingabestufen.length > 0 && collectErgebniseingabestufen(wahl).containsAll(asList(ergebniseingabestufen));
  }

  public List<Ergebniseingabestufe> collectErgebniseingabestufen(Wahl wahl) {
    return asList(Ergebniseingabestufe.ENDSTUFE);
  }

  public List<Ergebniseingangsfehlerstatus> collectErgebniseingangsfehlerstatus(Wahl wahl) {
    return collectErgebniseingabestufen(wahl).stream().flatMap(ergebniseingabestufe -> ergebniseingabestufe.collectErgebniseingangsfehlerstatus().stream()).distinct().sorted().collect(toList());
  }
}
