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

import de.ivu.elect.business.ergebnis.entity.Ergebnisart;
import de.ivu.elect.business.kandidatur.entity.Kandidatur;
import de.ivu.elect.business.kandidatur.entity.KandidaturStatus;
import de.ivu.elect.business.kandidatur.entity.WaehlerBenannteKandidaturen;
import de.ivu.elect.business.pruefung.boundary.ZulassungPruefer;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.Zulassungspruefung;
import de.ivu.elect.business.wahlvorschlag.entity.Wahlvorschlag;
import de.ivu.elect.business.wahlvorschlag.entity.WahlvorschlagStatus;

public class WahlZulassungspruefung {

  private final Zulassungspruefung zulassungspruefung;

  private final ZulassungPruefer zulassungPruefer;

  private final boolean zulassungPrueferAktiviert;

  public WahlZulassungspruefung(Wahl wahl, ZulassungPruefer zulassungPruefer) {
    this(wahl.getWahlart().getZulassungspruefung(), zulassungPruefer);
  }

  public WahlZulassungspruefung(Zulassungspruefung zulassungspruefung, ZulassungPruefer zulassungPruefer) {
    super();

    this.zulassungspruefung = zulassungspruefung;

    this.zulassungPruefer = zulassungPruefer;
    this.zulassungPrueferAktiviert = zulassungspruefung.isAktiviert();
  }

  public boolean isZulassungMitPruefkriterienDurchfuehrbar() {
    return isZulassungBearbeitbar(); // ELECT-9119
  }

  public boolean isZulassungMitPruefkriterienZulaessig(Wahlvorschlag wahlvorschlag) {
    return isZulassungMitPruefkriterienDurchfuehrbar();
  }

  public boolean isZulassungMitPruefkriterienZulaessig(Kandidatur kandidatur) {
    return isZulassungMitPruefkriterienDurchfuehrbar();
  }

  public boolean isZulassungBearbeitbar() {
    return zulassungspruefung.isNichtzulassenMoeglich() || zulassungspruefung.isNichtzulassenNachtraeglichMoeglich();
  }

  public boolean isZulassungBestaetigenZulaessig(Wahlvorschlag wahlvorschlag) {
    return isWahlvorschlagStatusAenderbar(wahlvorschlag, WahlvorschlagStatus.ZUGELASSEN) && (!zulassungPrueferAktiviert || getZulassungPruefer().isZulassenErlaubt(wahlvorschlag));
  }

  public boolean isZulassungAblehnenZulaessig(Wahlvorschlag wahlvorschlag) {
    return isWahlvorschlagStatusAenderbar(wahlvorschlag, WahlvorschlagStatus.NICHT_ZUGELASSEN) && zulassungspruefung.isNichtzulassenMoeglich();
  }

  public boolean isZulassungZuruecksetzenZulaessig(Wahlvorschlag wahlvorschlag) {
    return zulassungPrueferAktiviert && isWahlvorschlagStatusAenderbar(wahlvorschlag, WahlvorschlagStatus.OFFEN);
  }

  public boolean isZulassungAufhebenKeineZulassungsfaehigkeitBeimZulassungsausschussZulaessig(Wahlvorschlag wahlvorschlag) {
    return isZulassungAufhebenZulaessig(wahlvorschlag, WahlvorschlagStatus.NICHT_MEHR_ZUGELASSEN_WEIL_ZULASSUNGSFAEHIGKEIT_VOR_ZULASSUNGSAUSSCHUSS_NICHT_VORLAG);
  }

  public boolean isZulassungAufhebenKeineZulassungsfaehigkeitNachZulassungsausschussZulaessig(Wahlvorschlag wahlvorschlag) {
    return isZulassungAufhebenZulaessig(wahlvorschlag, WahlvorschlagStatus.NICHT_MEHR_ZUGELASSEN_WEIL_ZULASSUNGSFAEHIGKEIT_NACH_ZULASSUNGSAUSSCHUSS_VERLOREN);
  }

  private boolean isZulassungAufhebenZulaessig(Wahlvorschlag wahlvorschlag, WahlvorschlagStatus wahlvorschlagStatus) {
    return zulassungspruefung.isNichtzulassenNachtraeglichMoeglich() && wahlvorschlag != null && wahlvorschlag.isZugelassen() && !isWahlvorschlagFuerWaehlerBenannteKandidaturen(wahlvorschlag);
  }

  private boolean isWahlvorschlagStatusAenderbar(Wahlvorschlag wahlvorschlag, WahlvorschlagStatus wahlvorschlagStatus) {
    return wahlvorschlag != null && !wahlvorschlagStatus.equals(wahlvorschlag.getWahlvorschlagStatus());
  }

  public WahlvorschlagStatus getZulassungWahlvorschlagStatusInitial() {
    if (zulassungPrueferAktiviert) {
      return WahlvorschlagStatus.OFFEN;
    }

    return WahlvorschlagStatus.ZUGELASSEN;
  }

