
package de.ivu.elect.presentation.wahlrechtspruefung;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Named;

import de.ivu.elect.business.kandidatur.boundary.KandidaturExtendedDAO;
import de.ivu.elect.business.kandidatur.entity.Direktkandidatur;
import de.ivu.elect.business.kandidatur.entity.Ersatzkandidatur;
import de.ivu.elect.business.kandidatur.entity.Kandidatur;
import de.ivu.elect.business.kandidatur.entity.KandidaturProperties;
import de.ivu.elect.business.kandidatur.entity.Listenkandidatur;
import de.ivu.elect.business.wahlrechtspruefung.boundary.WahlrechtspruefungSearchParameters;
import de.ivu.elect.business.wahlrechtspruefung.entity.WahlrechtspruefStatus;
import de.ivu.elect.business.wahlrechtspruefung.entity.Wahlrechtspruefung;
import de.ivu.elect.business.wahlrechtspruefung.entity.WahlrechtspruefungProperties.WahlrechtspruefStatusMitLeererAuswahlProperty;
import de.ivu.elect.business.wahlvorschlag.boundary.WahlvorschlagExtendedDAO;
import de.ivu.elect.business.wahlvorschlag.entity.Liste;
import de.ivu.elect.business.wahlvorschlag.entity.Wahlvorschlag;
import de.ivu.elect.jee.faces.PreConditionCheck;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.redirect.Redirect;
import de.ivu.elect.presentation.gebietsbaum.GebietNummerFormatter;
import de.ivu.elect.presentation.security.AbstractGebietSecurityFilter;


import static de.ivu.elect.jee.entity.EntityUtil.castTo;

@Named(AbstractWahlrechtspruefungSearchView.COMPONENT_NAME)
public class WahlrechtspruefungSearchView extends AbstractWahlrechtspruefungSearchView {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient WahlvorschlagExtendedDAO wahlvorschlagExtendedDAO;

  @Inject
  private transient KandidaturExtendedDAO kandidaturExtendedDAO;

  @Inject
  private transient GebietNummerFormatter gebietNummerFormatter;

  public WahlrechtspruefungSearchView() {
    super();
  }

  @PreConditionCheck
  public String checkCondition() {
    if (getWahlvorschlag() == null) {
      addErrorMessage("wahlvorschlag.selected.fuer.pruefung.missing");

      return getStartViewId();
    }

    return null;
  }

  @Override
  protected AbstractGebietSecurityFilter<Wahlrechtspruefung> getGebietSecurityFilter() {
    return KEIN_GEBIET_SECURITY_FILTER;
  }

  @Override
  public int getDefaultPageSize() {
    return getPageSizeShowAll();
  }

  public String getPageTitle() {
    String msgKeyPrefix = "wahlrechtspruefung.search.page.title.";

    if (isListeZuPruefen()) {
      return getMessage(msgKeyPrefix + "liste", getListe().getKurznameAufGebiet(), gebietNummerFormatter.getDarstellung(getListe().getGebiet()));
    } else if (isDirektkandidaturZuPruefen()) {
      Direktkandidatur direktkandidatur = getDirektkandidatur();

      return getMessage(msgKeyPrefix + "direktkandidatur", direktkandidatur.getFamilienname(), direktkandidatur.getRufname());
    } else if (isListenkandidaturZuPruefen()) {
      Listenkandidatur listenkandidatur = getListenkandidatur();
      Liste liste = listenkandidatur.getListe();

      return getMessage(msgKeyPrefix + "listenkandidatur", listenkandidatur.getFamilienname(), listenkandidatur.getRufname(),
          listenkandidatur.getEingereichtePosition(), liste.getKurznameAufGebiet());
    } else if (isErsatzkandidaturZuPruefen()) {
      Ersatzkandidatur ersatzkandidatur = getErsatzkandidatur();

      return getMessage(msgKeyPrefix + "ersatzkandidatur", ersatzkandidatur.getFamilienname(), ersatzkandidatur.getRufname());
    }

    throw new IllegalStateException("Unklar, was hier geprüft werden soll... " + getSearchParameters());
  }

  @Redirect
  public String initialisiereKomplettePruefung(Liste liste) {
    return initialisierePruefung(liste, null, false);
  }

  @Redirect
  public String initialisiereKomplettePruefung(Listenkandidatur listenkandidatur) {
    return initialisierePruefung(listenkandidatur.getListe(), listenkandidatur, false);
  }

  @Redirect
  public String initialisiereKomplettePruefung(Direktkandidatur direktkandidatur) {
    return initialisierePruefung(direktkandidatur.getDirektkandidat(), direktkandidatur, false);
  }

  @Redirect
  public String initialisiereKomplettePruefung(Ersatzkandidatur ersatzkandidatur) {
    return initialisierePruefung(ersatzkandidatur.getWahlvorschlag(), ersatzkandidatur, false);
  }

  private String initialisierePruefung(Wahlvorschlag wahlvorschlag, Kandidatur kandidatur, boolean nurSofortpruefung) {
    return initialisierePruefung(wahlvorschlag, kandidatur, nurSofortpruefung, getDefaultWahlrechtsPruefstatus()); // ELECTMUC-2506
  }

  @Nullable
  protected WahlrechtspruefStatus getDefaultWahlrechtsPruefstatus() {
    return null;
  }

