package control;

import entities.Bild;
import entities.Nutzer;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.annotation.Resource;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.transaction.NotSupportedException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

@ManagedBean
@SessionScoped
public class Controller implements Serializable {

  @PersistenceUnit
  private EntityManagerFactory emf;
  @Resource
  private UserTransaction utx;
  private EntityManager em;
  private String name = null;
  private Bild hat = new Bild();
  private Bild sucht = new Bild();
  private List<Bild> haben = new ArrayList<Bild>();
  private List<Bild> suchen = new ArrayList<Bild>();
  private List<Bild> nutzerHaben = new ArrayList<Bild>();
  private List<Bild> nutzerSuchen = new ArrayList<Bild>();
  private String statusHaben = "vorhandenes Bild ergänzen";
  private String statusSuchen = "folgendes Bild ist gewünscht";

  public List<Bild> getHaben() {
    em = emf.createEntityManager();
    haben = em.createQuery("SELECT b FROM Nutzer n JOIN n.hat b", Bild.class).getResultList();
    schliessen();
    return haben;
  }

  public List<Bild> getSuchen() {
    em = emf.createEntityManager();
    suchen = em.createQuery("SELECT b FROM Nutzer n JOIN n.sucht b", Bild.class).getResultList();
    schliessen();
    return suchen;
  }
  
  public List<Bild> getNutzerHaben() {
  em = emf.createEntityManager();
  nutzerHaben = em.createQuery("SELECT b FROM Nutzer n JOIN n.hat b WHERE n.name='"+name+"'", Bild.class).getResultList();
  schliessen();
  return nutzerHaben;
  }

  public List<Bild> getNutzerSuchen() {
  em = emf.createEntityManager();
  nutzerSuchen = em.createQuery("SELECT b FROM Nutzer n JOIN n.sucht b WHERE n.name='"+name+"'", Bild.class).getResultList();
  schliessen();
  return nutzerSuchen;
  }

  public String getName() {
    if (name == null) {
      ExternalContext ectx = FacesContext.getCurrentInstance().getExternalContext();
      name = ectx.getRemoteUser();
      if (name != null) {
        em = emf.createEntityManager();
        int anzahl = em.createQuery("SELECT n FROM Nutzer n WHERE n.name='" + name+"'", Nutzer.class).getResultList().size();
        schliessen();
        if (anzahl == 0) {
          persist(new Nutzer(name));
        }
      }
    }
    return name;
  }

  private void schliessen() {
    if (em != null && em.isOpen()) {
      em.close();
    }
  }

  public String anmelden() {
    return "./handeln/bearbeiten.xhtml?faces-redirect=true";
  }

  public String abmelden() {
    ExternalContext ectx = FacesContext.getCurrentInstance().getExternalContext();
    ectx.invalidateSession();
    name = null;
    return "//index.xhtml?faces-redirect=true";
  }

  public String aktionHaben(){
    if(statusHaben.equals("vorhandenes Bild ergänzen")){
      try {
        em = emf.createEntityManager();
        utx.begin();
         Bild b = new Bild(hat.getNr(), hat.getSerie());
        Nutzer n = em.createQuery("SELECT n FROM Nutzer n WHERE n.name='" + name + "'", Nutzer.class).getSingleResult();
        n.hatErgaenzen(b);
        em.persist(n);
        utx.commit();
        hat = new Bild();
      } catch (Exception e){
        System.out.println(e);
      }
    } else
    if(statusHaben.equals("Bilddaten bearbeiten")){
      try {
        em = emf.createEntityManager();
        utx.begin();
        Bild b = em.find(Bild.class, hat.getId());
        b.setNr(hat.getNr());
        b.setSerie(hat.getSerie());
        em.persist(b);
        utx.commit();
        hat = new Bild();
      } catch (Exception e){
        System.out.println(e);
      }
      statusHaben = "vorhandenes Bild ergänzen";
    }
    return "bearbeiten";
  }

  public String aendernHaben(Bild b){
    statusHaben="Bilddaten bearbeiten";
    hat=b;
    return "bearbeiten";
  }

