
package de.ivu.elect.presentation.ergebnis.exchange;

import de.ivu.elect.business.dokumente.boundary.DokumentVorlageExtendedDAO;
import de.ivu.elect.business.dokumente.entity.DokumentVorlage;
import de.ivu.elect.business.dokumente.entity.DokumentVorlageArt;
import de.ivu.elect.business.dokumente.entity.DokumentVorlageConstants;
import de.ivu.elect.business.ergebnis.boundary.ErgebnisKandidaturenTabellarischDocumentExporter;
import de.ivu.elect.business.ergebnis.boundary.ErgebnisSessionSelect;
import de.ivu.elect.business.ergebnis.control.ErgebnisExchangeContext;
import de.ivu.elect.business.ergebnis.control.ErgebnisdokumentTypExportObject;
import de.ivu.elect.business.ergebnis.control.kandidatur.ErgebnisKandidaturenTabellarischDocumentExportContext;
import de.ivu.elect.business.ergebnis.entity.Ergebnis;
import de.ivu.elect.business.exchange.control.AbstractExporter;
import de.ivu.elect.business.gebietsbaum.boundary.GebietExtendedDAO;
import de.ivu.elect.business.gebietsbaum.control.GebietByNummerComparator;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.jee.presentation.dynamicform.AdvancedDynaFormModel;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.presentation.View;
import de.ivu.elect.presentation.dokumente.DokumentVorlageProperty;
import de.ivu.elect.presentation.exchange.AbstractExportSearchView;
import de.ivu.elect.presentation.hilfe.OnlineHilfeId;

import javax.inject.Inject;
import javax.inject.Named;
import java.util.List;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.sort;

@Named(ErgebnisKandidaturenTabellarischDocumentExportView.COMPONENT_NAME)
@View(viewId = ErgebnisKandidaturenTabellarischDocumentExportView.VIEW_ID, useCase = UseCasePermission.DOKUMENT_ERZEUGEN_NIEDERSCHRIFT)
@OnlineHilfeId(value = "317", mehrfachVergebenOk = true)
public class ErgebnisKandidaturenTabellarischDocumentExportView extends AbstractExportSearchView<ErgebnisdokumentTypExportObject, ErgebnisKandidaturenTabellarischDocumentExportContext> {

  private static final long serialVersionUID = 1L;

  public static final String COMPONENT_NAME = "ergebnisKandidaturenTabellarischDocumentExportView";

  public static final String VIEW_ID = "/ergebnis/ergebnis-kandidaturen-tabellarisch-document-export.xhtml";

  @Inject
  private transient GebietExtendedDAO gebietExtendedDAO;

  @Inject
  private transient DokumentVorlageExtendedDAO dokumentVorlageExtendedDAO;

  @Inject
  private transient ErgebnisSessionSelect ergebnisSessionSelect;

  @Inject
  private transient ErgebnisKandidaturenTabellarischDocumentExporter exporter;

  @Inject
  private transient ErgebnisKandidaturenTabellarischDocumentExportDescription exportDescription;

  private AdvancedDynaFormModel model;

  private ErgebnisDocumentExportViewGebietProperty<Gebiet> auswertungsgebietProperty;

  private ErgebnisDocumentExportViewAnzahlZeilenProSeiteProperty anzahlZeilenProSeiteProperty;

  private DokumentVorlageProperty dokumentVorlageErsteSeiteProperty;

  private ErgebnisDocumentExportViewDokumentVorlageAnzahlSpaltenProperty dokumentVorlageErsteSeiteAnzahlSpaltenProperty;

  private DokumentVorlageProperty dokumentVorlageWeitereSeitenProperty;

  private ErgebnisDocumentExportViewDokumentVorlageAnzahlSpaltenProperty dokumentVorlageWeitereSeitenAnzahlSpaltenProperty;

  public ErgebnisKandidaturenTabellarischDocumentExportView() {
    super();
  }

