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

import static de.ivu.elect.jee.entity.EntityUtil.castTo;
import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.startsWithIgnoreCase;

import java.io.Serializable;
import java.util.function.Predicate;

import de.ivu.elect.business.gruppe.entity.Gruppe;
import de.ivu.elect.business.kandidatur.entity.Direktkandidatur;
import de.ivu.elect.business.kandidatur.entity.Kandidatur;
import de.ivu.elect.business.kandidatur.entity.KandidaturStatus;
import de.ivu.elect.business.kandidatur.entity.Listenkandidatur;
import de.ivu.elect.business.kandidatur.entity.ListenkandidaturArt;
import de.ivu.elect.business.wahlvorschlag.entity.Direktkandidat;
import de.ivu.elect.business.wahlvorschlag.entity.Liste;
import de.ivu.elect.business.wahlvorschlag.entity.Wahlvorschlag;
import de.ivu.elect.business.wahlvorschlag.entity.WahlvorschlagStatus;
import de.ivu.elect.jee.faces.Messages;

public class WaehlerBenannteKandidaturKonfiguration implements Serializable {

  private static final long serialVersionUID = 1L;

  public static final WahlvorschlagStatus WAEHLER_BENANNTE_KANDIDATUR_WAHLVORSCHLAG_STATUS_DEFAULT = WahlvorschlagStatus.ZUGELASSEN;

  public static final KandidaturStatus WAEHLER_BENANNTE_KANDIDATUR_KANDIDATUR_STATUS_DEFAULT = KandidaturStatus.ZUGELASSEN;

  private static final String WAEHLER_BENANNTE_GRUPPE_SCHLUESSEL_DEFAULT = "WBK";

  public static final String MSG_KEY_WAEHLER_BENANNTE_GRUPPE_EINZAHL = "WAEHLER_BENANNTE_GRUPPE.entity.einzahl";

  public static final String MSG_KEY_WAEHLER_BENANNTE_GRUPPE_MEHRZAHL = "WAEHLER_BENANNTE_GRUPPE.entity.mehrzahl";

  public static final String MSG_KEY_WAEHLER_BENANNTE_LISTE_EINZAHL = "WAEHLER_BENANNTE_LISTE.entity.einzahl";

  public static final String MSG_KEY_WAEHLER_BENANNTE_LISTE_MEHRZAHL = "WAEHLER_BENANNTE_LISTE.entity.mehrzahl";

  public static final String MSG_KEY_WAEHLER_BENANNTE_LISTE_KENNWORT_DEFAULT = "WAEHLER_BENANNTE_LISTE.kennwort.default";

  public static final String WAEHLER_BENANNTE_LISTENKANDIDATUR_GRUPPE_SCHLUESSEL = WAEHLER_BENANNTE_GRUPPE_SCHLUESSEL_DEFAULT;

  public static final ListenkandidaturArt WAEHLER_BENANNTE_LISTENKANDIDATUR_LISTENKANDIDATUR_ART_DEFAULT = ListenkandidaturArt.LISTENKANDIDATUR;

  public static final String WAEHLER_BENANNTE_LISTENKANDIDATUR_SONSTIGE_EXTERNE_ID = WAEHLER_BENANNTE_LISTENKANDIDATUR_GRUPPE_SCHLUESSEL + ":SONSTIGE";

  public static final long WAEHLER_BENANNTE_LISTENKANDIDATUR_SONSTIGE_POSITION = 99L;

  public static final String MSG_KEY_WAEHLER_BENANNTE_LISTENKANDIDATUR_SONSTIGE_NAME_DEFAULT = "WAEHLER_BENANNTE_LISTENKANDIDATUR_SONSTIGE.name.default";

  public static final String MSG_KEY_WAEHLER_BENANNTE_LISTENKANDIDATUR_SONSTIGE_BEMERKUNG_DEFAULT = "WAEHLER_BENANNTE_LISTENKANDIDATUR_SONSTIGE.bemerkung.default";

  public static final String MSG_KEY_WAEHLER_BENANNTE_LISTENKANDIDATUR_SONSTIGE_TOOLTIP = "WAEHLER_BENANNTE_KANDIDATUR_SONSTIGE.tooltip";