  public boolean isZulassungBestaetigenZulaessig(Kandidatur kandidatur) {
    if (kandidatur == null || kandidatur.getWahlvorschlag() == null) {
      return false;
    }

    if (!zulassungPrueferAktiviert || getZulassungPruefer().isZulassenErlaubt(kandidatur)) {
      if (kandidatur.isDirektkandidatur()) {
        return isZulassungBestaetigenZulaessig(kandidatur.getWahlvorschlag());
      }

      return isKandidaturStatusAenderbar(kandidatur, KandidaturStatus.ZUGELASSEN);
    }

    return false;
  }

  public boolean isZulassungBestaetigenNachtraeglichAmtsannahmeUnzulaessigZulaessig(Kandidatur kandidatur) {
    if (kandidatur == null || kandidatur.getWahlvorschlag() == null) {
      return false;
    }

    return KandidaturStatus.ZUGELASSEN.equals(kandidatur.getKandidaturStatus()) && isKandidaturStatusAenderbar(kandidatur, KandidaturStatus.ZUGELASSEN_NACHTRAEGLICH_AMTSHINDERNIS_VORHANDEN);
  }

  public boolean isZulassungBestaetigenNachtraeglichAmtsannahmeVerweigertZulaessig(Kandidatur kandidatur) {
    if (kandidatur == null || kandidatur.getWahlvorschlag() == null) {
      return false;
    }

    if (!(kandidatur.isGewaehlt(Ergebnisart.VORLAEUFIG) || kandidatur.isGewaehlt(Ergebnisart.ENDGUELTIG))) {
      return false;
    }

    return KandidaturStatus.ZUGELASSEN.equals(kandidatur.getKandidaturStatus()) && isKandidaturStatusAenderbar(kandidatur, KandidaturStatus.ZUGELASSEN_NACHTRAEGLICH_AMTSANNAHME_VERWEIGERT);
  }

  public boolean isZulassungAblehnenZulaessig(Kandidatur kandidatur) {
    if (kandidatur == null || kandidatur.getWahlvorschlag() == null) {
      return false;
    }

    if (zulassungspruefung.isNichtzulassenMoeglich()) {
      if (kandidatur.isDirektkandidatur()) {
        return isZulassungAblehnenZulaessig(kandidatur.getWahlvorschlag());
      }

      return isKandidaturStatusAenderbar(kandidatur, KandidaturStatus.NICHT_ZUGELASSEN);
    }

    return false;
  }

  public boolean isZulassungZuruecksetzenZulaessig(Kandidatur kandidatur) {
    if (kandidatur == null || kandidatur.getWahlvorschlag() == null) {
      return false;
    }

    if (zulassungPrueferAktiviert) {
      if (kandidatur.isDirektkandidatur()) {
        return isZulassungZuruecksetzenZulaessig(kandidatur.getWahlvorschlag());
      }

      return isKandidaturStatusAenderbar(kandidatur, KandidaturStatus.OFFEN);
    }

    return false;
  }

  public boolean isZulassungAufhebenKeineZulassungsfaehigkeitBeimZulassungsausschussZulaessig(Kandidatur kandidatur) {
    return isZulassungAufhebenZulaessig(kandidatur, KandidaturStatus.NICHT_MEHR_ZUGELASSEN_WEIL_ZULASSUNGSFAEHIGKEIT_VOR_ZULASSUNGSAUSSCHUSS_NICHT_VORLAG);
  }

  public boolean isZulassungAufhebenKeineZulassungsfaehigkeitNachZulassungsausschussZulaessig(Kandidatur kandidatur) {
    return isZulassungAufhebenZulaessig(kandidatur, KandidaturStatus.NICHT_MEHR_ZUGELASSEN_WEIL_ZULASSUNGSFAEHIGKEIT_NACH_ZULASSUNGSAUSSCHUSS_VERLOREN);
  }

  private boolean isZulassungAufhebenZulaessig(Kandidatur kandidatur, KandidaturStatus kandidaturStatus) {
    if (kandidatur == null || kandidatur.getWahlvorschlag() == null) {
      return false;
    }

    if (zulassungspruefung.isNichtzulassenNachtraeglichMoeglich()) {
      if (kandidatur.isDirektkandidatur()) {
        return isZulassungAufhebenZulaessig(kandidatur.getWahlvorschlag(), kandidaturStatus.toWahlvorschlagStatus());
      }

      return kandidatur.isZugelassen() && !isWahlvorschlagFuerWaehlerBenannteKandidaturen(kandidatur.getWahlvorschlag());
    }

    return false;
  }

  private boolean isKandidaturStatusAenderbar(Kandidatur kandidatur, KandidaturStatus kandidaturStatus) {
    return kandidatur != null && !kandidaturStatus.equals(kandidatur.getKandidaturStatus());
  }

  public KandidaturStatus getZulassungKandidaturStatusInitial() {
    if (zulassungPrueferAktiviert) {
      return KandidaturStatus.OFFEN;
    }

    return KandidaturStatus.ZUGELASSEN;
  }

  protected boolean isWahlvorschlagFuerWaehlerBenannteKandidaturen(Wahlvorschlag wahlvorschlag) {
    return WaehlerBenannteKandidaturen.isWaehlerBenannterWahlvorschlag(wahlvorschlag);
  }

  public boolean isZulassungPrueferAktiviert() {
    return zulassungPrueferAktiviert;
  }

  public ZulassungPruefer getZulassungPruefer() {
    return zulassungPruefer;
  }
}