  public void preRenderView() {
    if (!hasDokumentVorlagen()) {
      addErrorMessage("dokument.vorlage.nicht.hinterlegt", getMessage(getDokumentVorlageArt()));
    }
  }

  private boolean hasDokumentVorlagen() {
    return !getDokumentVorlagen(getSelectedWahl()).isEmpty();
  }

  public AdvancedDynaFormModel getModel() {
    if (model == null) {
      model = createModel();
    }

    return model;
  }

  @Override
  protected void resetExportParameterModel() {
    super.resetExportParameterModel();

    model = null;

    auswertungsgebietProperty = null;

    anzahlZeilenProSeiteProperty = null;

    dokumentVorlageErsteSeiteProperty = null;
    dokumentVorlageErsteSeiteAnzahlSpaltenProperty = null;

    dokumentVorlageWeitereSeitenProperty = null;
    dokumentVorlageWeitereSeitenAnzahlSpaltenProperty = null;
  }

  // Cf. KomErgebnisKandidaturenTabellarischDocumentExportSubView#createExportContext!!!
  private AdvancedDynaFormModel createModel() {
    Wahl wahl = getSelectedWahl();

    boolean seitenartIgnored = !getExportDescription().isWahlartDokumentVorlagenBySeitenart(wahl);
    String seitenartIgnoredLabel = getMessage(DokumentVorlageConstants.MESSAGE_KEY_ENTITY_EINZAHL);

    FormBuilder formBuilder = new FormBuilder();

    formBuilder.addProperty(getAuswertungsgebietProperty());

    formBuilder.addProperty(getAnzahlZeilenProSeiteProperty());

    formBuilder.addSeparator(seitenartIgnored ? DokumentVorlageConstants.MESSAGE_KEY_ENTITY_EINZAHL : DokumentVorlageConstants.MESSAGE_KEY_ENTITY_MEHRZAHL);

    if (seitenartIgnored) {
      // Bspw. zusammenstellung-ergebnisse-v5-V5 Zweite Schnellmeldung Ergebnisse.odt
      formBuilder.addProperty(getDokumentVorlageErsteSeiteProperty()).withLabel(seitenartIgnoredLabel);
      formBuilder.addProperty(getDokumentVorlageErsteSeiteAnzahlSpaltenProperty());
    } else {
      // Bspw. zusammenstellung-ergebnisse-v5-V5 Zweite Schnellmeldung Ergebnisse (Erste Seite).odt, zusammenstellung-ergebnisse-v5-V5 Zweite Schnellmeldung Ergebnisse (Weitere Seiten).odt
      formBuilder.addProperty(getDokumentVorlageErsteSeiteProperty());
      formBuilder.addProperty(getDokumentVorlageErsteSeiteAnzahlSpaltenProperty());

      formBuilder.addProperty(getDokumentVorlageWeitereSeitenProperty());
      formBuilder.addProperty(getDokumentVorlageWeitereSeitenAnzahlSpaltenProperty());
    }

    return formBuilder.createModel();
  }

  private ErgebnisDocumentExportViewGebietProperty<Gebiet> getAuswertungsgebietProperty() {
    if (auswertungsgebietProperty == null) {
      List<Gebiet> auswertungsgebiete = getAuswertungsgebietDefaultValues(getSelectedWahl());
      sort(auswertungsgebiete, GebietByNummerComparator.ASCENDING);

      auswertungsgebietProperty = new ErgebnisDocumentExportViewGebietProperty<>(auswertungsgebiete);
    }

    return auswertungsgebietProperty;
  }

  private List<Gebiet> getAuswertungsgebietDefaultValues(Wahl wahl) {
    return ErgebnisGesamtergebnisTabellarischDocumentExportView.getAuswertungsgebietDefaultValues(wahl, gebietExtendedDAO);
  }

  private ErgebnisDocumentExportViewAnzahlZeilenProSeiteProperty getAnzahlZeilenProSeiteProperty() {
    if (anzahlZeilenProSeiteProperty == null) {
      anzahlZeilenProSeiteProperty = new ErgebnisDocumentExportViewAnzahlZeilenProSeiteProperty(getAnzahlZeilenProSeiteDefaultValue(getSelectedWahl()));
    }

    return anzahlZeilenProSeiteProperty;
  }

