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

import java.text.MessageFormat;
import java.util.Collection;

import de.ivu.elect.business.ergebnis.entity.Stimmenart;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.gruppeimgebiet.entity.GruppeImGebiet;
import de.ivu.elect.business.kandidatur.boundary.WaehlerBenannteKandidaturKonfiguration;
import de.ivu.elect.business.kandidatur.entity.Direktkandidatur;
import de.ivu.elect.business.kandidatur.entity.KandidaturStimmzettelPersonendaten;
import de.ivu.elect.business.stimmzettel.entity.EntityAufStimmzettelDaten;
import de.ivu.elect.business.wahlvorschlag.entity.Direktkandidat;
import de.ivu.elect.business.wahlvorschlag.entity.WahlvorschlagStimmzettelPosition;

public class DirektstimmeLabelGenerator extends AbstractStimmeLabelGenerator {

  private static final long serialVersionUID = 1L;

  protected static final String MSG_KEY_INFIX_DIREKTSTIMME = Stimmenart.DIREKTSTIMME.name();

  public DirektstimmeLabelGenerator() {
    super();
  }

  public DirektstimmeLabelGenerator(StimmeLabelMessages stimmeLabelMessages, WaehlerBenannteKandidaturKonfiguration waehlerBenannteKandidaturKonfiguration) {
    super(stimmeLabelMessages, waehlerBenannteKandidaturKonfiguration);
  }

  public String formatDirektstimmeAnzahlUngueltigeGesamtKennung(GruppeImGebiet gruppeImGebiet, Collection<GruppeImGebiet> gruppenImGebiet) {
    return formatDirektstimmeAnzahlUngueltigeGesamtKennung(gruppeImGebiet.getGebiet());
  }

  public String formatDirektstimmeAnzahlUngueltigeGesamtKennung(Gebiet gebiet) {
    return getDirektstimmeAnzahlUngueltigeGesamtKennung(gebiet);
  }

  protected String getDirektstimmeAnzahlUngueltigeGesamtKennung(Gebiet gebiet) {
    String msgKeyInfix = MSG_KEY_INFIX_DIREKTSTIMME + ".ANZAHL." + MSG_KEY_INFIX_UNGUELTIGE + "." + MSG_KEY_INFIX_GESAMT;

    return getKennungOrDefault(gebiet, msgKeyInfix, "C");
  }

  public String formatDirektstimmeAnzahlUngueltigeGesamtBezeichnung(GruppeImGebiet gruppeImGebiet, Collection<GruppeImGebiet> gruppenImGebiet) {
    return getDirektstimmeAnzahlUngueltigeGesamtBezeichnung(gruppeImGebiet.getGebiet());
  }

  protected String getDirektstimmeAnzahlUngueltigeGesamtBezeichnung(Gebiet gebiet) {
    String defaultValue = "Ungültige Direktstimmen";

    if (isSystemGruppeUngueltigeErfasstAlsStimmzettel(gebiet)) {
      defaultValue = "Ungültige Stimmzettel";
    }

    String msgKeyInfix = MSG_KEY_INFIX_DIREKTSTIMME + ".ANZAHL." + MSG_KEY_INFIX_UNGUELTIGE + "." + MSG_KEY_INFIX_GESAMT;

    return getBezeichnungOrDefault(gebiet, msgKeyInfix, defaultValue);
  }

  public String formatDirektstimmeAnzahlGueltigeGesamtKennung(GruppeImGebiet gruppeImGebiet, Collection<GruppeImGebiet> gruppenImGebiet) {
    return formatDirektstimmeAnzahlGueltigeGesamtKennung(gruppeImGebiet.getGebiet());
  }

  public String formatDirektstimmeAnzahlGueltigeGesamtKennung(Gebiet gebiet) {
    return getDirektstimmeAnzahlGueltigeGesamtKennung(gebiet);
  }

  protected String getDirektstimmeAnzahlGueltigeGesamtKennung(Gebiet gebiet) {
    String msgKeyInfix = MSG_KEY_INFIX_DIREKTSTIMME + ".ANZAHL." + MSG_KEY_INFIX_GUELTIGE + "." + MSG_KEY_INFIX_GESAMT;

    return getKennungOrDefault(gebiet, msgKeyInfix, "D");
  }

  public String formatDirektstimmeAnzahlGueltigeGesamtBezeichnung(GruppeImGebiet gruppeImGebiet, Collection<GruppeImGebiet> gruppenImGebiet) {
    return getDirektstimmeAnzahlGueltigeGesamtBezeichnung(gruppeImGebiet.getGebiet());
  }

