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

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

import javax.inject.Inject;

import de.ivu.elect.business.ergebnis.entity.Stimmenart;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.gruppe.entity.NlSystemGruppe;
import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebiet;
import de.ivu.elect.business.stimmeingabe.control.NlStimmeingabeKopfzahlKonfiguration;
import de.ivu.elect.business.stimmeingabe.control.StimmeingabeErfassenContext;
import de.ivu.elect.business.stimmeingabe.entity.Ergebniseingang;
import de.ivu.elect.business.stimmeingabe.entity.NlStimmeingabeKopfzahlErfassenModel;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabeKopfzahl;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabeKopfzahlErfassenModel;
import de.ivu.elect.business.wahl.entity.WahlartErgebnisart;

// https://support.elect-it.com/wiki/display/ELECT/Kopfzahlen+in+VAPP
public class NlStimmeingabeKopfzahlModelBuilder extends AbstractStimmeingabeKopfzahlModelBuilder {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient NlStimmeingabeKopfzahlKonfiguration nlStimmeingabeKopfzahlKonfiguration;

  public NlStimmeingabeKopfzahlModelBuilder() {
    super();
  }

  @Override
  protected NlStimmeingabeKopfzahlErfassenModel createStimmeingabeKopfzahlErfassenModel(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, Ergebniseingang ergebniseingang) {
    return new NlStimmeingabeKopfzahlErfassenModel(wahldurchfuehrungsgebiet, ergebniseingang);
  }

  @Override
  protected void initializeModelStimmeingabeKopfzahl(StimmeingabeKopfzahlErfassenModel result, GruppeImGebiet gruppeImGebiet, StimmeingabeErfassenContext context) {
    super.initializeModelStimmeingabeKopfzahl(result, gruppeImGebiet, context);

    initializeModelStimmeingabeKopfzahl((NlStimmeingabeKopfzahlErfassenModel) result, gruppeImGebiet, context);

    boolean anzahlWahlberechtigteGesamtNurAngezeigt = result.hasWahlberechtigteGesamt()
        && getStimmeingabeKopfzahlKonfiguration().isWahlberechtigteGesamtBeiStimmeingabeNurAnzuzeigen(context.getWahldurchfuehrungsgebiet(),
        context.getErgebniseingangsart(), context);

    if (anzahlWahlberechtigteGesamtNurAngezeigt) {
      StimmeingabeKopfzahl wahlberechtigteGesamt = result.getWahlberechtigteGesamt();

      if (!wahlberechtigteGesamt.hasAnzahl()) {
        wahlberechtigteGesamt.setAnzahlEingabe("0"); // ELECTVAPP-1295
      }
    }
  }

  private void initializeModelStimmeingabeKopfzahl(NlStimmeingabeKopfzahlErfassenModel result, GruppeImGebiet gruppeImGebiet, StimmeingabeErfassenContext context) {
    for (NlSystemGruppe nlSystemGruppe : NlSystemGruppe.valuesStimmzettel()) {
      if (nlSystemGruppe.equalsSystemGruppe(gruppeImGebiet, getSystemGruppeEigenschaften())) {
        for (Stimmenart stimmenart : nlSystemGruppe.getStimmenarten()) {
          if (isStimmeingabeKopfzahlCreated(context, nlSystemGruppe, stimmenart)) {
            result.setStimmeingabeKopfzahl(nlSystemGruppe, stimmenart, createStimmeingabeKopfzahl(context, gruppeImGebiet, stimmenart));
          }
        }
      }
    }
  }

  @Override
  protected void sortModelStimmeingabeWahlberechtigte(List<StimmeingabeKopfzahl> stimmeingabenWahlberechtigteRendered) {
    // Do nothing...
  }

  @Override
  protected void sortModelStimmeingabeWaehler(List<StimmeingabeKopfzahl> stimmeingaben) {
    // Do nothing...
  }

  public List<StimmeingabeKopfzahl> layoutModelStimmeingabeKopfzahlStimmzettelEingenommenAbweichend(NlStimmeingabeKopfzahlErfassenModel model) {
    List<StimmeingabeKopfzahl> result = new ArrayList<>();

    if (model.hasStimmzettelEingenommenAbweichendZuviel()) {
      result.add(model.getStimmzettelEingenommenAbweichendZuviel());
    }

    if (model.hasStimmzettelEingenommenAbweichendZuwenig()) {
      result.add(model.getStimmzettelEingenommenAbweichendZuwenig());
    }

    if (model.hasStimmzettelEingenommenAbweichendGrundAusgegebenNichtAbgegeben()) {
      result.add(model.getStimmzettelEingenommenAbweichendGrundAusgegebenNichtAbgegeben());
    }

    if (model.hasStimmzettelEingenommenAbweichendGrundAusgegebenZuwenig()) {
      result.add(model.getStimmzettelEingenommenAbweichendGrundAusgegebenZuwenig());
    }

    if (model.hasStimmzettelEingenommenAbweichendGrundAusgegebenZuviel()) {
      result.add(model.getStimmzettelEingenommenAbweichendGrundAusgegebenZuviel());
    }

    if (model.hasStimmzettelEingenommenAbweichendGrundInWahlbriefZuwenig()) {
      result.add(model.getStimmzettelEingenommenAbweichendGrundInWahlbriefZuwenig());
    }

    if (model.hasStimmzettelEingenommenAbweichendGrundInWahlbriefZuviel()) {
      result.add(model.getStimmzettelEingenommenAbweichendGrundInWahlbriefZuviel());
    }

    if (model.hasStimmzettelEingenommenAbweichendGrundVerloren()) {
      result.add(model.getStimmzettelEingenommenAbweichendGrundVerloren());
    }

    /*
     * ELECTVAPP-2245, "Sonstiges" VOR "Unbekannt"!
     */

    if (model.hasStimmzettelEingenommenAbweichendGrundSonstiges()) {
      result.add(model.getStimmzettelEingenommenAbweichendGrundSonstiges());
    }

    if (model.hasStimmzettelEingenommenAbweichendGrundUnbekannt()) {
      result.add(model.getStimmzettelEingenommenAbweichendGrundUnbekannt());
    }

    return result;
  }

  private boolean isStimmeingabeKopfzahlCreated(StimmeingabeErfassenContext context, NlSystemGruppe nlSystemGruppe, Stimmenart stimmenart) {
    return isStimmeingabeKopfzahlCreated(context.getWahldurchfuehrungsgebiet(), context.getErgebniseingangsart(), nlSystemGruppe, stimmenart);
  }

  protected boolean isStimmeingabeKopfzahlCreated(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, WahlartErgebnisart ergebnisart, NlSystemGruppe nlSystemGruppe, Stimmenart stimmenart) {
    return getStimmeingabeKopfzahlKonfiguration().isGruppeMitStimmenartBeiStimmeingabeRelevant(wahldurchfuehrungsgebiet, ergebnisart, nlSystemGruppe, stimmenart);
  }

  @Override
  protected boolean isWaehlerMitVollmachtCreated(Wahldurchfuehrungsgebiet wahldurchfuehrungsgebiet, WahlartErgebnisart ergebnisart) {
    return getStimmeingabeKopfzahlKonfiguration().isWaehlerMitVollmachtBeiStimmeingabeRelevant(wahldurchfuehrungsgebiet, ergebnisart);
  }

  @Override
  protected NlStimmeingabeKopfzahlKonfiguration getStimmeingabeKopfzahlKonfiguration() {
    return nlStimmeingabeKopfzahlKonfiguration;
  }
}