  public String loeschenHaben(Bild b){
         try {
        em = emf.createEntityManager();
        utx.begin();
        //Bild tmp = em.find(Bild.class, b.getId());
        Nutzer n = em.createQuery("SELECT n FROM Nutzer n WHERE n.name='" + name + "'", Nutzer.class).getSingleResult();
        n.hatLoeschen(b);
        em.persist(n);
        utx.commit();
        hat = new Bild();
      } catch (Exception e){
        System.out.println(e);
      }
      statusHaben = "vorhandenes Bild ergänzen";
    return "bearbeiten";
  }

    public String aktionSuchen(){
    if(statusSuchen.equals("folgendes Bild ist gewünscht")){
      try {
        em = emf.createEntityManager();
        utx.begin();
         Bild b = new Bild(sucht.getNr(), sucht.getSerie());
        Nutzer n = em.createQuery("SELECT n FROM Nutzer n WHERE n.name='" + name + "'", Nutzer.class).getSingleResult();
        n.suchtErgaenzen(b);
        em.persist(n);
        utx.commit();
        sucht = new Bild();
      } catch (Exception e){
        System.out.println(e);
      }
    } else
    if(statusSuchen.equals("Bilddaten bearbeiten")){
      try {
        em = emf.createEntityManager();
        utx.begin();
        Bild b = em.find(Bild.class, sucht.getId());
        b.setNr(sucht.getNr());
        b.setSerie(sucht.getSerie());
        em.persist(b);
        utx.commit();
        sucht = new Bild();
      } catch (Exception e){
        System.out.println(e);
      }
      statusSuchen = "folgendes Bild ist gewünscht";
    }
    return "bearbeiten";
  }

  public String aendernSuchen(Bild b){
    statusSuchen="Bilddaten bearbeiten";
    sucht=b;
    return "bearbeiten";
  }

  public String loeschenSuchen(Bild b){
         try {
        em = emf.createEntityManager();
        utx.begin();
        //Bild tmp = em.find(Bild.class, b.getId());
        Nutzer n = em.createQuery("SELECT n FROM Nutzer n WHERE n.name='" + name + "'", Nutzer.class).getSingleResult();
        n.suchtLoeschen(b);
        em.persist(n);
        utx.commit();
        sucht = new Bild();
      } catch (Exception e){
        System.out.println(e);
      }
      statusSuchen = "folgendes Bild ist gewünscht";
    return "bearbeiten";
  }

  public String start() {
    return abmelden();
  }

  public String nutzerSucht(Bild b){
    String ergebnis="nein";
    em = emf.createEntityManager();
    if(em.createQuery("SELECT n FROM Nutzer n JOIN n.sucht b WHERE n.name='"
            +name+"' AND b.nr='"+b.getNr()+"' AND b.serie='"
            +b.getSerie()+"'").getResultList().size() >0)
      ergebnis="ja";
    schliessen();
    return ergebnis;
  }

    public String nutzerHat(Bild b){
    String ergebnis="nein";
    em = emf.createEntityManager();
    if(em.createQuery("SELECT n FROM Nutzer n JOIN n.hat b WHERE n.name='"
            +name+"' AND b.nr='"+b.getNr()+"' AND b.serie='"
            +b.getSerie()+"'").getResultList().size() >0)
      ergebnis="ja";
    schliessen();
    return ergebnis;
  }

  public void persist(Object o) {
    FacesContext ctxt = FacesContext.getCurrentInstance();
    FacesMessage ms = new FacesMessage("Aktion erfolgreich");

    try {
      em = emf.createEntityManager();
      utx.begin();
      em.persist(o);
      utx.commit();
    } catch (Exception e) {
      try {
        ms = new FacesMessage(e.getMessage());
        utx.rollback();
      } catch (Exception e2) {
        ms = new FacesMessage(e2.getMessage());
      }
    } finally {
      schliessen();
    }
    ctxt.addMessage(null, ms);
  }

  public Bild getHat() {
    return hat;
  }

  public void setHat(Bild hat) {
    this.hat = hat;
  }

  public String getStatusHaben() {
    return statusHaben;
  }

  public void setStatusHaben(String statusHaben) {
    this.statusHaben = statusHaben;
  }

  public String getStatusSuchen() {
    return statusSuchen;
  }

  public void setStatusSuchen(String statusSuchen) {
    this.statusSuchen = statusSuchen;
  }

  public Bild getSucht() {
    return sucht;
  }

  public void setSucht(Bild sucht) {
    this.sucht = sucht;
  }
}
