package com.rjconsultores.ventaboletos.dao.hibernate;


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.AliasServicoDAO;
import com.rjconsultores.ventaboletos.entidad.AliasServico;
import com.rjconsultores.ventaboletos.entidad.ClaseServicio;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.OrgaoConcedente;
import com.rjconsultores.ventaboletos.entidad.Parada;
import com.rjconsultores.ventaboletos.entidad.Ruta;

@Repository("aliasServicoDAO")
@SuppressWarnings("unchecked")
public class AliasServicoHibernateDAO extends GenericHibernateDAO<AliasServico, Integer>
		implements AliasServicoDAO {

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

	@Override
	public List<AliasServico> buscarAliasSemCorrida(Integer origenId, Integer destinoId, Integer rutaId) {

		Criteria c = makeCriteria();
		c.add(Restrictions.eq(ACTIVO, Boolean.TRUE));
		c.add(Restrictions.eq("origen.paradaId",origenId));
		c.add(Restrictions.eq("destino.paradaId",destinoId));
		c.add(Restrictions.eq("ruta.rutaId",rutaId));
		c.add(Restrictions.isNull("corridaId"));
		
		return c.list();
	}

	@Override
	public List<AliasServico> buscar(Integer origenId, Integer destinoId, Integer rutaId, Integer corridaId) {
		Criteria c = makeCriteria();
		c.add(Restrictions.eq(ACTIVO, Boolean.TRUE));
		c.add(Restrictions.eq("origen.paradaId",origenId));
		c.add(Restrictions.eq("destino.paradaId",destinoId));
		c.add(Restrictions.eq("ruta.rutaId",rutaId));
		c.add(Restrictions.eq("corridaId",corridaId));
		
		return c.list();
	}

	@Override
	public List<AliasServico> buscarPorRuta(Integer rutaId) {

		StringBuilder hql = new StringBuilder();
		hql.append("SELECT DISTINCT alias ");
		hql.append("FROM AliasServico alias ");
		hql.append(" WHERE alias.activo = 1 ");
		hql.append(" AND alias.ruta.rutaId = :rutaId" );
		
		Query query = getSession().createQuery(hql.toString());
		query.setInteger("rutaId", rutaId);
		
		return query.list();
	}
	
	@Override
	public List<AliasServico> buscarPorLinhaEmpresa(List<Ruta> linhas, List<Empresa> empresas, List<ClaseServicio> tiposClasses, List<OrgaoConcedente> orgaos, String prefixo) {

		StringBuilder hql = new StringBuilder();
		hql.append("SELECT DISTINCT alias ");
		hql.append("FROM AliasServico alias ");
		hql.append("INNER JOIN alias.ruta.lsRutaEmpresa as re ");
		hql.append(" WHERE alias.activo = 1 ");

		if (!linhas.isEmpty()) {
			hql.append(" AND alias.ruta.rutaId IN (");
			for (Ruta r : linhas) {
				hql.append(r.getRutaId() + ",");
			}
			hql.deleteCharAt(hql.length() - 1);
			hql.append(")");
		}

		if (!empresas.isEmpty()) {
			hql.append(" AND re.empresa.empresaId IN (");
			for (Empresa e : empresas) {
				hql.append(e.getEmpresaId() + ",");
			}
			hql.deleteCharAt(hql.length() - 1);
			hql.append(")");
		}
		
		if(!tiposClasses.isEmpty()){
			hql.append(" AND alias.ruta.claseServicio.claseservicioId IN (");
			for (ClaseServicio c : tiposClasses) {
				hql.append(c.getClaseservicioId() + ",");
			}
			hql.deleteCharAt(hql.length() - 1);
			hql.append(")");
		}
		
		if(!orgaos.isEmpty()){
			hql.append(" AND alias.ruta.orgaoConcedente.orgaoConcedenteId IN (");
			for (OrgaoConcedente o : orgaos) {
				hql.append(o.getOrgaoConcedenteId() + ",");
			}
			hql.deleteCharAt(hql.length() - 1);
			hql.append(")");
		}
		
		if(prefixo != null && !prefixo.isEmpty()){
			hql.append(" AND alias.ruta.prefixo = '" + prefixo +"'" );
		}
		
		Query query = getSession().createQuery(hql.toString());
		
		return query.list();
	}

	@Override
	public AliasServico existe(Parada origem, Parada destino, Ruta linha, Integer idCorrida) {
		Criteria c = makeCriteria();

		c.add(Restrictions.eq(ACTIVO, Boolean.TRUE));
		c.add(Restrictions.eq("origen.paradaId", origem.getParadaId()));
		c.add(Restrictions.eq("destino.paradaId", destino.getParadaId()));
		c.add(Restrictions.eq("ruta.rutaId", linha.getRutaId()));
		if (idCorrida != null) {
			c.add(Restrictions.eq("corridaId", idCorrida));
		} else {
			c.add(Restrictions.isNull("corridaId"));
		}
		return (AliasServico) c.uniqueResult();
	}

}
