
package de.ivu.elect.presentation.niederschrift;

import static org.apache.commons.lang3.StringUtils.isNoneBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;

import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.FacesConverter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.business.niederschrift.boundary.AbstractNiederschriftDAO;
import de.ivu.elect.business.niederschrift.boundary.NiederschriftFormatter;
import de.ivu.elect.business.niederschrift.boundary.NiederschriftFormatter.NiederschriftKuerzelSchnelleingabe;
import de.ivu.elect.business.niederschrift.entity.Niederschrift;
import de.ivu.elect.business.niederschrift.entity.NiederschriftArt;
import de.ivu.elect.jee.faces.AbstractEntityConverter;

@FacesConverter(value = NiederschriftEntityConverterMitSchnelleingabeSupport.CONVERTER_ID, forClass = Niederschrift.class)
public class NiederschriftEntityConverterMitSchnelleingabeSupport extends AbstractEntityConverter {

  public static final String CONVERTER_ID = "niederschriftEntityConverterMitSchnelleingabeSupport";

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

  private final AbstractNiederschriftDAO niederschriftDAO;

  private final NiederschriftFormatter niederschriftFormatter;

  private final Map<String, Object> niederschriftPerKuerzelSchnelleingabe;

  public NiederschriftEntityConverterMitSchnelleingabeSupport(AbstractNiederschriftDAO niederschriftDAO, NiederschriftFormatter niederschriftFormatter, Collection<Niederschrift> niederschriften) {
    super();

    this.niederschriftDAO = niederschriftDAO;
    this.niederschriftFormatter = niederschriftFormatter;

    this.niederschriftPerKuerzelSchnelleingabe = new HashMap<>();

    for (Niederschrift niederschrift : niederschriften) {
      niederschriftPerKuerzelSchnelleingabe.put(niederschriftFormatter.formatKuerzelSchnelleingabeWahlExcluded(niederschrift).getValueFormatted(), niederschrift);
      niederschriftPerKuerzelSchnelleingabe.put(niederschriftFormatter.formatKuerzelSchnelleingabeWahlIncluded(niederschrift).getValueFormatted(), niederschrift);
    }
  }

  @Override
  public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
    Object result = super.getAsObject(facesContext, component, value);

    // Wurde keine Entität aus der dem Benutzer angezeigten Auswahlliste ausgewählt: versuche, den verbleibenden
    // String selbst zu interpretieren.
    if (result == null && isNotBlank(value)) {
      result = niederschriftPerKuerzelSchnelleingabe.get(value);

      if (result == null) {
        NiederschriftKuerzelSchnelleingabe niederschriftKuerzelSchnelleingabe = niederschriftFormatter.formatKuerzelSchnelleingabe(value);

        String valueFormatted = niederschriftKuerzelSchnelleingabe.getValueFormatted();

        result = niederschriftPerKuerzelSchnelleingabe.get(valueFormatted);

        if (result == null) { // ELECTMUC-2749
          String wahlKennzeichen = niederschriftKuerzelSchnelleingabe.getWahlKennzeichen();
          Date wahlWahldatum = niederschriftKuerzelSchnelleingabe.getWahlWahldatum();

          String gebietNummer = niederschriftKuerzelSchnelleingabe.getGebietNummer();

          NiederschriftArt niederschriftArt = niederschriftKuerzelSchnelleingabe.getNiederschriftNiederschriftArt();

          if (isNoneBlank(wahlKennzeichen, gebietNummer) && wahlWahldatum != null && niederschriftArt != null) {
            for (Niederschrift niederschrift : niederschriftDAO.findByKuerzelSchnelleingabe(wahlKennzeichen, wahlWahldatum, gebietNummer, niederschriftArt)) {
              // NOTE, dass die Darstellung der Gebietsart für MUC in CustomData hinterlegt ist, cf. MucNiederschriftFormatter#formatKuerzelSchnelleingabeGebietGebietsart!!!
              // Deshalb hier für alle passenden Niederschriften einfach nochmal die korrekten Darstellungen berechnen und dann auf die Map zugreifen.
              niederschriftPerKuerzelSchnelleingabe.put(niederschriftFormatter.formatKuerzelSchnelleingabeWahlIncluded(niederschrift).getValueFormatted(), niederschrift);
            }

            result = niederschriftPerKuerzelSchnelleingabe.get(valueFormatted);
          }

          if (result == null) {
            LOG.warn(
                "Niederschriftkuerzel fuer Schnelleingabe lieferte KEIN Ergebnis [value = {}, valueFormatted = {}, wahlKennzeichen = {}, wahlWahldatum = {}, gebietNummer = {}, niederschriftArt = {}]",
                value, valueFormatted, wahlKennzeichen, wahlWahldatum, gebietNummer, niederschriftArt);
          }
        }
      }
    }

    return result;
  }
}