  public int getAnzahlZeilenProSeiteDefaultValue(Wahl wahl) {
    return getExportDescription().getWahlartDokumentVorlagenAnzahlZeilenProSeiteDefaultValue(wahl);
  }

  private DokumentVorlageProperty getDokumentVorlageErsteSeiteProperty() {
    if (dokumentVorlageErsteSeiteProperty == null) {
      dokumentVorlageErsteSeiteProperty = new DokumentVorlageProperty("ergebnis.kandidaturen.tabellarisch.exportieren.dokument.vorlage.property.label.erste.seite",
          getDokumentVorlagen(getSelectedWahl()));
    }

    return dokumentVorlageErsteSeiteProperty;
  }

  private ErgebnisDocumentExportViewDokumentVorlageAnzahlSpaltenProperty getDokumentVorlageErsteSeiteAnzahlSpaltenProperty() {
    if (dokumentVorlageErsteSeiteAnzahlSpaltenProperty == null) {
      dokumentVorlageErsteSeiteAnzahlSpaltenProperty = new ErgebnisDocumentExportViewDokumentVorlageAnzahlSpaltenProperty(
          ErgebnisDocumentExportViewDokumentVorlageAnzahlSpaltenProperty.LABEL_MSG_KEY_ANZAHL_SPALTEN_ERSTE_SEITE, getDokumentVorlageErsteSeiteAnzahlSpaltenDefaultValue(getSelectedWahl()));
    }

    return dokumentVorlageErsteSeiteAnzahlSpaltenProperty;
  }

  public int getDokumentVorlageErsteSeiteAnzahlSpaltenDefaultValue(Wahl wahl) {
    return getExportDescription().getWahlartDokumentVorlagenErsteSeiteAnzahlSpaltenDefaultValue(wahl);
  }

  private DokumentVorlageProperty getDokumentVorlageWeitereSeitenProperty() {
    if (dokumentVorlageWeitereSeitenProperty == null) {
      dokumentVorlageWeitereSeitenProperty = new DokumentVorlageProperty("ergebnis.kandidaturen.tabellarisch.exportieren.dokument.vorlage.property.label.andere.seiten",
          getDokumentVorlagen(getSelectedWahl()));
    }

    return dokumentVorlageWeitereSeitenProperty;
  }

  private ErgebnisDocumentExportViewDokumentVorlageAnzahlSpaltenProperty getDokumentVorlageWeitereSeitenAnzahlSpaltenProperty() {
    if (dokumentVorlageWeitereSeitenAnzahlSpaltenProperty == null) {
      dokumentVorlageWeitereSeitenAnzahlSpaltenProperty = new ErgebnisDocumentExportViewDokumentVorlageAnzahlSpaltenProperty(
          ErgebnisDocumentExportViewDokumentVorlageAnzahlSpaltenProperty.LABEL_MSG_KEY_ANZAHL_SPALTEN_WEITERE_SEITEN, getDokumentVorlageWeitereSeitenAnzahlSpaltenDefaultValue(getSelectedWahl()));
    }

    return dokumentVorlageWeitereSeitenAnzahlSpaltenProperty;
  }

  public int getDokumentVorlageWeitereSeitenAnzahlSpaltenDefaultValue(Wahl wahl) {
    return getExportDescription().getWahlartDokumentVorlagenWeitereSeitenAnzahlSpaltenDefaultValue(wahl);
  }

  @Override
  protected AbstractExporter<ErgebnisdokumentTypExportObject, ErgebnisKandidaturenTabellarischDocumentExportContext> getExporter() {
    return exporter;
  }

