package no.valg.valgnatt.database.dao;

import java.util.Date;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import no.valg.valgnatt.database.hibernate.Stemmeskjema;
import no.valg.valgnatt.database.domene.ValgType;
import no.valg.valgnatt.database.domene.ValideringStatus;
import no.valg.valgnatt.database.hibernate.Stemmeskjema_;

import org.hibernate.Session;
import org.hibernate.query.NativeQuery;
import org.springframework.stereotype.Repository;

@Repository
public class StemmeskjemaDao extends BaseDao<Stemmeskjema, Integer> {

    public List<Stemmeskjema> findByValideringStatus(final ValideringStatus valideringStatus) {
        Session session = sessionFactory.getCurrentSession();
        CriteriaBuilder cb = session.getCriteriaBuilder();
        CriteriaQuery<Stemmeskjema> cq = cb.createQuery(Stemmeskjema.class);
        Root<Stemmeskjema> root = cq.from(Stemmeskjema.class);
        cq.select(root)
            .where(cb.equal(root.get(Stemmeskjema_.valideringstatus), valideringStatus.name()))
            .orderBy(cb.asc(root.get(Stemmeskjema_.id)));
        return session.createQuery(cq).getResultList();
    }

    public int getTotalRefId() {
        Session session = sessionFactory.getCurrentSession();
        CriteriaBuilder cb = session.getCriteriaBuilder();
        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
        cq.select(cb.count(cq.from(Stemmeskjema.class)));
        return session.createQuery(cq).getSingleResult().intValue();
    }

    public int getMaxRefId() {
        Session session = sessionFactory.getCurrentSession();
        CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
        CriteriaQuery<Integer> cq = criteriaBuilder.createQuery(Integer.class);
        Root<Stemmeskjema> root = cq.from(Stemmeskjema.class);
        cq.select(criteriaBuilder.max(root.get(Stemmeskjema_.id)));
        Integer id = session.createQuery(cq).getSingleResult();
        return id == null ? 0 : id;
    }

    public int getPendingRefId() {
        Session session = sessionFactory.getCurrentSession();
        CriteriaBuilder cb = session.getCriteriaBuilder();
        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
        Root<Stemmeskjema> root = cq.from(Stemmeskjema.class);
        cq.select(cb.count(root))
                .where(root.get(Stemmeskjema_.valideringstatus).in(ValideringStatus.I.name(), ValideringStatus.M.name(), ValideringStatus.P.name()));
        return session.createQuery(cq).getSingleResult().intValue();   
    }

    public List<Stemmeskjema> getStemmeskjema(String kommune) {
        Session session = sessionFactory.getCurrentSession();
        CriteriaBuilder cb = session.getCriteriaBuilder();
        CriteriaQuery<Stemmeskjema> cq = cb.createQuery(Stemmeskjema.class);
        Root<Stemmeskjema> root = cq.from(Stemmeskjema.class);
        cq.select(root)
                .where(cb.equal(root.get(Stemmeskjema_.kommnr), kommune));
        return session.createQuery(cq).getResultList();
    }

    public List<Stemmeskjema> getStemmeskjemaSidenTidspunkt(Date dato) {
        if (dato == null) {
            return list();
        }
        Session session = sessionFactory.getCurrentSession();
        CriteriaBuilder cb = session.getCriteriaBuilder();
        CriteriaQuery<Stemmeskjema> cq = cb.createQuery(Stemmeskjema.class);
        Root<Stemmeskjema> root = cq.from(Stemmeskjema.class);
        cq.select(root)
                .where(cb.greaterThan(root.get(Stemmeskjema_.opprettetTid), dato));
        return session.createQuery(cq).getResultList();
    }

    public List<Stemmeskjema> getStemmeskjemaSiste(ValgType valgType, String skjemaType) {
        Session session = sessionFactory.getCurrentSession();
        NativeQuery nativeQuery = session.createNativeQuery("select * from Stemmeskjema a " +
                "where not exists " +
                "(select 0 from Stemmeskjema b " +
                "where a.kommnr = b.kommnr " +
                "and a.kretsnr = b.kretsnr " +
                "and a.valgType = b.valgType " +
                "and a.skjemaType = b.skjemaType " +
                "and a.id < b.id) " +
                "and a.valgType = ? and a.skjemaType = ? " +
                "order by a.kommnr, a.kretsnr", Stemmeskjema.class);
        nativeQuery.setParameter(1, valgType.name());
        nativeQuery.setParameter(2, skjemaType);
        return nativeQuery.getResultList();
    }
}
