
package de.ivu.elect.business.ergebnis.control;

import static java.util.Arrays.asList;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import de.ivu.elect.business.ergebnis.entity.Stimmabgabeart;
import de.ivu.elect.business.ergebnis.entity.Stimmenart;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.gruppe.entity.SystemGruppe;
import de.ivu.elect.business.internet.control.GebietUndStimmabgabeart;

// ELECT-11817
public class NlErgebnisDatenWaehler extends AbstractErgebnisDaten {

  private final Map<GebietUndStimmabgabeart, Map<Stimmenart, Long>> waehler = new HashMap<>();

  private final StimmenPool stimmen;

  private final StimmenKumulierer stimmenKumulierer;

  public NlErgebnisDatenWaehler(NlErgebnisDaten nlErgebnisDaten) {
    super(nlErgebnisDaten.collectGebieteUntergeordnetFct(), nlErgebnisDaten.collectGebieteErfasstFct());

    this.stimmen = nlErgebnisDaten.getStimmen();
    this.stimmenKumulierer = nlErgebnisDaten.getStimmenKumulierer();
  }

  private StimmenPool getStimmen() {
    return stimmen;
  }

  BestimmeStimmen<Stimmenart, GebietUndStimmabgabeart> waehlerBestimmeStimmen = new BestimmeStimmen<Stimmenart, GebietUndStimmabgabeart>() {

    @Override
    public Long ermittleStimmen(Stimmenart stimmenart, Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet) {
      return stimmenKumulierer.bestimmeSummeSystemGruppenStimmenAufGebiet(getStimmen(), wahldurchfuehrungsgebiet, SystemGruppe.WAEHLER, stimmenart); // ELECT-11817
    }

    @Override
    public Map<Stimmenart, Long> getErgebnisUntergebiet(GebietUndStimmabgabeart gebietUndStimmabgabeart) {
      return getSummeWaehler(gebietUndStimmabgabeart);
    }

    @Override
    public List<Stimmenart> getTargetAufGebiet(GebietUndStimmabgabeart gebietUndStimmabgabeart) {
      return asList(Stimmenart.OHNE_WAHLSCHEIN, Stimmenart.MIT_WAHLSCHEIN, Stimmenart.ALS_URNENWAHL_IN_URNE, Stimmenart.ALS_BRIEFWAHL_IN_URNE, Stimmenart.MIT_VOLLMACHT, Stimmenart.GESAMT);
    }
  };

  public long getSummeWaehlerOhneWahlschein(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmabgabeart stimmabgabeart) {
    return getSummeWaehlerOhneWahlschein(new GebietUndStimmabgabeart(wahldurchfuehrungsgebiet, stimmabgabeart));
  }

  public long getSummeWaehlerOhneWahlschein(GebietUndStimmabgabeart gebietUndStimmabgabeart) {
    return getSummeWaehler(gebietUndStimmabgabeart, Stimmenart.OHNE_WAHLSCHEIN);
  }

  public long getSummeWaehlerMitWahlschein(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmabgabeart stimmabgabeart) {
    return getSummeWaehlerMitWahlschein(new GebietUndStimmabgabeart(wahldurchfuehrungsgebiet, stimmabgabeart));
  }

  public long getSummeWaehlerMitWahlschein(GebietUndStimmabgabeart gebietUndStimmabgabeart) {
    return getSummeWaehler(gebietUndStimmabgabeart, Stimmenart.MIT_WAHLSCHEIN);
  }

  public long getSummeWaehlerMitVollmacht(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmabgabeart stimmabgabeart) {
    return getSummeWaehlerMitVollmacht(new GebietUndStimmabgabeart(wahldurchfuehrungsgebiet, stimmabgabeart));
  }

  public long getSummeWaehlerMitVollmacht(GebietUndStimmabgabeart gebietUndStimmabgabeart) {
    return getSummeWaehler(gebietUndStimmabgabeart, Stimmenart.MIT_VOLLMACHT);
  }

  public long getSummeWaehlerGesamt(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Stimmabgabeart stimmabgabeart) {
    return getSummeWaehlerGesamt(new GebietUndStimmabgabeart(wahldurchfuehrungsgebiet, stimmabgabeart));
  }

  public long getSummeWaehlerGesamt(GebietUndStimmabgabeart gebietUndStimmabgabeart) {
    return getSummeWaehler(gebietUndStimmabgabeart, Stimmenart.GESAMT);
  }

  public long getSummeWaehler(GebietUndStimmabgabeart gebietUndStimmabgabeart, Stimmenart stimmenart) {
    return notNull(getSummeWaehler(gebietUndStimmabgabeart).get(stimmenart));
  }

  private Map<Stimmenart, Long> getSummeWaehler(GebietUndStimmabgabeart gebietUndStimmabgabeart) {
    return bestimmeStimmenOderSummiereAufUntergebieten(gebietUndStimmabgabeart, waehler, waehlerBestimmeStimmen);
  }
}
