package de.ivu.elect.presentation.security;

import java.io.Serializable;
import java.util.List;

import javax.annotation.Nullable;
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.konfiguration.entity.ElectKonfigurationWerte;
import de.ivu.elect.business.konfiguration.entity.KonfigurationExtendedLoader;
import de.ivu.elect.business.konfiguration.entity.LoginMandantAuswahlArt;
import de.ivu.elect.business.mandant.boundary.MandantExtendedDAO;
import de.ivu.elect.business.mandant.control.MandantSupport;
import de.ivu.elect.business.mandant.entity.AbstractMandant;
import de.ivu.elect.business.mandant.entity.Mandant;
import de.ivu.elect.business.mandant.entity.MandantPK;


import static java.util.stream.Collectors.toList;

@ViewAccessScoped
@Named(LoginViewMandantStore.COMPONENT_NAME)
public class LoginViewMandantStore implements Serializable {

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

  public static final String COMPONENT_NAME = "loginViewMandantStore";

  @Inject
  private transient MandantenNummerUrlParameter mandantenNummerUrlParameter;

  @Inject
  private transient MandantSupport mandantSupport;

  @Inject
  private transient MandantExtendedDAO mandantExtendedDAO;

  @Inject
  private transient KonfigurationExtendedLoader konfigurationExtendedLoader;

  private MandantPK mandantPK;

  @PostConstruct
  public void init() {
    checkUrlParameter();
  }

  public void checkUrlParameter() {
    if (isMandantUnterstuetzt()) {
      Long nummer = mandantenNummerUrlParameter.bestimmeMandantenNummerAusContext();
      if (nummer != null) {
        try {
          Mandant mandant = mandantExtendedDAO.findByNummer(nummer);
          if (mandant != null) {
            mandantPK = mandant.getPk();
          }
        } catch (Exception e) {
          LOG.warn("Mandantennummer nicht erkannt/gefunden: '" + nummer + "' " + e.getMessage());
        }
      }
      if (isMandantAuswahlArtAuswahlAnzeigen()) {
        if (mandantPK == null) {
          List<Mandant> mandanten = getMandanten();
          if (mandanten.size() == 1) {
            mandantPK = mandanten.get(0).getPk();
          } else {
            // Ein Systemmandant und ein Customer-Mandant => Custommer-Mandant nehmen
            if (mandanten.size() == 2) {
              for (Mandant mandant : mandanten) {
                if (mandant.getArt().isCustomerMandant()) {
                  mandantPK = mandant.getPk();
                }
              }
            }
          }
        }
      }
    }
  }


  public boolean isMandantAuswahlAktiv() {
    return isMandantUnterstuetzt() && isMandantAuswahlArtAuswahlAnzeigen();
  }

  private boolean isMandantUnterstuetzt() {
    return mandantSupport.isMandantenUnterstuetzt();
  }

  private boolean isMandantAuswahlArtAuswahlAnzeigen() {
    LoginMandantAuswahlArt loginMandantAuswahlArt = konfigurationExtendedLoader
        .resolveEnumValue(ElectKonfigurationWerte.LOGIN_MANDANT_AUSWAHL_ART, LoginMandantAuswahlArt.class);
    if (loginMandantAuswahlArt == null) {
      return false;
    }
    return loginMandantAuswahlArt.isLoginAuswahlAnzeigen();
  }

  @Nullable
  public Mandant getMandant() {
    if (mandantPK == null) {
      return null;
    }
    return mandantExtendedDAO.findByPrimaryKey(mandantPK);
  }

  public void setMandant(Mandant mandant) {
    if (mandant == null) {
      mandantPK = null;
      mandantenNummerUrlParameter.setMandantenNummer(null);
    } else {
      mandantPK = mandant.getPk();
      mandantenNummerUrlParameter.setMandantenNummer(mandant.getNummer());
    }
  }

  public List<Mandant> getMandanten() {
    return mandantExtendedDAO.findByAll().stream()
        .filter(mandant -> mandant.getStatus().isAktiv())
        //.sorted(Comparator.comparing(Mandant::getArt, Comparator.comparing(MandantArt::ordinal).reversed()).thenComparing(Mandant::getNummer))
        .sorted((u,v)->{

          if (!u.getArt().equals(v.getArt())) {
            if (u.getArt().isSystemMandant()) {
              return 1;
            }
            if (v.getArt().isSystemMandant()) {
              return -1;
            }
          }
          return u.getNummer().compareTo(v.getNummer());
        })
        .collect(toList());
  }

  @Nullable
  public Long getNummerFuerLogin() {
    if (isMandantUnterstuetzt()) {
      Long mandantenNummer = mandantenNummerUrlParameter.getMandantenNummer();
      if (mandantenNummer != null) {
        try {
          Mandant mandant = mandantExtendedDAO.findByNummer(mandantenNummer);
          if (mandant != null) {
            return mandant.getNummer();
          }
        } catch (Exception e) {
          LOG.warn("Mandantennummer nicht erkannt/gefunden: '" + mandantenNummer + "' " + e.getMessage());
        }
      }
      return null;
    }
    return AbstractMandant.SYSTEM_MANDANT_NUMMER;
  }

  public boolean isShowLoginInput() {
    return !isMandantUnterstuetzt() || isMandantAuswahlAktiv() || mandantenNummerUrlParameter.getMandantenNummer() != null;
  }

}
