
package de.ivu.elect.presentation.stimmeingabe;

import static java.util.Collections.emptyList;

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

import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebiet;
import de.ivu.elect.business.kandidatur.entity.Listenkandidatur;
import de.ivu.elect.business.stimmeingabe.entity.Stimmeingabe;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabeGruppeStimmen;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabeKopfzahl;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabeListenkandidaturStimmen;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabeListenkandidaturStimmenErfassenModel;
import de.ivu.elect.business.stimmeingabe.entity.StimmeingabeStimmen;
import de.ivu.elect.business.stimmeingabe.entity.Stimmeingabefehler;
import de.ivu.elect.business.wahlvorschlag.entity.Liste;
import de.ivu.elect.business.wahlvorschlag.entity.WahlvorschlagStimmzettelPosition;

public abstract class AbstractStimmeingabeGruppeStimmenErfassenViewListingListenkandidaturStimmen extends AbstractStimmeingabeGruppeStimmenErfassenView {

  private static final long serialVersionUID = 1L;

  private static final StimmeingabeGruppeStimmen EMPTY = StimmeingabeGruppeStimmen.empty();

  protected AbstractStimmeingabeGruppeStimmenErfassenViewListingListenkandidaturStimmen() {
    super();
  }

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

  @Override
  protected boolean isStimmeingabenGruppeStimmenListenstimmeRendered() {
    return true;
  }

  @Override
  public boolean isBtnScrollDownInitiallyRendered() {
    return true; // ELECTVAPP-1040, lange Seite -> man sollte immer "nach unten springen" können, ohne vorher zu scrollen...
  }

  @Override
  public boolean isStimmeingabePlausiFehlerBtnPanelRendered() {
    return isErfassungGesperrt() && hasStimmeingabePlausiFehler(); // ELECTVAPP-1040, lange Seite -> man sollte Buttons auch oben sehen, wenn Fehler zu bestätigen sind...
  }

  @Override
  public boolean isStimmeingabeErfassenBtnPanelRendered() {
    return true; // ELECTVAPP-1040, lange Seite -> man sollte immer speichern können, wenn man schon mal unten ist...
  }

  @Override
  public List<StimmeingabeGruppeStimmen> getStimmeingabenGruppeStimmen() {
    List<StimmeingabeGruppeStimmen> result = new ArrayList<>();

    for (Iterator<StimmeingabeGruppeStimmen> iter = super.getStimmeingabenGruppeStimmen().iterator(); iter.hasNext();) {
      StimmeingabeGruppeStimmen stimmeingabeGruppeStimmen = iter.next();

      if (stimmeingabeGruppeStimmen.isPolitischeGruppe()) {
        StimmeingabeListenkandidaturStimmenErfassenModel stimmeingabeListenkandidaturStimmenErfassenModel = getStimmeingabeListenkandidaturStimmenErfassenModel(
            stimmeingabeGruppeStimmen.getGruppeImGebiet());

        if (stimmeingabeListenkandidaturStimmenErfassenModel != null) {
          for (StimmeingabeListenkandidaturStimmen stimmeingabeListenkandidaturStimmen : stimmeingabeListenkandidaturStimmenErfassenModel.getListenkandidaturStimmen()) {
            if (stimmeingabeListenkandidaturStimmen.getListenkandidatur() != null) {
              result.add(asStimmeingabeGruppeStimmen(stimmeingabeGruppeStimmen, stimmeingabeListenkandidaturStimmen));
            }
          }
        }

        stimmeingabeGruppeStimmen.addRowStyleClass(StimmeingabeStimmen.STYLE_CLASS_SUM); // ELECTVAPP-100
      }

      result.add(stimmeingabeGruppeStimmen);

      if (iter.hasNext()) {
        result.add(asStimmeingabeGruppeStimmenSeparator(stimmeingabeGruppeStimmen));
      }
    }

    return result;
  }

  public String getStimmeingabenGruppeStimmenGroupKey(StimmeingabeGruppeStimmen stimmeingabeGruppeStimmen) {
    if (stimmeingabeGruppeStimmen != null) {
      return stimmeingabeGruppeStimmen.getKennung();
    }

    return "<UNDEFINED>";
  }