  public static final String MSG_KEY_WAEHLER_BENANNTE_LISTENKANDIDATUR_SONSTIGE_TOOLTIP_SITZBERECHNUNG = "WAEHLER_BENANNTE_KANDIDATUR_SONSTIGE.tooltip.sitzberechnung";

  public static final String MSG_KEY_WAEHLER_BENANNTE_LISTENKANDIDATUR_EINZAHL = "WAEHLER_BENANNTE_LISTENKANDIDATUR.entity.einzahl";

  public static final String MSG_KEY_WAEHLER_BENANNTE_LISTENKANDIDATUR_MEHRZAHL = "WAEHLER_BENANNTE_LISTENKANDIDATUR.entity.mehrzahl";

  public static final String MSG_KEY_WAEHLER_BENANNTE_LISTENKANDIDATUR_GRUPPE_NAME_DEFAULT = "WAEHLER_BENANNTE_LISTENKANDIDATUR_GRUPPE.name.default";

  public static final String MSG_KEY_WAEHLER_BENANNTE_LISTENKANDIDATUR_GRUPPE_KURZNAME_DEFAULT = "WAEHLER_BENANNTE_LISTENKANDIDATUR_GRUPPE.kurzname.default";

  public static final String WAEHLER_BENANNTE_DIREKTKANDIDATUR_GRUPPE_SCHLUESSEL_PREFIX = WAEHLER_BENANNTE_GRUPPE_SCHLUESSEL_DEFAULT + ":";

  public static final String MSG_KEY_WAEHLER_BENANNTE_DIREKTKANDIDATUR_EINZAHL = "WAEHLER_BENANNTE_DIREKTKANDIDATUR.entity.einzahl";

  public static final String MSG_KEY_WAEHLER_BENANNTE_DIREKTKANDIDATUR_MEHRZAHL = "WAEHLER_BENANNTE_DIREKTKANDIDATUR.entity.mehrzahl";

  public static final String MSG_KEY_WAEHLER_BENANNTE_DIREKTKANDIDATUR_KENNWORT_DEFAULT = "WAEHLER_BENANNTE_DIREKTKANDIDATUR.kennwort.default";

  public static final String WAEHLER_BENANNTE_DIREKTKANDIDATUR_SONSTIGE_EXTERNE_ID = WAEHLER_BENANNTE_LISTENKANDIDATUR_SONSTIGE_EXTERNE_ID;

  public static final String MSG_KEY_WAEHLER_BENANNTE_DIREKTKANDIDATUR_SONSTIGE_NAME_DEFAULT = MSG_KEY_WAEHLER_BENANNTE_LISTENKANDIDATUR_SONSTIGE_NAME_DEFAULT;

  public static final String MSG_KEY_WAEHLER_BENANNTE_DIREKTKANDIDATUR_SONSTIGE_TOOLTIP = MSG_KEY_WAEHLER_BENANNTE_LISTENKANDIDATUR_SONSTIGE_TOOLTIP;

  public static final String MSG_KEY_WAEHLER_BENANNTE_DIREKTKANDIDATUR_SONSTIGE_TOOLTIP_SITZBERECHNUNG = MSG_KEY_WAEHLER_BENANNTE_LISTENKANDIDATUR_SONSTIGE_TOOLTIP_SITZBERECHNUNG;

  public WaehlerBenannteKandidaturKonfiguration() {
    super();
  }

  public boolean isWaehlerBenannterWahlvorschlag(Wahlvorschlag wahlvorschlag) {
    if (wahlvorschlag != null) {
      return wahlvorschlag.isDirektkandidat() && isWaehlerBenannterDirektkandidat(castTo(wahlvorschlag, Direktkandidat.class))
          || wahlvorschlag.isListe() && isWaehlerBenannteListe(castTo(wahlvorschlag, Liste.class));
    }

    return false;
  }

  public boolean isWaehlerBenannterDirektkandidat(Direktkandidat direktkandidat) {
    if (direktkandidat != null) {
      return isWaehlerBenannterDirektkandidatGruppe(direktkandidat.getGruppe());
    }

    return false;
  }

