
package de.ivu.elect.presentation.exchange;

import static java.util.Objects.nonNull;

import java.io.Serializable;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

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

import org.apache.deltaspike.core.api.scope.ViewAccessScoped;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.business.datei.boundary.DateiConversationSelect;
import de.ivu.elect.business.datei.control.DateiLeser;
import de.ivu.elect.business.datei.control.XmlEncodingDetector;
import de.ivu.elect.business.datei.entity.CsvDatei;
import de.ivu.elect.business.datei.entity.CsvZeichensatz;
import de.ivu.elect.business.datei.entity.Datei;
import de.ivu.elect.business.security.UseCasePermission;
import de.ivu.elect.jee.faces.FacesContextUtil;
import de.ivu.elect.jee.faces.Messages;
import de.ivu.elect.jee.faces.PreConditionCheck;
import de.ivu.elect.jee.presentation.menu.AbstractMenuModelBuilder;
import de.ivu.elect.jee.presentation.redirect.Redirect;
import de.ivu.elect.jee.presentation.security.StartViewResolver;
import de.ivu.elect.presentation.View;
import de.ivu.elect.presentation.hilfe.OnlineHilfeId;

@Named
@ViewAccessScoped
@OnlineHilfeId(value = "148", mehrfachVergebenOk = true)
@View(viewId = DateiVorschauView.VIEW_ID, useCase = UseCasePermission.OHNE)
public class DateiVorschauView implements Serializable {

  private static final long serialVersionUID = 1L;

  public static final String VIEW_ID = "/exchange/datei-vorschau.xhtml";

  private static final Logger LOG = LoggerFactory.getLogger(DateiVorschauView.class);

  private static final int DEFAULT_ANZAHL_ZEICHEN = 10000;

  @Inject
  private transient DateiConversationSelect dateiSelect;

  @Inject
  private transient DateiLeser dateiLeser;

  @Inject
  private transient StartViewResolver startViewResolver;

  @Inject
  private transient Messages messages;

  @Inject
  private transient DateiVorschauContextSelect dateiVorschauContextSelect;

  @Inject
  private transient XmlEncodingDetector xmlEncodingDetector;

  private CsvZeichensatz zeichensatz = CsvZeichensatz.UTF_8;

  public DateiVorschauView() {
    super();
  }

  @PostConstruct
  public void init() {
    Datei datei = dateiSelect.getEntity();

    if (datei != null) {
      if (datei.isCsvDatei()) {
        zeichensatz = ((CsvDatei) datei).getZeichensatz();
      }

      if (datei.isXmlDatei()) {
        CsvZeichensatz zeichensatzDetected = xmlEncodingDetector.detectEncoding(datei);

        if (zeichensatzDetected != null) {
          zeichensatz = zeichensatzDetected;
        } else {
          messages.addWarnMessage("datei.import.vorschau.kann.encoding.nicht.bestimmen");
        }
      }
    }
  }

  @PreConditionCheck
  public String preConditionCheck() {
    if (dateiSelect.getEntity() == null) {
      messages.addErrorMessage("datei.import.edit.action.vorschau.keine.datei.ausgewaehlt");

      return startViewResolver.getStartViewId();
    }

    return null;
  }

  @Redirect
  public String cancel() {
    if (dateiVorschauContextSelect.isSelected()) {
      return dateiVorschauContextSelect.getLastViewId();
    }

    return startViewResolver.getStartViewId();
  }

  public Datei getDatei() {
    return dateiSelect.getEntity();
  }

  public void setDatei(Datei datei) {
    dateiSelect.setEntity(datei);
  }

  // Hier wird bereits die Seite gerendert, es sollte also nicht knallen -> CATCH-Alles
  public List<String> getLines() {
    try {
      Charset charset = StandardCharsets.UTF_8;

      if (nonNull(getZeichensatz())) {
        charset = getZeichensatz().toCharset();
      }

      return dateiLeser.liesDatenAusDatei(getDatei(), charset, DEFAULT_ANZAHL_ZEICHEN);
    } catch (Exception ex) {
      String msg = ex.getLocalizedMessage();

      messages.addErrorMessage(Messages.LOCALIZED_MESSAGE_ONLY_MSG_KEY, msg);

      LOG.warn(msg, ex);

      return new ArrayList<>();
    }
  }

  public CsvZeichensatz getZeichensatz() {
    return zeichensatz;
  }

  public void setZeichensatz(CsvZeichensatz zeichensatz) {
    this.zeichensatz = zeichensatz;
  }

  public List<CsvZeichensatz> getZeichensatzValues() {
    return Arrays.asList(CsvZeichensatz.values());
  }

  public String getViewId() {
    return VIEW_ID;
  }

  public AbstractMenuModelBuilder getPageMenu() {
    return FacesContextUtil.getElValue("#{" + dateiVorschauContextSelect.getPageMenuComponentName() + "}", AbstractMenuModelBuilder.class);
  }

  public boolean isPageMenuAvailable() {
    return dateiVorschauContextSelect.getPageMenuComponentName() != null;
  }

  public int getAnzahlZeichen() {
    return DEFAULT_ANZAHL_ZEICHEN;
  }
}
