
package de.ivu.elect.business.stimmeingabe.control.plausi;

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

import de.ivu.elect.business.stimmeingabe.entity.Stimmeingabe;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabePlausiKonfiguration;
import de.ivu.elect.jee.faces.Messages;

// ELECT-16548
public abstract class AbstractGruppeStimmenAnzahlenUngleichGueltigeStimmenAnzahlenAnteilePlausi extends AbstractStimmeingabePlausi {

  private final Double anteilDirektstimmen;

  private final Stimmeingabe stimmeingabeGueltigeDirektstimmen;

  private final Double anteilListenstimmen;

  private final Stimmeingabe stimmeingabeGueltigeListenstimmen;

  private final Stimmeingabe stimmeingabeGruppeListenstimmen;

  protected AbstractGruppeStimmenAnzahlenUngleichGueltigeStimmenAnzahlenAnteilePlausi(Stimmeingabe stimmeingabeGueltigeDirektstimmen, Stimmeingabe stimmeingabeGueltigeListenstimmen,
      Stimmeingabe stimmeingabeGruppeListenstimmen, StimmeingabePlausiKonfiguration stimmeingabePlausiKonfiguration, Messages messages) {
    super(stimmeingabePlausiKonfiguration, messages);

    GruppeStimmenAnzahlenUngleichGueltigeStimmenAnzahlenAnteilePlausiCustomData stimmeingabePlausiKonfigurationCustomData = stimmeingabePlausiKonfiguration
        .getCustomData(GruppeStimmenAnzahlenUngleichGueltigeStimmenAnzahlenAnteilePlausiCustomData.class);

    this.anteilDirektstimmen = stimmeingabePlausiKonfigurationCustomData.getAnteilDirektstimmen();

    this.stimmeingabeGueltigeDirektstimmen = stimmeingabeGueltigeDirektstimmen;

    this.anteilListenstimmen = stimmeingabePlausiKonfigurationCustomData.getAnteilListenstimmen();

    this.stimmeingabeGueltigeListenstimmen = stimmeingabeGueltigeListenstimmen;
    this.stimmeingabeGruppeListenstimmen = stimmeingabeGruppeListenstimmen;
  }

  @Override
  protected boolean isPlausiResultCalculatedAutomatischKorrigierbar() {
    return false;
  }

  @Override
  protected StimmeingabePlausiResult calculatePlausiResult(Stimmeingabe stimmeingabeGruppeDirektstimmen) {
    if (anteilDirektstimmen == null || anteilListenstimmen == null) {
      return StimmeingabePlausiResult.KEIN_FEHLER;
    }

    if (anteilDirektstimmen.compareTo(0D) <= 0 || anteilListenstimmen.compareTo(0D) <= 0) {
      return StimmeingabePlausiResult.KEIN_FEHLER;
    }

    long anzahlGueltigeDirektstimmen = stimmeingabeGueltigeDirektstimmen.getAnzahl();
    long anzahlGruppeDirektstimmen = stimmeingabeGruppeDirektstimmen.getAnzahl();

    long anzahlGueltigeListenstimmen = stimmeingabeGueltigeListenstimmen.getAnzahl();
    long anzahlGruppeListenstimmen = stimmeingabeGruppeListenstimmen.getAnzahl();

    double anteilDirektstimmenKonfiguriert = anteilDirektstimmen;
    double anteilDirektstimmenBerechnet = anzahlGruppeDirektstimmen * 1D / anzahlGueltigeDirektstimmen;

    double anteilListenstimmenKonfiguriert = anteilListenstimmen;
    double anteilListenstimmenBerechnet = anzahlGruppeListenstimmen * 1D / anzahlGueltigeListenstimmen;

    if (isAnteileBerechnetZulaessig(anteilDirektstimmenKonfiguriert, anteilDirektstimmenBerechnet, anteilListenstimmenKonfiguriert, anteilListenstimmenBerechnet)) {
      return StimmeingabePlausiResult.KEIN_FEHLER;
    }

    return createPlausiResultOhneFiktiveWerteFehlerBeheber(stimmeingabeGruppeDirektstimmen);
  }

  protected abstract boolean isAnteileBerechnetZulaessig(double anteilDirektstimmenKonfiguriert, double anteilDirektstimmenBerechnet, double anteilListenstimmenKonfiguriert,
      double anteilListenstimmenBerechnet);

  @Override
  protected List<Object> getStimmeingabefehlerBeschreibungParameters(Stimmeingabe stimmeingabe) {
    List<Object> result = new ArrayList<>(super.getStimmeingabefehlerBeschreibungParameters(stimmeingabe));
    result.add(StimmeingabePlausiFormatter.formatAnteil(anteilDirektstimmen));
    result.add(StimmeingabePlausiFormatter.formatAnteil(anteilListenstimmen));

    return result;
  }
}
