package jpa;


import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.criteria.*;
import metier.*;

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

public class JpaTest {
    private EntityManager manager;

    public JpaTest(EntityManager manager) {
        this.manager = manager;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        EntityManager manager = EntityManagerHelper.getEntityManager();

        JpaTest test = new JpaTest(manager);

        EntityTransaction tx = manager.getTransaction();
        tx.begin();
        try {
            test.create_user_test();
            test.create_session_test();
            test.create_quizz_test(1,1);
            //test.list_utilisateur();
            //test.list_session();
            test.list_quizz();
        } catch (Exception e) {
            e.printStackTrace();
        }
        tx.commit();

        manager.close();
        EntityManagerHelper.closeEntityManagerFactory();
        System.out.println(".. done");
    }

    private void create_user_test() {
        int numUser = manager.createQuery("SELECT u FROM Utilisateur u", Utilisateur.class).getResultList().size();
        if (numUser == 0) {
            //Utilisateur
            Utilisateur utilisateur1 = new Utilisateur();
            utilisateur1.setName("Titi");
            utilisateur1.setEmail("titi@email.com");
            utilisateur1.setPassword("123456");

            Utilisateur utilisateur2 = new Utilisateur();
            utilisateur2.setName("Toto");

            manager.persist(utilisateur1);
            manager.persist(utilisateur2);
        }
    }

    private void create_session_test() {
        int numUser = manager.createQuery("SELECT u FROM Session u", Session.class).getResultList().size();
        if (numUser == 0) {
            //Utilisateur
            Session session1 = new Session();
            session1.setCodePIN(1703);
            session1.setTheme("Inphormatik");
            session1.setQuizzs(new ArrayList<>());

            List<Utilisateur> ulist = manager.createQuery("select user from Utilisateur user").getResultList();
            session1.setUtilisateurs(ulist);

            manager.persist(session1);
        }
    }

    private void list_utilisateur() {
        CriteriaBuilder criteriaBuilder = manager.getCriteriaBuilder();
        CriteriaQuery<Utilisateur> query = criteriaBuilder.createQuery(Utilisateur.class);
        Root<Utilisateur> from = query.from(Utilisateur.class);
        query.select(from);
        List<Utilisateur> result_utilisatuer_list = manager.createQuery(query).getResultList();
        for (Utilisateur u : result_utilisatuer_list) {
            System.out.println(u.getId() + " " + u.getName() + " " + u.getEmail());
        }
    }

    private void list_session() {
        CriteriaBuilder criteriaBuilder = manager.getCriteriaBuilder();
        CriteriaQuery<Session> query = criteriaBuilder.createQuery(Session.class);
        Root<Session> from = query.from(Session.class);
        query.select(from);
        List<Session> result_session_list = manager.createQuery(query).getResultList();
        for (Session s : result_session_list) {
            System.out.println(s.getCodePIN() + " " + s.getTheme());
            for (Utilisateur u : s.getUtilisateurs()) {
                System.out.println(u.getId() + " " + u.getName() + " " + u.getEmail());
            }
        }
    }

    private void create_quizz_test(int userId, int sessionId) {

        CriteriaBuilder cb = manager.getCriteriaBuilder();

        //GET USER
        CriteriaQuery<Utilisateur> cqUser = cb.createQuery(Utilisateur.class);
        Root<Utilisateur> userRoot = cqUser.from(Utilisateur.class);
        cqUser.select(userRoot).where(cb.equal(userRoot.get("id"), userId));
        Utilisateur u1 = manager.createQuery(cqUser).getSingleResult();

        //GET SESSION
        CriteriaQuery<Session> cqSess = cb.createQuery(Session.class);
        Root<Session> sessRoot = cqSess.from(Session.class);
        cqSess.select(sessRoot).where(cb.equal(sessRoot.get("id"), sessionId));
        Session s1 = manager.createQuery(cqSess).getSingleResult();

        List<Session> ls= u1.getSession();
        ls.add(s1);
        u1.setSession(ls);
        Quizz quizz1 = new Quizz();
        quizz1.setUtilisateur(u1);
        quizz1.setSession(s1);

        manager.persist(quizz1);
        manager.merge(u1);
        manager.persist(s1);
    }

    private void list_quizz() {
        CriteriaBuilder cb = manager.getCriteriaBuilder();
        CriteriaQuery<Quizz> cq = cb.createQuery(Quizz.class);
        Root<Quizz> from = cq.from(Quizz.class);

        List<Integer> sessionIds = new ArrayList<>();
        sessionIds.add(1);
        //https://www.w3schools.com/SQL/sql_join_inner.asp
        //https://stackoverflow.com/questions/15990141/how-to-make-a-criteriabuilder-join-with-a-custom-on-condition
        Join<Quizz, Session> sessionJoin = from.join("session", JoinType.INNER);
        cq.select(from).where(sessionJoin.get("id").in(sessionIds));

        List<Quizz> quizzs = manager.createQuery(cq).getResultList();
        for (Quizz q : quizzs) {
            System.out.println("Quizz ID: " + q.getId() + ", User: " + q.getUtilisateur().getName() +
                    ", Session ID: " + q.getSession().getId());
        }
    }
}