  @Override
  protected ErgebnisKandidaturenTabellarischDocumentExportContext getContext() {
    Integer anzahlZeilenProSeite = getAnzahlZeilenProSeiteProperty().getValue();

    Integer dokumentVorlageErsteSeiteAnzahlSpalten = getDokumentVorlageErsteSeiteAnzahlSpaltenProperty().getValue();
    Integer dokumentVorlageWeitereSeitenAnzahlSpalten = getDokumentVorlageWeitereSeitenAnzahlSpaltenProperty().getValue();

    boolean documentsCreatedPerStimmzettelgebiet = true;
    boolean documentsCreatedPerGemeinde = false;

    boolean tabellenCreatedPerDatenArt = true;

    boolean tabellenCreatedGemeindenGesamt = true;

    return createContext(new ErgebnisExchangeContext(getSelectedWahl(), getSelectedAuswertungsgebiete(), ErgebnisExchangeContext.KANDIDATUR_FORMAT_DARSTELLUNG_NOT_CONFIGURED),
        ergebnisSessionSelect.getEntity(), documentsCreatedPerStimmzettelgebiet, documentsCreatedPerGemeinde, tabellenCreatedPerDatenArt, tabellenCreatedGemeindenGesamt, anzahlZeilenProSeite,
        getDokumentVorlageErsteSeite(), dokumentVorlageErsteSeiteAnzahlSpalten, getDokumentVorlageWeitereSeiten(), dokumentVorlageWeitereSeitenAnzahlSpalten);
  }

  public ErgebnisKandidaturenTabellarischDocumentExportContext createContext(ErgebnisExchangeContext ergebnisExchangeContext, Ergebnis ergebnis, Boolean documentsCreatedPerStimmzettelgebiet,
      Boolean documentsCreatedPerGemeinde, Boolean tabellenCreatedPerDatenArt, Boolean tabellenCreatedGemeindenGesamt, Integer anzahlZeilenProSeite, DokumentVorlage dokumentVorlageErsteSeite,
      Integer dokumentVorlageErsteSeiteAnzahlSpalten, DokumentVorlage dokumentVorlageWeitereSeiten, Integer dokumentVorlageWeitereSeitenAnzahlSpalten) {
    boolean tabellenCreatedKreiseGesamt = false;

    return new ErgebnisKandidaturenTabellarischDocumentExportContext(ergebnisExchangeContext, ergebnis, getBenutzer(), getMessages(), documentsCreatedPerStimmzettelgebiet, documentsCreatedPerGemeinde,
        tabellenCreatedPerDatenArt, tabellenCreatedKreiseGesamt, tabellenCreatedGemeindenGesamt, anzahlZeilenProSeite, dokumentVorlageErsteSeite, dokumentVorlageErsteSeiteAnzahlSpalten,
        dokumentVorlageWeitereSeiten, dokumentVorlageWeitereSeitenAnzahlSpalten);
  }

  private DokumentVorlage getDokumentVorlageWeitereSeiten() {
    if (getDokumentVorlageWeitereSeitenProperty().getValue() != null) {
      return getDokumentVorlageWeitereSeitenProperty().getValue();
    }

    return getDokumentVorlageErsteSeite();
  }

  private DokumentVorlage getDokumentVorlageErsteSeite() {
    return getDokumentVorlageErsteSeiteProperty().getValue();
  }

  private List<Gebiet> getSelectedAuswertungsgebiete() {
    Gebiet selectedAuswertungsgebiet = getAuswertungsgebietProperty().getValue();

    if (selectedAuswertungsgebiet == null) {
      return getAuswertungsgebietDefaultValues(getSelectedWahl());
    }

    return asList(selectedAuswertungsgebiet);
  }

  private List<DokumentVorlage> getDokumentVorlagen(Wahl wahl) {
    if (wahl == null) {
      return emptyList();
    }
    return dokumentVorlageExtendedDAO.findByWahlAndArtOrderByName(wahl, getDokumentVorlageArt());
  }

  public DokumentVorlageArt getDokumentVorlageArt() {
    return getExportDescription().getDokumentVorlageArt();
  }

  @Override
  public ErgebnisKandidaturenTabellarischDocumentExportDescription getExportDescription() {
    return exportDescription;
  }
}