  protected String getDirektstimmeAnzahlGueltigeGesamtBezeichnung(Gebiet gebiet) {
    String defaultValue = "Gültige Direktstimmen";

    if (isSystemGruppeGueltigeErfasstAlsStimmzettel(gebiet)) {
      defaultValue = "Gültige Stimmzettel";
    }

    String msgKeyInfix = MSG_KEY_INFIX_DIREKTSTIMME + ".ANZAHL." + MSG_KEY_INFIX_GUELTIGE + "." + MSG_KEY_INFIX_GESAMT;

    return getBezeichnungOrDefault(gebiet, msgKeyInfix, defaultValue);
  }

  public String formatDirektstimmeAnzahlGueltigeGruppeBezeichnung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, GruppeImGebiet gruppeImGebiet, Collection<GruppeImGebiet> gruppenImGebiet) {
    if (gruppeImGebiet.isSystemGruppe()) {
      return "";
    }

    if (!gruppeImGebiet.isParteiWaehlergruppeOderVereinigung()) {
      return getMessage(gruppeImGebiet.getGruppeArt());
    }

    return gruppeImGebiet.getGruppe().getKurzname();
  }

  public String formatDirektstimmeAnzahlGueltigeKennung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, GruppeImGebiet gruppeImGebiet, Collection<GruppeImGebiet> gruppenImGebiet) {
    return formatDirektstimmeAnzahlGueltigeKennung(entityAufStimmzettelDaten, gruppeImGebiet, getWahlvorschlagStimmzettelPosition(entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet));
  }

  public String formatDirektstimmeAnzahlGueltigeKennung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, GruppeImGebiet gruppeImGebiet,
      WahlvorschlagStimmzettelPosition wahlvorschlagStimmzettelPosition) {
    if (isGruppeImGebietFuerWaehlerBenannteKandidaturen(gruppeImGebiet)) {
      return formatDirektstimmeAnzahlGueltigeFuerWaehlerBenannteKandidaturenKennung(entityAufStimmzettelDaten, gruppeImGebiet, wahlvorschlagStimmzettelPosition);
    }

    return format(getDirektstimmeAnzahlGueltigeKennung(gruppeImGebiet.getGebiet()), entityAufStimmzettelDaten, gruppeImGebiet, wahlvorschlagStimmzettelPosition);
  }

  private String formatDirektstimmeAnzahlGueltigeFuerWaehlerBenannteKandidaturenKennung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, GruppeImGebiet gruppeImGebiet,
      WahlvorschlagStimmzettelPosition wahlvorschlagStimmzettelPosition) {
    return "";
  }

  protected String getDirektstimmeAnzahlGueltigeKennung(Gebiet gebiet) {
    String msgKeyInfix = MSG_KEY_INFIX_DIREKTSTIMME + ".ANZAHL." + MSG_KEY_INFIX_GUELTIGE;

    return getKennungOrDefault(gebiet, msgKeyInfix, "D{0}");
  }

  public String formatDirektstimmeAnzahlGueltigeBezeichnung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, GruppeImGebiet gruppeImGebiet, Collection<GruppeImGebiet> gruppenImGebiet) {
    return format(getDirektstimmeAnzahlGueltigeBezeichnung(gruppeImGebiet.getGebiet()), entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet);
  }

  protected String getDirektstimmeAnzahlGueltigeBezeichnung(Gebiet gebiet) {
    String msgKeyInfix = MSG_KEY_INFIX_DIREKTSTIMME + ".ANZAHL." + MSG_KEY_INFIX_GUELTIGE;

    return getBezeichnungOrDefault(gebiet, msgKeyInfix, "{1}");
  }

  public String formatDirektstimmeAnzahlAbgegebeneKennung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, GruppeImGebiet gruppeImGebiet, Collection<GruppeImGebiet> gruppenImGebiet) {
    return format(getDirektstimmeAnzahlAbgegebeneKennung(gruppeImGebiet.getGebiet()), entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet);
  }

  protected String getDirektstimmeAnzahlAbgegebeneKennung(Gebiet gebiet) {
    String msgKeyInfix = MSG_KEY_INFIX_DIREKTSTIMME + ".ANZAHL." + MSG_KEY_INFIX_ABGEGEBENE;

    return getKennungOrDefault(gebiet, msgKeyInfix, "");
  }

  protected String getDirektstimmeAnzahlAbgegebeneBezeichnung(Gebiet gebiet) {
    String defaultValue = "Abgegebene Direktstimmen insgesamt";

    if (isSystemGruppeGueltigeErfasstAlsStimmzettel(gebiet)) {
      if (isSystemGruppeUngueltigeErfasstAlsStimmzettel(gebiet)) {
        defaultValue = "Abgegebene Stimmzettel insgesamt";
      } else {
        defaultValue = "";
      }
    }

    String msgKeyInfix = MSG_KEY_INFIX_DIREKTSTIMME + ".ANZAHL." + MSG_KEY_INFIX_ABGEGEBENE;

    return getBezeichnungOrDefault(gebiet, msgKeyInfix, defaultValue);
  }

  public String formatDirektstimmeAnzahlAbgegebeneGesamtKennung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, GruppeImGebiet gruppeImGebiet, Collection<GruppeImGebiet> gruppenImGebiet) {
    return format(getDirektstimmeAnzahlAbgegebeneGesamtKennung(gruppeImGebiet.getGebiet()), entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet);
  }

  protected String getDirektstimmeAnzahlAbgegebeneGesamtKennung(Gebiet gebiet) {
    String msgKeyInfix = MSG_KEY_INFIX_DIREKTSTIMME + ".ANZAHL." + MSG_KEY_INFIX_ABGEGEBENE + "." + MSG_KEY_INFIX_GESAMT;

    return getKennungOrDefault(gebiet, msgKeyInfix, "");
  }

  public String formatDirektstimmeAnzahlAbgegebeneGesamtBezeichnung(EntityAufStimmzettelDaten entityAufStimmzettelDaten, GruppeImGebiet gruppeImGebiet, Collection<GruppeImGebiet> gruppenImGebiet) {
    return format(getDirektstimmeAnzahlAbgegebeneGesamtBezeichnung(gruppeImGebiet.getGebiet()), entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet);
  }

  protected String getDirektstimmeAnzahlAbgegebeneGesamtBezeichnung(Gebiet gebiet) {
    String defaultValue = "Abgegebene Direktstimmen insgesamt";

    if (isSystemGruppeGueltigeErfasstAlsStimmzettel(gebiet)) {
      if (isSystemGruppeUngueltigeErfasstAlsStimmzettel(gebiet)) {
        defaultValue = "Abgegebene Stimmzettel insgesamt";
      } else {
        defaultValue = "";
      }
    }

    String msgKeyInfix = MSG_KEY_INFIX_DIREKTSTIMME + ".ANZAHL." + MSG_KEY_INFIX_ABGEGEBENE + "." + MSG_KEY_INFIX_GESAMT;

    return getBezeichnungOrDefault(gebiet, msgKeyInfix, defaultValue);
  }

  @Override
  public String getWahlvorschlagStimmzettelKurzname(EntityAufStimmzettelDaten entityAufStimmzettelDaten, GruppeImGebiet gruppeImGebiet) {
    Direktkandidat direktkandidat = gruppeImGebiet.getErstenDirektkandidatAbgeleitet(entityAufStimmzettelDaten);

    if (direktkandidat != null) {
      return getDirektkandidaturStimmzettelName(entityAufStimmzettelDaten, direktkandidat.getDirektkandidatur()).getName();
    }

    return super.getWahlvorschlagStimmzettelKurzname(entityAufStimmzettelDaten, gruppeImGebiet);
  }

  public KandidaturStimmzettelPersonendaten getDirektkandidaturStimmzettelName(EntityAufStimmzettelDaten entityAufStimmzettelDaten, Direktkandidatur direktkandidatur) {
    if (direktkandidatur != null) {
      return direktkandidatur.getStimmzettelPersonendaten(entityAufStimmzettelDaten);
    }

    return KandidaturStimmzettelPersonendaten.EMPTY;
  }

  private String format(String pattern, EntityAufStimmzettelDaten entityAufStimmzettelDaten, GruppeImGebiet gruppeImGebiet, Collection<GruppeImGebiet> gruppenImGebiet) {
    return format(pattern, entityAufStimmzettelDaten, gruppeImGebiet, getWahlvorschlagStimmzettelPosition(entityAufStimmzettelDaten, gruppeImGebiet, gruppenImGebiet));
  }

  private String format(String pattern, EntityAufStimmzettelDaten entityAufStimmzettelDaten, GruppeImGebiet gruppeImGebiet, WahlvorschlagStimmzettelPosition wahlvorschlagStimmzettelPosition) {
    return format(pattern, wahlvorschlagStimmzettelPosition, getWahlvorschlagStimmzettelKurzname(entityAufStimmzettelDaten, gruppeImGebiet));
  }

  private String format(String pattern, WahlvorschlagStimmzettelPosition wahlvorschlagStimmzettelPosition, String wahlvorschlagStimmzettelKurzname) {
    return MessageFormat.format(pattern, fixNullToEmpty(wahlvorschlagStimmzettelPosition), fixNullToEmpty(wahlvorschlagStimmzettelKurzname));
  }
}