  public boolean isWaehlerBenannterDirektkandidatGruppe(Gruppe gruppe) {
    Predicate<String> schluesselPredicate = schluessel -> startsWithIgnoreCase(schluessel, WAEHLER_BENANNTE_DIREKTKANDIDATUR_GRUPPE_SCHLUESSEL_PREFIX);

    return isWaehlerBenannterWahlvorschlagGruppe(gruppe, schluesselPredicate);
  }

  public boolean isWaehlerBenannteDirektkandidatur(Kandidatur kandidatur) {
    return kandidatur != null && kandidatur.isInstanceOf(Direktkandidatur.class) && isWaehlerBenannterWahlvorschlag(kandidatur.getWahlvorschlag());
  }

  public boolean isWaehlerBenannteDirektkandidaturSonstige(Messages messages, Kandidatur kandidatur) {
    if (isWaehlerBenannteDirektkandidatur(kandidatur)) {
      return equalsIgnoreCase(kandidatur.getExterneId(), WAEHLER_BENANNTE_DIREKTKANDIDATUR_SONSTIGE_EXTERNE_ID)
          || messages != null && equalsIgnoreCase(kandidatur.getFamilienname(), messages.getMessageForMessageKey(MSG_KEY_WAEHLER_BENANNTE_DIREKTKANDIDATUR_SONSTIGE_NAME_DEFAULT));
    }

    return false;
  }

  public String formatWaehlerBenannteDirektkandidaturSonstigeBeschreibung(Messages messages, Direktkandidatur direktkandidatur) {
    if (isWaehlerBenannteDirektkandidaturSonstige(messages, direktkandidatur)) {
      return messages.getMessageForMessageKey(WaehlerBenannteKandidaturKonfiguration.MSG_KEY_WAEHLER_BENANNTE_DIREKTKANDIDATUR_SONSTIGE_TOOLTIP);
    }

    return "";
  }

  public boolean isWaehlerBenannteListe(Liste liste) {
    if (liste != null) {
      return isWaehlerBenannteListeGruppe(liste.getGruppe());
    }

    return false;
  }

  public boolean isWaehlerBenannteListeGruppe(Gruppe gruppe) {
    Predicate<String> schluesselPredicate = schluessel -> equalsIgnoreCase(schluessel, WAEHLER_BENANNTE_LISTENKANDIDATUR_GRUPPE_SCHLUESSEL)
        || /* LEGACY */ equalsIgnoreCase(schluessel, "WAEHLER_BENANNTE_KANDIDATUREN");

    return isWaehlerBenannterWahlvorschlagGruppe(gruppe, schluesselPredicate);
  }

  public boolean isWaehlerBenannteListenkandidatur(Kandidatur kandidatur) {
    return kandidatur != null && kandidatur.isInstanceOf(Listenkandidatur.class) && isWaehlerBenannterWahlvorschlag(kandidatur.getWahlvorschlag());
  }

  public boolean isWaehlerBenannteListenkandidaturSonstige(Messages messages, Kandidatur kandidatur) {
    if (isWaehlerBenannteListenkandidatur(kandidatur)) {
      String externeId = kandidatur.getExterneId();

      return equalsIgnoreCase(externeId, WAEHLER_BENANNTE_LISTENKANDIDATUR_SONSTIGE_EXTERNE_ID) || /* LEGACY */ equalsIgnoreCase(externeId, "WAEHLER_BENANNTE_KANDIDATUR_SONSTIGE");
    }

    return false;
  }

  public String formatWaehlerBenannteListenkandidaturSonstigeBeschreibung(Messages messages, Listenkandidatur listenkandidatur) {
    if (isWaehlerBenannteListenkandidaturSonstige(messages, listenkandidatur)) {
      return messages.getMessageForMessageKey(MSG_KEY_WAEHLER_BENANNTE_LISTENKANDIDATUR_SONSTIGE_TOOLTIP);
    }

    return "";
  }

  private boolean isWaehlerBenannterWahlvorschlagGruppe(Gruppe gruppe, Predicate<String> schluesselPredicate) {
    if (gruppe != null) {
      String schluessel = gruppe.getSchluessel();

      return !gruppe.isSystemGruppe() && isNotBlank(schluessel) && schluesselPredicate.test(schluessel);
    }

    return false;
  }
}
