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 com.rjconsultores.ventaboletos.dao.VoucherDAO;
import com.rjconsultores.ventaboletos.entidad.Voucher;

@SuppressWarnings("unchecked")
@Repository("voucherDAO")
public class VoucherHibernateDAO extends GenericHibernateDAO<Voucher, Long> implements VoucherDAO {

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

	@Override
    public List<Voucher> obtenerTodos() {
        Criteria c = getSession().createCriteria(getPersistentClass());
        c.add(Restrictions.eq(ACTIVO, Boolean.TRUE));

        return c.list();
    }

	@Override
	public List<Voucher> buscarConsulta(Long voucherId, 
										String numContrato, 
										String nit, 
										String nomeTransportadora,
										Date dataInicial, 
										Date dataFinal, 
										Integer origemId, 
										Integer destinoId) {
		
		StringBuilder hql = new StringBuilder();
        hql.append("SELECT v, ori.descParada AS descOrigem , des.descParada AS descDestino ");
        hql.append("FROM Voucher v ");        
        
        setJoins( hql);
        
        hql.append("WHERE v.activo = 1 ");
        
        setClausulas(voucherId, 
        			 numContrato, 
        			 nit, 
        			 nomeTransportadora, 
        			 dataInicial, 
        			 dataFinal,
        			 null,
        			 origemId, 
        			 destinoId, 
        			 null,
        			 null,
        			 null,
        			 null,
        			 hql);
        
        hql.append("ORDER BY voucherId ");
        
        Query query = getSession().createQuery(hql.toString());
        
        setParametros(voucherId, 
        			  numContrato, 
        			  nit, 
        			  nomeTransportadora, 
        			  dataInicial, 
        			  dataFinal, 
        			  null,
        			  origemId, 
        			  destinoId,
        			  null,
        			  null,
        			  null,
        			  null,
        			  query);

        return query.list();
	}

	@Override
	public List<Voucher> buscarListaVoucher(Long numInicial, 
											Long numFinal, 
											String numContrato, 
											Long transportadoraId,
											Long grupoContratoId,
											Integer status, 
											Integer origemId, 
											Integer destinoId) {
		
		
		StringBuilder hql = new StringBuilder();
        hql.append(" SELECT v ");
        hql.append(" FROM Voucher v ");        
        hql.append(" WHERE v.activo = 1 ");
        
        
        setClausulas(null, 
   			 numContrato, 
   			 null, 
   			 null, 
   			 null, 
   			 null,
   			 status,
   			 origemId, 
   			 destinoId,
			 transportadoraId,
			 grupoContratoId,
   			 numInicial,
   			 numFinal,
   			 hql);
        
        hql.append("ORDER BY v.voucherId ");
        
        Query query = getSession().createQuery(hql.toString());
        
        setParametros(null, 
      			 numContrato, 
       			 null, 
       			 null, 
       			 null, 
       			 null,
       			 status,
       			 origemId, 
       			 destinoId,
    			 transportadoraId,
    			 grupoContratoId,
       			 numInicial,
       			 numFinal,
       			 query);

        return query.list();
	}
	
	private void setJoins(StringBuilder hql) {
		hql.append("LEFT JOIN com.rjconsultores.ventaboletos.entidad.Parada ori ON v.origenId = ori.paradaId ");
        hql.append("LEFT JOIN com.rjconsultores.ventaboletos.entidad.Parada des ON v.destinoId = des.paradaId ");
	}

	private void setClausulas(Long voucherId, 
							  String numContrato, 
							  String nit, 
							  String nomeTransportadora,
							  Date dataInicial, 
							  Date dataFinal,							  
							  Integer status,
							  Integer origemId, 
							  Integer destinoId,
							  Long transportadoraId,
							  Long grupoContratoId,
							  Long numInicial,
							  Long numFinal,
							  StringBuilder hql) {
		
		if(voucherId != null ){
			hql.append(" AND v.voucherId = :voucherId ");
		}
		
		if(numInicial != null ){
			hql.append(" AND v.voucherId >= :numInicial ");
		}
        
        if(numFinal != null ){
        	hql.append(" AND v.voucherId <= :numFinal ");
		}
        
        if(status != null ){
        	hql.append("  AND v.status = :status ");
		}
        
        if(numContrato != null ){
			hql.append(" AND v.contrato.numContrato = :numContrato ");
		}
        
        if(nit != null ){
			hql.append(" AND v.transportadora.nit = :nit ");
		}
        
        if(nomeTransportadora != null ){
			hql.append(" AND v.transportadora.nomeTransportadora like :nomeTransportadora ");
		}
        
        if(transportadoraId != null ){
			hql.append(" AND v.transportadora.transportadoraId = :transportadoraId ");
		}
        
        if(grupoContratoId != null ){
			hql.append(" AND v.contrato.grupoContratoId = :grupoContratoId ");
		}
        
        if(dataInicial != null ){
			hql.append(" AND v.dataValidade >= :dataInicial ");
		}
        
        if(dataFinal != null ){
        	hql.append(" AND v.dataValidade <= :dataFinal ");
		}
        
        if(origemId != null ){
			hql.append(" AND v.origenId = :origemId ");
		}
        
        if(destinoId != null ){
			hql.append(" AND v.destinoId = :destinoId ");
		}
	}

	private void setParametros(Long voucherId, 
			String numContrato, 
			String nit, 
			String nomeTransportadora,
			Date dataInicial, 
			Date dataFinal,
			Integer status,
			Integer origemId, 
			Integer destinoId,
			Long transportadoraId,
			Long grupoContratoId,
			Long numInicial,
			Long numFinal,
			Query query) {
		
		if(voucherId != null ){
        	query.setLong("voucherId", voucherId);
        }
		
		if(numInicial != null ){
        	query.setLong("numInicial", numInicial);
        }
		
		if(numFinal != null ){
        	query.setLong("numFinal", numFinal);
        }
        
        if(numContrato != null ){
        	query.setString("numContrato", numContrato);
		}
        
        if(nit != null ){
        	query.setString("nit", nit);
		}
        
        if(nomeTransportadora != null ){
        	query.setString("nomeTransportadora", nomeTransportadora);
		}
        
        if(transportadoraId != null ){
        	query.setLong("transportadoraId", transportadoraId);
		}
        
        if(grupoContratoId != null ){
        	query.setLong("grupoContratoId", grupoContratoId);
		}
        
        if(dataInicial != null ){
        	query.setDate("dataInicial", dataInicial);
		}
        
        if(dataFinal != null ){
        	query.setDate("dataFinal", dataFinal);
		}
        
        if(status != null ){
        	query.setInteger("status", status);
		}
        
        if(origemId != null ){
        	query.setInteger("origemId", origemId);
		}
        
        if(destinoId != null ){
        	query.setInteger("destinoId", destinoId);
		}
	}
}
