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

import java.util.function.BiFunction;
import java.util.function.Function;

import de.ivu.elect.business.ergebnis.entity.Stimmenart;
import de.ivu.elect.business.gruppe.entity.PolitischeGruppe;

/**
 *  on 31.03.2016.
 */
public class KumulierteAbweichungMass implements StimmenAbweichungMass {

  @Override
  public double berechneAbweichungImGebiet(AbweichungMassStimmenProvider stimmenProvider) {

    double abweichung = 0d;

    for (PolitischeGruppe politischeGruppe : stimmenProvider.getPolitischeGruppen()) {
      for (Stimmenart stimmenart : stimmenProvider.getStimmenarten()) {

        Double anteilEingegeben = bestimmeAnteil(politischeGruppe, stimmenart, stimmenProvider::getAnzahlGueltigeStimmenEingegeben, stimmenProvider::getAnzahlStimmenEingegeben);
        Double anteilHochgerechnet = bestimmeAnteil(politischeGruppe, stimmenart, stimmenProvider::getAnzahlGueltigeStimmenHochgerechnet, stimmenProvider::getAnzahlStimmenHochgerechnet);
        if (anteilEingegeben != null && anteilHochgerechnet != null) {
          abweichung += Math.abs(anteilEingegeben - anteilHochgerechnet);
        }

      }
    }

    return abweichung*100d;
  }

  private Double bestimmeAnteil(PolitischeGruppe politischeGruppe, Stimmenart stimmenart, Function<Stimmenart, Long> gueltigeFct, BiFunction<PolitischeGruppe, Stimmenart, Long> anzahlFct) {

    Long gueltige = gueltigeFct.apply(stimmenart);
    if (gueltige == null || gueltige == 0L) {
      return null;
    }

    Long anzahl = anzahlFct.apply(politischeGruppe, stimmenart);
    if (anzahl == null) {
      return null;
    }
    return (anzahl * 1d) / gueltige;
  }

  @Override
  public String getMessageKey() {
    return "stimmen.abweichung.mass.kumuliert";
  }


}