  public String getStimmeingabenGruppeStimmenGroupHeader(StimmeingabeGruppeStimmen stimmeingabeGruppeStimmen) {
    if (stimmeingabeGruppeStimmen != null) {
      return getMessage("stimmeingabe.erfassen.tabelle.rowgroup.header", stimmeingabeGruppeStimmen.getBezeichnung());
    }

    return "";
  }

  public String getStimmeingabenGruppeStimmenGroupFooter(StimmeingabeGruppeStimmen stimmeingabeGruppeStimmen) {
    if (stimmeingabeGruppeStimmen != null) {
      return getMessage("stimmeingabe.erfassen.tabelle.rowgroup.footer", stimmeingabeGruppeStimmen.getBezeichnung());
    }

    return "";
  }

  public StimmeingabeGruppeStimmen getStimmeingabenGruppeStimmenGroupStimmeingabeGruppeStimmenGesamt(StimmeingabeGruppeStimmen template) {
    if (template != null) {
      GruppeImGebiet gruppeImGebiet = template.getGruppeImGebiet();

      if (gruppeImGebiet != null) {
        for (StimmeingabeGruppeStimmen stimmeingabeGruppeStimmen : super.getStimmeingabenGruppeStimmen()) {
          if (stimmeingabeGruppeStimmen != null && gruppeImGebiet.equals(stimmeingabeGruppeStimmen.getGruppeImGebiet())) {
            return stimmeingabeGruppeStimmen;
          }
        }
      }
    }

    return EMPTY;
  }

  @Override
  protected String getStimmeingabeBezug(Stimmeingabe stimmeingabe) {
    if (stimmeingabe != null && stimmeingabe.hasListenkandidatur()) { // ELECT-9736
      return getStimmeingabeListenkandidaturStimmenErfassenLabelGenerator().getListenkandidaturStimmenStimmeingabeKennung(getEntityAufStimmzettelDaten(), stimmeingabe, getGruppenImGebiet());
    }

    return super.getStimmeingabeBezug(stimmeingabe);
  }

  protected StimmeingabeKopfzahl asStimmeingabeKopfzahl(StimmeingabeGruppeStimmen stimmeingabeGruppeStimmen) {
    return new StimmeingabeKopfzahl( //
        stimmeingabeGruppeStimmen.getKennung(), stimmeingabeGruppeStimmen.getBezeichnung(), //

        stimmeingabeGruppeStimmen.getStimmeingabeListenstimme(), stimmeingabeGruppeStimmen.getStimmeingabeListenstimmeKennung(), stimmeingabeGruppeStimmen.getStimmeingabeListenstimmeBezeichnung(), "",
        null, stimmeingabeGruppeStimmen.getStimmeingabefehlerListenstimmeLetzterErgebniseingang(), stimmeingabeGruppeStimmen.getStimmeingabeListenstimmeVergleich() //
    );
  }

