package com.rjconsultores.ventaboletos.dao.hibernate;

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

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.zkoss.zul.Comboitem;

import com.rjconsultores.ventaboletos.dao.TarjetaViajeDAO;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.TarjetaViaje;
import java.util.Calendar;
import java.util.GregorianCalendar;
import org.hibernate.criterion.Order;

@Repository("tarjetaViajeDAO")
public class TarjetaViajeHibernateDAO extends GenericHibernateDAO<TarjetaViaje, Integer> implements TarjetaViajeDAO {

    @Autowired
    public TarjetaViajeHibernateDAO(@Qualifier("sessionFactory") SessionFactory factory) {
        setSessionFactory(factory);
    }

    @Override
    public List<TarjetaViaje> buscarTarjetaPorFiltros(Integer autoIni, Integer autoFin, Date dataIni, Date dataFin, Comboitem empresa) {
        String hql = " select tv from TarjetaViaje tv "
                + " where tv.tarjetaviajeId > 0 and activo = 1 ";
        StringBuilder sb = new StringBuilder();
        if (autoIni != null && autoFin != null) {
            sb.append(" and cast(tv.autobus.numautobus as int) <= ").append(autoFin);
            sb.append(" and cast(tv.autobus.numautobus as int) >= ").append(autoIni);
        }
        if (dataFin != null && dataIni != null) {
            sb.append(" and tv.fecHorSalida >= :dataIni");
            sb.append(" and tv.fecHorSalida <= :dataFin");
        }
        if (empresa != null) {
            Empresa e = (Empresa) empresa.getValue();
            if (e.getEmpresaId() != -1) {
                sb.append(" and tv.empresa.empresaId = ").append(e.getEmpresaId());
            }
        }

        sb.append(" order by cast(tv.autobus.numautobus as int), tv.fecHorSalida, tv.origen, tv.conductor.conductorId asc ");

        hql += sb.toString();

        Query sq = getSession().createQuery(hql);
        if (dataFin != null && dataIni != null) {
            sq.setTimestamp("dataIni", dataIni);
            sq.setTimestamp("dataFin", dataFin);
        }
        List<TarjetaViaje> lsTarjetas = sq.list();

        return lsTarjetas;
    }

    @Override
    public List<TarjetaViaje> buscarTarjetaPorFiltros(TarjetaViaje tarjeta) {
        Criteria c = getSession().createCriteria(getPersistentClass());
        c.add(Restrictions.eq(ACTIVO, true));
        c.add(Restrictions.or(Restrictions.eq("autobus", tarjeta.getAutobus()), Restrictions.eq("conductor", tarjeta.getConductor())));
        c.add(Restrictions.eq("origen", tarjeta.getOrigen()));
        return c.list();
    }

    @Override
    public boolean buscarTarjetaExisteVolta(TarjetaViaje tarjeta) {
        Criteria c = getSession().createCriteria(getPersistentClass());
        c.add(Restrictions.eq(ACTIVO, true));
        c.add(Restrictions.or(Restrictions.eq("autobus", tarjeta.getAutobus()), Restrictions.eq("conductor", tarjeta.getConductor())));
        c.add(Restrictions.ge("fecHorSalida", tarjeta.getFecHorSalida()));
        c.add(Restrictions.not(Restrictions.eq("tarjetaviajeId", tarjeta.getTarjetaviajeId())));
        c.addOrder(Order.asc("fecHorSalida"));

        c.setMaxResults(1);

        if (!c.list().isEmpty()) {

            TarjetaViaje tVResult = (TarjetaViaje) c.uniqueResult();
            if (tVResult.getOrigen().equals(tarjeta.getDestino())
                    && tVResult.getDestino().equals(tarjeta.getOrigen())) {
                return true;
            }
        }

        Criteria c1 = getSession().createCriteria(getPersistentClass());
        c1.add(Restrictions.eq(ACTIVO, true));
        c1.add(Restrictions.or(Restrictions.eq("autobus", tarjeta.getAutobus()), Restrictions.eq("conductor", tarjeta.getConductor())));
        c1.add(Restrictions.le("fecHorSalida", tarjeta.getFecHorSalida()));
        c1.add(Restrictions.not(Restrictions.eq("tarjetaviajeId", tarjeta.getTarjetaviajeId())));
        c1.addOrder(Order.desc("fecHorSalida"));
        c1.setMaxResults(1);
        if (!c1.list().isEmpty()) {
            TarjetaViaje tVResult = (TarjetaViaje) c1.uniqueResult();
            if (tVResult.getOrigen().equals(tarjeta.getDestino())
                    && tVResult.getDestino().equals(tarjeta.getOrigen())) {
                return true;
            }
        }


        return false;
    }

    @Override
    public List<TarjetaViaje> buscarTarjetasParaEnvioNomina(Date fecIni, Date fecFin) {
        Criteria c = getSession().createCriteria(getPersistentClass());
        c.add(Restrictions.eq(ACTIVO, true));
        c.add(Restrictions.isNull("fecenvionomina"));

        GregorianCalendar gAux = new GregorianCalendar();
        gAux.setTime(fecIni);
        GregorianCalendar gcalendar = new GregorianCalendar();
        gcalendar.setTime(fecIni);
        gcalendar.set(Calendar.HOUR_OF_DAY, 0);
        gcalendar.set(Calendar.MINUTE, 0);
        gcalendar.set(Calendar.SECOND, 0);
        gcalendar.set(Calendar.MILLISECOND, 0);
        fecIni = gcalendar.getTime();

        GregorianCalendar gcalendarFim = new GregorianCalendar();
        gcalendarFim.setTime(fecFin);
        gcalendarFim.set(Calendar.HOUR_OF_DAY, 23);
        gcalendarFim.set(Calendar.MINUTE, 59);
        gcalendarFim.set(Calendar.SECOND, 59);
        gcalendarFim.set(Calendar.MILLISECOND, 59);
        fecFin = gcalendarFim.getTime();

        c.add(Restrictions.between("fecHorSalida", fecIni, fecFin));
        return c.list();
    }
}
