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

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

import javax.enterprise.event.Observes;
import javax.enterprise.event.Reception;
import javax.inject.Inject;
import javax.inject.Named;

import de.ivu.elect.business.datei.entity.DateiExport;
import de.ivu.elect.business.entschaedigung.boundary.AuszahlungConversationSelect;
import de.ivu.elect.business.entschaedigung.boundary.AuszahlungEdit;
import de.ivu.elect.business.entschaedigung.boundary.AuszahlungExporter;
import de.ivu.elect.business.entschaedigung.boundary.AuszahlungExtendedDAO;
import de.ivu.elect.business.entschaedigung.boundary.AuszahlungSelectChangeEvent;
import de.ivu.elect.business.entschaedigung.boundary.EntschaedigungSearch;
import de.ivu.elect.business.entschaedigung.boundary.EntschaedigungSearch.EntschaedigungenInAuszahlungObsoleteSearchResult;
import de.ivu.elect.business.entschaedigung.control.AuszahlungExportContext;
import de.ivu.elect.business.entschaedigung.control.AuszahlungExportObject;
import de.ivu.elect.business.entschaedigung.entity.Auszahlung;
import de.ivu.elect.business.entschaedigung.entity.AuszahlungConstants;
import de.ivu.elect.business.entschaedigung.entity.EntschaedigungConstants;
import de.ivu.elect.business.exchange.control.AbstractExporter;
import de.ivu.elect.business.exchange.control.FileFormat;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.dynamicform.LambdaBooleanProperty;
import de.ivu.elect.jee.presentation.redirect.Redirect;
import de.ivu.elect.presentation.AbstractEntitySelectOneMenuProperty;
import de.ivu.elect.presentation.View;
import de.ivu.elect.presentation.exchange.AbstractExportSearchView;
import de.ivu.elect.presentation.exchange.ExportDescription;
import de.ivu.elect.presentation.exchange.ExportViewConfirmDialog;
import de.ivu.elect.presentation.hilfe.OnlineHilfeId;

@OnlineHilfeId("538")
@Named(AuszahlungExportView.COMPONENT_NAME)
@View(viewId = AuszahlungExportView.VIEW_ID, useCase = UseCasePermission.KONTODATEN_EXPORTIEREN)
public class AuszahlungExportView extends AbstractExportSearchView<AuszahlungExportObject, AuszahlungExportContext> {

  private static final long serialVersionUID = 1L;

  public static final String COMPONENT_NAME = "auszahlungExportView";

  public static final String VIEW_ID = "/entschaedigung/auszahlung-export.xhtml";

  @Inject
  private transient AuszahlungExtendedDAO auszahlungExtendedDAO;

  @Inject
  private transient AuszahlungEdit auszahlungEdit;

  @Inject
  private transient AuszahlungExporter auszahlungExporter;

  @Inject
  private transient AuszahlungConversationSelect auszahlungSelect;

  @Inject
  private transient AuszahlungExportDescription auszahlungExportDescription;

  @Inject
  private transient EntschaedigungSearch entschaedigungSearch;

  private AuszahlungExportContext context;

  private Boolean searchEntschaedigungenInAuszahlungObsoleteRequired;

  public AuszahlungExportView() {
    super();

    this.searchEntschaedigungenInAuszahlungObsoleteRequired = true; // ELECTKOM-589
  }

  @Override
  protected AbstractExporter<AuszahlungExportObject, AuszahlungExportContext> getExporter() {
    return auszahlungExporter;
  }

  @Override
  public ExportDescription getExportDescription() {
    return auszahlungExportDescription;
  }

  @Override
  protected AuszahlungExportContext getContext() {
    if (context == null) {
      context = new AuszahlungExportContext(getBenutzer());
    }

    return context;
  }

  /**
   * @deprecated POC für ELECTKOM-480, Hilfsmethode, um nicht ALLE Exporte zu crashen...
   */
  @Deprecated
  @Override
  protected boolean isExportParameterModelDynamic() {
    return true; // Bei Auswahl eines Formates das DynaForm-Model neu bauen...
  }

  @Override
  protected void addProperties(FormBuilder formBuilder, FileFormat fileFormat, AuszahlungExportContext context) {
    LambdaBooleanProperty searchEntschaedigungenInAuszahlungObsoleteProperty = new LambdaBooleanProperty(
        getMessage("auszahlung.export.option.entschaedigungen.pruefen.label", getMessage(EntschaedigungConstants.MESSAGE_KEY_ENTITY_MEHRZAHL)), false,
        this::setSearchEntschaedigungenInAuszahlungObsoleteRequired, this::getSearchEntschaedigungenInAuszahlungObsoleteRequired);

    formBuilder.addProperty(createAuszahlungProperty());
    formBuilder.addProperty(searchEntschaedigungenInAuszahlungObsoleteProperty).withTooltip(getMessage("auszahlung.export.option.entschaedigungen.pruefen.tooltip"));

    super.addProperties(formBuilder, fileFormat, context);
  }