  protected StimmeingabeGruppeStimmen asStimmeingabeGruppeStimmen(StimmeingabeGruppeStimmen template, StimmeingabeListenkandidaturStimmen stimmeingabeListenkandidaturStimmen) {
    Stimmeingabe stimmeingabeListenkandidatur = stimmeingabeListenkandidaturStimmen.getStimmeingabe();

    Listenkandidatur listenkandidatur = stimmeingabeListenkandidatur.getListenkandidatur();

    WahlvorschlagStimmzettelPosition wahlvorschlagStimmzettelPosition = WahlvorschlagStimmzettelPosition.EMPTY;

    if (listenkandidatur != null) {
      Liste liste = listenkandidatur.getListe();

      if (liste != null) {
        wahlvorschlagStimmzettelPosition = liste.getStimmzettelPosition(getGebiet(), getEntityAufStimmzettelDaten());
      }
    }

    String kennung = getStimmeingabenGruppeStimmenGroupKey(template);
    String bezeichnung = getStimmeingabenGruppeStimmenGroupHeader(template);

    Stimmeingabe stimmeingabeListenstimme = stimmeingabeListenkandidatur;
    String stimmeingabeListenstimmeKennung = stimmeingabeListenkandidaturStimmen.getStimmeingabeKennung();
    String stimmeingabeListenstimmeBezeichnung = stimmeingabeListenkandidaturStimmen.getStimmeingabeBezeichnung();
    String stimmeingabeListenstimmeTooltip = stimmeingabeListenkandidaturStimmen.getStimmeingabeTooltip();

    List<Stimmeingabefehler> stimmeingabefehlerListenstimmeLetzterErgebniseingang = stimmeingabeListenkandidaturStimmen.getStimmeingabefehlerLetzterErgebniseingang();

    Stimmeingabe stimmeingabeVergleich = getStimmeingabeErfassenContext().getVergleichErgebniseingangStimmeingabenPerTk().get(stimmeingabeListenkandidatur.getTk());

    return createStimmeingabeGruppeStimmen(template, wahlvorschlagStimmzettelPosition, kennung, bezeichnung, stimmeingabeListenstimme, stimmeingabeListenstimmeKennung,
        stimmeingabeListenstimmeBezeichnung, stimmeingabeListenstimmeTooltip, stimmeingabefehlerListenstimmeLetzterErgebniseingang, stimmeingabeVergleich);
  }

  private StimmeingabeGruppeStimmen asStimmeingabeGruppeStimmenSeparator(StimmeingabeGruppeStimmen template) {
    WahlvorschlagStimmzettelPosition wahlvorschlagStimmzettelPosition = WahlvorschlagStimmzettelPosition.EMPTY;

    String kennung = getStimmeingabenGruppeStimmenGroupKey(template);
    String bezeichnung = getStimmeingabenGruppeStimmenGroupHeader(template);

    Stimmeingabe stimmeingabeListenstimme = null;
    String stimmeingabeListenstimmeKennung = "";
    String stimmeingabeListenstimmeBezeichnung = "";
    String stimmeingabeListenstimmeTooltip = "";

    List<Stimmeingabefehler> stimmeingabefehlerListenstimmeLetzterErgebniseingang = emptyList();

    Stimmeingabe stimmeingabeVergleich = null;

    StimmeingabeGruppeStimmen stimmeingabeGruppeStimmen = createStimmeingabeGruppeStimmen(template, wahlvorschlagStimmzettelPosition, kennung, bezeichnung, stimmeingabeListenstimme,
        stimmeingabeListenstimmeKennung, stimmeingabeListenstimmeBezeichnung, stimmeingabeListenstimmeTooltip, stimmeingabefehlerListenstimmeLetzterErgebniseingang, stimmeingabeVergleich);
    stimmeingabeGruppeStimmen.addRowStyleClass(StimmeingabeStimmen.STYLE_CLASS_SEPARATOR); // ELECTVAPP-100

    return stimmeingabeGruppeStimmen;
  }

  private StimmeingabeGruppeStimmen createStimmeingabeGruppeStimmen(StimmeingabeGruppeStimmen template, WahlvorschlagStimmzettelPosition wahlvorschlagStimmzettelPosition, String kennung,
      String bezeichnung, Stimmeingabe stimmeingabeListenstimme, String stimmeingabeListenstimmeKennung, String stimmeingabeListenstimmeBezeichnung, String stimmeingabeListenstimmeTooltip,
      List<Stimmeingabefehler> stimmeingabefehlerListenstimmeLetzterErgebniseingang, Stimmeingabe stimmeingabeVergleich) {
    return new StimmeingabeGruppeStimmen( //
        wahlvorschlagStimmzettelPosition, kennung, bezeichnung, //

        null, "", "", "", "", emptyList(), null, //

        stimmeingabeListenstimme, template.getStimmeingabeListenstimmeGruppeBezeichnung(), stimmeingabeListenstimmeKennung, stimmeingabeListenstimmeBezeichnung, stimmeingabeListenstimmeTooltip,
        stimmeingabefehlerListenstimmeLetzterErgebniseingang, stimmeingabeVergleich //
    );
  }
}
