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

import java.util.Collection;

import de.ivu.elect.business.ergebnis.entity.Stimmenart;
import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebiet;
import de.ivu.elect.business.stimmeingabe.boundary.AbstractStimmeingabeReferendumVorlageStimmenModelBuilder;
import de.ivu.elect.business.stimmeingabe.control.AbstractStimmeingabeErfassenLabelGenerator;
import de.ivu.elect.business.stimmeingabe.control.StimmeingabeReferendumOptionStimmenErfassenLabelGenerator;
import de.ivu.elect.business.stimmeingabe.entity.Stimmeingabe;
import de.ivu.elect.business.stimmen.boundary.ReferendumStimmeLabelGenerator;
import de.ivu.elect.business.stimmzettel.entity.EntityAufStimmzettelDaten;
import de.ivu.elect.business.wahl.entity.WahlartErgebnisart;
import de.ivu.elect.business.wahlvorschlag.entity.ReferendumOption;

public abstract class AbstractReferendumVorlageStimmeingabeErfassenLabelGenerator extends AbstractStimmeingabeErfassenLabelGenerator
    implements
      StimmeingabeReferendumOptionStimmenErfassenLabelGenerator {

  private static final long serialVersionUID = 1L;

  protected AbstractReferendumVorlageStimmeingabeErfassenLabelGenerator() {
    super();
  }

  @Override
  public boolean isGruppeHatKennung() {
    return true;
  }

  private ReferendumStimmeLabelGenerator getReferendumStimmeLabelGenerator() {
    return getGruppeStimmeLabelGenerator().getReferendumStimmeLabelGenerator();
  }

  @Override
  public String getGruppeStimmenStimmeingabeGruppeBezeichnung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, Stimmeingabe stimmeingabe, Collection<GruppeImGebiet> gruppenImGebiet) {
    if (stimmeingabe != null) {
      LOG.warn("Zur Stimmeingabe [stimmeingabeTk = {}] kann keine Gruppe Bezeichnung generiert werden", stimmeingabe.getTk());
    }

    return "";
  }

  @Override
  public String getGruppeStimmenKennung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, GruppeImGebiet gruppeImGebiet, WahlartErgebnisart ergebnisart,
      Collection<GruppeImGebiet> gruppenImGebiet) {
    // NOTE, dass nur Referendum Stimmen erfasst werden!
    return getGruppeStimmenKennung(entityAufStimmzettelDaten, gruppeImGebiet, ergebnisart, Stimmenart.REFERENDUM_STIMME, gruppenImGebiet);
  }

  @Override
  public String getGruppeStimmenStimmeingabeKennung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, Stimmeingabe stimmeingabe, Collection<GruppeImGebiet> gruppenImGebiet) {
    if (stimmeingabe != null) {
      // NOTE, dass diese Implementierung anhand vorhandener Legacy-Tests entstanden ist! Diese testen bspw., dass es bei Referenden keine Gruppen-Stimmeingaben gibt.
      LOG.warn("Zur Stimmeingabe [stimmeingabeTk = {}] kann keine Kennung generiert werden", stimmeingabe.getTk());
    }

    return "";
  }

  @Override
  public String getGruppeStimmenKennung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, GruppeImGebiet gruppeImGebiet, WahlartErgebnisart ergebnisart, Stimmenart stimmenart,
      Collection<GruppeImGebiet> gruppenImGebiet) {
    if (gruppeImGebiet != null && stimmenart != null) {
      if (gruppeImGebiet.isSystemGruppe()) {
        // NOTE, dass diese Implementierung anhand vorhandener Legacy-Tests entstanden ist! Diese testen bspw., dass es bei Referenden keine Gruppen-Stimmeingaben gibt.
      } else if (gruppenImGebiet.contains(gruppeImGebiet)) {
        if (stimmenart.isReferendumStimmenart()) {
          return getReferendumStimmeLabelGenerator().formatReferendumVorlageKennung(entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet);
        }
      }
    }

    LOG.warn("Zur GruppeImGebiet [{}] und Stimmenart [{}] kann keine Kennung generiert werden", gruppeImGebiet, stimmenart);

    return "";
  }

  @Override
  public String getGruppeStimmenBezeichnung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, GruppeImGebiet gruppeImGebiet, WahlartErgebnisart ergebnisart,
      Collection<GruppeImGebiet> gruppenImGebiet) {
    // NOTE, dass nur Referendum Stimmen erfasst werden!
    return getGruppeStimmenBezeichnung(entityAufStimmzettelDaten, gruppeImGebiet, ergebnisart, Stimmenart.REFERENDUM_STIMME, gruppenImGebiet);
  }

  @Override
  public String getGruppeStimmenStimmeingabeBezeichnung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, Stimmeingabe stimmeingabe, Collection<GruppeImGebiet> gruppenImGebiet) {
    if (stimmeingabe != null) {
      // NOTE, dass diese Implementierung anhand vorhandener Legacy-Tests entstanden ist! Diese testen bspw., dass es bei Referenden keine Gruppen-Stimmeingaben gibt.
      LOG.warn("Zur Stimmeingabe [stimmeingabeTk = {}] kann keine Kennung generiert werden", stimmeingabe.getTk());
    }

    return "";
  }

  @Override
  public String getGruppeStimmenBezeichnung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, GruppeImGebiet gruppeImGebiet, WahlartErgebnisart ergebnisart, Stimmenart stimmenart,
      Collection<GruppeImGebiet> gruppenImGebiet) {
    if (gruppeImGebiet != null && stimmenart != null) {
      if (gruppeImGebiet.isSystemGruppe()) {
        // NOTE, dass diese Implementierung anhand vorhandener Legacy-Tests entstanden ist! Diese testen bspw., dass es bei Referenden keine Gruppen-Stimmeingaben gibt.
      } else if (gruppenImGebiet.contains(gruppeImGebiet)) {
        if (stimmenart.isReferendumStimmenart()) {
          return getReferendumStimmeLabelGenerator().formatReferendumVorlageBezeichnung(entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet);
        }
      }
    }

    LOG.warn("Zur GruppeImGebiet [{}] und Stimmenart [{}] kann keine Kennung generiert werden", gruppeImGebiet, stimmenart);

    return "";
  }

  @Override
  public String getReferendumOptionStimmenStimmeingabeKennung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, Stimmeingabe stimmeingabe, Collection<GruppeImGebiet> gruppenImGebiet) {
    if (stimmeingabe != null) {
      GruppeImGebiet gruppeImGebiet = stimmeingabe.getGruppeImGebiet();

      if (gruppeImGebiet != null) {
        if (gruppeImGebiet.isSystemGruppe()) {
          // NOTE, dass diese Implementierung anhand vorhandener Legacy-Tests entstanden ist! Diese testen bspw., dass es bei Referenden keine Gruppen-Stimmeingaben gibt.
        } else if (gruppenImGebiet.contains(gruppeImGebiet)) {
          if (isStimmeingabeReferendumOption(stimmeingabe)) {
            return getReferendumOptionStimmenKennung(entityAufStimmzettelDaten, stimmeingabe.getReferendumOption(), gruppeImGebiet, gruppenImGebiet);
          }

          if (isStimmeingabeZwischensummeAnzahlUngueltigeGesamt(stimmeingabe)) {
            return getReferendumStimmeLabelGenerator().formatReferendumOptionStimmeAnzahlUngueltigeGesamtKennung(entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet);
          }

          if (isStimmeingabeZwischensummeAnzahlGueltigeGesamt(stimmeingabe)) {
            return getReferendumStimmeLabelGenerator().formatReferendumOptionStimmeAnzahlGueltigeGesamtKennung(entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet);
          }

          if (isStimmeingabeZwischensummeAnzahlUebrigeGesamt(stimmeingabe)) {
            return getReferendumStimmeLabelGenerator().formatReferendumOptionStimmeAnzahlUebrigeGesamtKennung(entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet);
          }

          if (isStimmeingabeZwischensummeAnzahlAbgegebenGesamt(stimmeingabe)) {
            return getReferendumStimmeLabelGenerator().formatReferendumOptionStimmeAnzahlAbgegebeneGesamtKennung(entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet);
          }
        }

        LOG.warn("Zur Stimmeingabe [stimmeingabeTk = {}] kann keine Kennung generiert werden", stimmeingabe.getTk());
      }
    }

    return "";
  }

  @Override
  public String getReferendumOptionStimmenKennung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, ReferendumOption referendumOption, GruppeImGebiet gruppeImGebiet,
      Collection<GruppeImGebiet> gruppenImGebiet) {
    if (referendumOption != null) {
      if (gruppeImGebiet != null) {
        if (gruppeImGebiet.isSystemGruppe()) {
          // NOTE, dass diese Implementierung anhand vorhandener Legacy-Tests entstanden ist! Diese testen bspw., dass es bei Referenden keine Gruppen-Stimmeingaben gibt.
        } else if (gruppenImGebiet.contains(gruppeImGebiet)) {
          return getReferendumStimmeLabelGenerator().formatReferendumOptionStimmeAnzahlGueltigeKennung(entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet, referendumOption);
        }
      }

      LOG.warn("Zur ReferendumOption [referendumOption = {}, gruppeImGebiet = {}] kann keine Kennung generiert werden", referendumOption, gruppeImGebiet);
    }

    return "";
  }

  @Override
  public String getReferendumOptionStimmenStimmeingabeBezeichnung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, Stimmeingabe stimmeingabe, Collection<GruppeImGebiet> gruppenImGebiet) {
    if (stimmeingabe != null) {
      GruppeImGebiet gruppeImGebiet = stimmeingabe.getGruppeImGebiet();

      if (gruppeImGebiet != null) {
        if (gruppeImGebiet.isSystemGruppe()) {
          // NOTE, dass diese Implementierung anhand vorhandener Legacy-Tests entstanden ist! Diese testen bspw., dass es bei Referenden keine Gruppen-Stimmeingaben gibt.
        } else if (gruppenImGebiet.contains(gruppeImGebiet)) {
          if (isStimmeingabeReferendumOption(stimmeingabe)) {
            return getReferendumStimmeLabelGenerator().formatReferendumOptionStimmeAnzahlGueltigeBezeichnung(entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet,
                stimmeingabe.getReferendumOption());
          }

          if (isStimmeingabeZwischensummeAnzahlUngueltigeGesamt(stimmeingabe)) {
            return getReferendumStimmeLabelGenerator().formatReferendumOptionStimmeAnzahlUngueltigeGesamtBezeichnung(entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet);
          }

          if (isStimmeingabeZwischensummeAnzahlGueltigeGesamt(stimmeingabe)) {
            return getReferendumStimmeLabelGenerator().formatReferendumOptionStimmeAnzahlGueltigeGesamtBezeichnung(entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet);
          }

          if (isStimmeingabeZwischensummeAnzahlUebrigeGesamt(stimmeingabe)) {
            return getReferendumStimmeLabelGenerator().formatReferendumOptionStimmeAnzahlUebrigeGesamtBezeichnung(entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet);
          }

          if (isStimmeingabeZwischensummeAnzahlAbgegebenGesamt(stimmeingabe)) {
            return getReferendumStimmeLabelGenerator().formatReferendumOptionStimmeAnzahlGesamtAbgegebenBezeichnung(entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet);
          }
        }

        LOG.warn("Zur Stimmeingabe [stimmeingabeTk = {}] kann keine Bezeichnung generiert werden", stimmeingabe.getTk());
      }
    }

    return "";
  }

  @Override
  public String getReferendumOptionStimmenBezeichnung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, ReferendumOption referendumOption, GruppeImGebiet gruppeImGebiet,
      Collection<GruppeImGebiet> gruppenImGebiet) {
    if (referendumOption != null) {
      if (gruppeImGebiet != null) {
        if (gruppeImGebiet.isSystemGruppe()) {
          // NOTE, dass diese Implementierung anhand vorhandener Legacy-Tests entstanden ist! Diese testen bspw., dass es bei Referenden keine Gruppen-Stimmeingaben gibt.
        } else if (gruppenImGebiet.contains(gruppeImGebiet)) {
          return getReferendumStimmeLabelGenerator().getReferendumOptionKurzbezeichnung(referendumOption);
        }
      }

      LOG.warn("Zur ReferendumOption [referendumOption = {}, gruppeImGebiet = {}] kann keine Bezeichnung generiert werden", referendumOption, gruppeImGebiet);
    }

    return "";
  }

  @Override
  public boolean isStimmeingabeZwischensummeAnzahlAbgegebenGesamt(Stimmeingabe stimmeingabe) {
    return isStimmeingabeZwischensumme(stimmeingabe, AbstractStimmeingabeReferendumVorlageStimmenModelBuilder.GRUPPE_STIMMEN_ABGEGEBEN_GESAMT_ZWISCHENSUMME_INDEX);
  }

  @Override
  public boolean isStimmeingabeZwischensummeAnzahlUngueltigeGesamt(Stimmeingabe stimmeingabe) {
    return isStimmeingabeZwischensumme(stimmeingabe, AbstractStimmeingabeReferendumVorlageStimmenModelBuilder.GRUPPE_STIMMEN_UNGUELTIGE_GESAMT_ZWISCHENSUMME_INDEX);
  }

  @Override
  public boolean isStimmeingabeZwischensummeAnzahlGueltigeGesamt(Stimmeingabe stimmeingabe) {
    return isStimmeingabeZwischensumme(stimmeingabe, AbstractStimmeingabeReferendumVorlageStimmenModelBuilder.GRUPPE_STIMMEN_GUELTIGE_GESAMT_ZWISCHENSUMME_INDEX);
  }

  @Override
  public boolean isStimmeingabeZwischensummeAnzahlUebrigeGesamt(Stimmeingabe stimmeingabe) {
    return isStimmeingabeZwischensumme(stimmeingabe, AbstractStimmeingabeReferendumVorlageStimmenModelBuilder.GRUPPE_STIMMEN_UEBRIGE_GESAMT_ZWISCHENSUMME_INDEX);
  }
}