  @Override
  @Redirect
  public String exportieren() {
    resetExportConfirmDialog();

    if (Boolean.TRUE.equals(getSearchEntschaedigungenInAuszahlungObsoleteRequired())) {
      Auszahlung auszahlung = getContext().getAuszahlung();

      if (auszahlung != null) {
        setExportConfirmDialog(new ExportViewConfirmDialog(getMessage("entity.export.page.title", getMessage(AuszahlungConstants.MESSAGE_KEY_ENTITY_EINZAHL)),
            searchEntschaedigungenInAuszahlungObsolete(auszahlung).toString(getMessages())));
      }
    }

    return super.exportieren();
  }

  private EntschaedigungenInAuszahlungObsoleteSearchResult searchEntschaedigungenInAuszahlungObsolete(Auszahlung auszahlung) {
    return entschaedigungSearch.getSearchResultEntschaedigungenInAuszahlungObsolete(auszahlung);
  }

  @Override
  protected void callDelete(DateiExport dateiExport) {
    auszahlungEdit.removeAndDeleteDateiExport(dateiExport); // ELECT-6877
  }

  public Boolean getSearchEntschaedigungenInAuszahlungObsoleteRequired() {
    return searchEntschaedigungenInAuszahlungObsoleteRequired;
  }

  public void setSearchEntschaedigungenInAuszahlungObsoleteRequired(Boolean searchEntschaedigungenInAuszahlungObsoleteRequired) {
    this.searchEntschaedigungenInAuszahlungObsoleteRequired = searchEntschaedigungenInAuszahlungObsoleteRequired;
  }

  private AuszahlungProperty createAuszahlungProperty() {
    List<Auszahlung> auszahlungen = findAuszahlungen();

    AuszahlungProperty auszahlungProperty = new AuszahlungProperty(auszahlungen);

    if (!auszahlungProperty.hasValue()) {
      auszahlungProperty.setValue(auszahlungSelect.getEntity());
    }

    if (!auszahlungProperty.hasValue() && !auszahlungen.isEmpty()) {
      auszahlungProperty.setValue(auszahlungen.get(0));
    }

    return auszahlungProperty;
  }

  private List<Auszahlung> findAuszahlungen() {
    List<Auszahlung> result = new ArrayList<>();

    if (isWahlSelected()) {
      result.addAll(auszahlungExtendedDAO.findByWahl(getSelectedWahl()));
    } else if (isWahlterminSelected()) {
      result.addAll(auszahlungExtendedDAO.findByWahltermin(getSelectedWahltermin()));
    }

    return result;
  }

  public void onAuszahlungSelectChangeEvent(@Observes(notifyObserver = Reception.IF_EXISTS) AuszahlungSelectChangeEvent event) {
    reset();
  }

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

    context = null;
  }

  public class AuszahlungProperty extends AbstractEntitySelectOneMenuProperty<Auszahlung> {

    // IMMER erforderlich und NIE eine leere Auswahl, da eine Auszahlung zum Export im Context vorausgewählt sein muss!!! Sonst
    // kann bspw. das Export-Parameter-Model nicht korrekt gebaut werden, cf. MucAuszahlungLsmwSapZipExportFormBuilder#addProperties...
    private static final boolean ALWAYS_REQUIRED_IN_CONTEXT = true;

    public AuszahlungProperty(List<Auszahlung> values) {
      super(values, !ALWAYS_REQUIRED_IN_CONTEXT);
    }

    @Override
    public boolean isRequired() {
      return ALWAYS_REQUIRED_IN_CONTEXT;
    }

    @Override
    public Auszahlung getValue() {
      return getContext().getAuszahlung();
    }

    @Override
    public void setValue(Auszahlung value) {
      getContext().setAuszahlung(value);
    }

    @Override
    public String getItemLabel(Auszahlung item) {
      if (item != null) {
        return item.getBezeichnung();
      }

      return "";
    }

    @Override
    protected String getMessageKeyEntityEinzahl() {
      return AuszahlungConstants.MESSAGE_KEY_ENTITY_EINZAHL;
    }
  }
}
