
package de.ivu.elect.dokumente.ergebnistabelle.referendum;

import static java.util.Objects.isNull;

import java.util.Collection;
import java.util.Locale;

import javax.annotation.Nullable;

import de.ivu.elect.business.ergebnis.control.ErgebnisDaten;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.gruppe.entity.SystemGruppe;
import de.ivu.elect.business.gruppe.entity.SystemGruppeEigenschaften;
import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebiet;
import de.ivu.elect.business.stimmeingabe.control.StimmeingabeReferendumOptionStimmenErfassenLabelGenerator;
import de.ivu.elect.business.wahlvorschlag.entity.ReferendumOption;
import de.ivu.elect.dokumente.ergebnistabelle.AbstractErgebnistabelleDocumentColumn;
import de.ivu.elect.dokumente.ergebnistabelle.ErgebnistabelleCsvDTO;
import de.ivu.elect.jee.faces.Messages;

public class ReferendumErgebnistabelleDocumentColumn extends AbstractErgebnistabelleDocumentColumn.AbstractLongErgebnistabelleDocumentColumn {

  private final ReferendumErgebnistabelleSpaltenSchluessel spaltenSchluessel;

  private final Wahldurchfuehrungsgebiet gebiet;

  private final ErgebnisDaten ergebnisDaten;

  private final StimmeingabeReferendumOptionStimmenErfassenLabelGenerator stimmeingabeReferendumOptionStimmenErfassenLabelGenerator;

  private final String bezeichnung;

  private final SystemGruppeEigenschaften systemGruppeEigenschaften;

  public ReferendumErgebnistabelleDocumentColumn(Locale locale, Messages messages, ReferendumErgebnistabelleSpaltenSchluessel spaltenSchluessel, Wahldurchfuehrungsgebiet gebiet,
      Gruppe referendumVorlage, ErgebnisDaten ergebnisDaten, SystemGruppeEigenschaften systemGruppeEigenschaften,
      StimmeingabeReferendumOptionStimmenErfassenLabelGenerator stimmeingabeReferendumOptionStimmenErfassenLabelGenerator) {
    this(locale, messages, spaltenSchluessel, gebiet, ergebnisDaten, null, systemGruppeEigenschaften, stimmeingabeReferendumOptionStimmenErfassenLabelGenerator);
  }

  public ReferendumErgebnistabelleDocumentColumn(Locale locale, Messages messages, ReferendumErgebnistabelleSpaltenSchluessel spaltenSchluessel, Wahldurchfuehrungsgebiet gebiet,
      ErgebnisDaten ergebnisDaten, @Nullable String bezeichnung, SystemGruppeEigenschaften systemGruppeEigenschaften,
      StimmeingabeReferendumOptionStimmenErfassenLabelGenerator stimmeingabeReferendumOptionStimmenErfassenLabelGenerator) {
    super(locale, messages);

    this.gebiet = gebiet;
    this.ergebnisDaten = ergebnisDaten;
    this.spaltenSchluessel = spaltenSchluessel;
    this.bezeichnung = bezeichnung;

    this.systemGruppeEigenschaften = systemGruppeEigenschaften;
    this.stimmeingabeReferendumOptionStimmenErfassenLabelGenerator = stimmeingabeReferendumOptionStimmenErfassenLabelGenerator;
  }

  @Override
  public Long getLongValue(ErgebnistabelleCsvDTO dto) {
    // TODO: Klasse verschieben und spezialisieren! Generics dafür benötigt?
    if (dto instanceof ReferendumErgebnistabelleCsvDTO) {
      return ((ReferendumErgebnistabelleCsvDTO) dto).getReferendumStimmenAusSpalte(spaltenSchluessel);
    }

    return null;
  }

  @Override
  public String getGruppierung() {
    return spaltenSchluessel.getGruppierung();
  }

  @Override
  public String getBezeichnung() {
    if (isNull(bezeichnung)) {
      GruppeImGebiet gruppeImGebiet = ergebnisDaten.getGruppeImGebiet(spaltenSchluessel.getGruppe(), gebiet);
      Collection<GruppeImGebiet> gruppenImGebiet = ergebnisDaten.getGruppenImGebietZuGebiet(gebiet);
      ReferendumOption referendumOption = spaltenSchluessel.getReferendumOption();

      String referendumOptionBezeichnung = stimmeingabeReferendumOptionStimmenErfassenLabelGenerator.getReferendumOptionStimmenBezeichnung(ergebnisDaten.getEntityAufStimmzettelDaten(),
          referendumOption, gruppeImGebiet, gruppenImGebiet);

      return getMessage("ergebnistabelle.gruppen.stimmen.untergruppierung.fuer.politische.gruppe.stimmenart." + spaltenSchluessel.getStimmenart(), referendumOptionBezeichnung);
    }

    return bezeichnung;
  }

  @Override
  public String getKennung() {
    Gruppe gruppe = spaltenSchluessel.getGruppe();

    // TODO Quick-Fix für ELECTBB-284.
    if (gruppe.isSystemGruppe()) {
      if (gruppe.isGruppeEqualsSystemGruppe(SystemGruppe.GUELTIGE, systemGruppeEigenschaften)) {
        return "H";
      }

      if (gruppe.isGruppeEqualsSystemGruppe(SystemGruppe.UNGUELTIGE, systemGruppeEigenschaften)) {
        return "G";
      }
    }

    GruppeImGebiet gruppeImGebiet = ergebnisDaten.getGruppeImGebiet(gruppe, gebiet);
    Collection<GruppeImGebiet> gruppenImGebiet = ergebnisDaten.getGruppenImGebietZuGebiet(gebiet);
    ReferendumOption referendumOption = spaltenSchluessel.getReferendumOption();

    return stimmeingabeReferendumOptionStimmenErfassenLabelGenerator.getReferendumOptionStimmenKennung(ergebnisDaten.getEntityAufStimmzettelDaten(), referendumOption, gruppeImGebiet, gruppenImGebiet);
  }
}