  protected String initialisierePruefung(Wahlvorschlag wahlvorschlag, Kandidatur kandidatur, boolean nurSofortpruefung,
                                         @Nullable WahlrechtspruefStatus wahlrechtspruefStatusInitial) {
    getSearchParameters().setWahlvorschlag(wahlvorschlag);
    getSearchParameters().setKandidatur(kandidatur);
    getSearchParameters().setNurSofortpruefungen(nurSofortpruefung);
    getSearchParameters().setWahlrechtspruefStatus(wahlrechtspruefStatusInitial);

    if (wahlrechtspruefStatusInitial != null) {
      addWarningMessage("wahlrechtspruefung.search.page.message.status.initial", getMessage(wahlrechtspruefStatusInitial));
    }

    return VIEW_ID;
  }

  public boolean isListeZuPruefen() {
    return getWahlvorschlag().isListe() && getKandidatur() == null;
  }

  private Liste getListe() {
    return castTo(getWahlvorschlag(), Liste.class);
  }

  public Wahlvorschlag getWahlvorschlag() {
    return wahlvorschlagExtendedDAO.attach(getSearchParameters().getWahlvorschlag());
  }

  public boolean isDirektkandidaturZuPruefen() {
    Kandidatur kandidatur = getKandidatur();

    return kandidatur != null && kandidatur.isDirektkandidatur();
  }

  private Direktkandidatur getDirektkandidatur() {
    return castTo(getKandidatur(), Direktkandidatur.class);
  }

  public boolean isErsatzkandidaturZuPruefen() {
    Kandidatur kandidatur = getKandidatur();

    return kandidatur != null && kandidatur.isErsatzkandidatur();
  }

  private Ersatzkandidatur getErsatzkandidatur() {
    return castTo(getKandidatur(), Ersatzkandidatur.class);
  }

  public boolean isListenkandidaturZuPruefen() {
    Kandidatur kandidatur = getKandidatur();

    return kandidatur != null && kandidatur.isListenkandidatur();
  }

  protected Listenkandidatur getListenkandidatur() {
    return castTo(getKandidatur(), Listenkandidatur.class);
  }

  public Kandidatur getKandidatur() {
    return kandidaturExtendedDAO.attach(getSearchParameters().getKandidatur());
  }

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

  @Override
  public void presetSearchParameters() {
    // Do nothing.
  }

  @Override
  public void addProperties(FormBuilder formBuilder) {
    boolean isPersonZuPruefen = addReadonlyPruefObjektProperties(formBuilder);

    WahlrechtspruefungSearchParametersProperties wahlrechtspruefungSearchParametersProperties = new WahlrechtspruefungSearchParametersProperties(
        getSearchParameters());

    // NOTE, dass neue Parameter in der Methode WahlrechtspruefungSearchView.reset manuell zurückgesetzt werden müssen!
    if (!isPersonZuPruefen) {
      formBuilder.addProperty(wahlrechtspruefungSearchParametersProperties.getKategorieProperty());
      formBuilder.addProperty(wahlrechtspruefungSearchParametersProperties.getUnterkategorieProperty());
      formBuilder.addProperty(wahlrechtspruefungSearchParametersProperties.getTeilDerSofortpruefungProperty());
      formBuilder.addProperty(wahlrechtspruefungSearchParametersProperties.getWahlrechtlichRelevantProperty());
    }
    formBuilder.addProperty(new WahlrechtspruefStatusMitLeererAuswahlProperty(getSearchParameters().getWahlrechtspruefung()));
  }

  private boolean addReadonlyPruefObjektProperties(FormBuilder formBuilder) {
    // ELECTMUC-495
    if (isListenkandidaturZuPruefen() || isDirektkandidaturZuPruefen() || isErsatzkandidaturZuPruefen()) {
      KandidaturProperties kandidaturProperties = getKandidatur().getProperties();

      formBuilder.addProperty(kandidaturProperties.getTitelProperty()).readonly();
      formBuilder.addProperty(kandidaturProperties.getAkademischerGradUnformatiertProperty()).readonly();

      formBuilder.addProperty(kandidaturProperties.getFamiliennameProperty()).readonly();
      formBuilder.addProperty(kandidaturProperties.getRufnameProperty()).readonly();
      formBuilder.addProperty(kandidaturProperties.getVornamenProperty()).readonly();

      formBuilder.addProperty(kandidaturProperties.getBerufUnformatiertProperty()).readonly();
      formBuilder.addProperty(kandidaturProperties.getEhrenamtUnformatiertProperty()).readonly();

      if (isListenkandidaturZuPruefen()) {
        formBuilder.addProperty(getListenkandidatur().getProperties().getAnzahlNennungenProperty()).readonly();
      }
      return true;
    }
    return false;
  }

  @Override
  @Redirect
  public String reset() {
    // NOTE, dass dieser View laut msc speziell und insbesondere nicht mit @ViewAccessScoped annotiert ist. Die
    // Suchparameter werden deshalb nicht per AbstractSearchParameters.reset sondern manuell zurückgesetzt!
    WahlrechtspruefungSearchParameters wahlrechtspruefungSearchParameters = getSearchParameters();

    presetSearchParameters();

    wahlrechtspruefungSearchParameters.setKategorie(null);
    wahlrechtspruefungSearchParameters.setUnterkategorie(null);
    wahlrechtspruefungSearchParameters.setNurSofortpruefungen(false);
    wahlrechtspruefungSearchParameters.setWahlrechtlichRelevant(false);
    wahlrechtspruefungSearchParameters.setWahlrechtspruefStatus(null);

    wahlrechtspruefungSearchParameters.setInitialized(true);

    resetSearchParametersModel();

    return getViewId();
  }

  public List<String> getDialogTemplates() {
    return new ArrayList<>(); // ELECT-10729
  }
}
