/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.rjconsultores.ventaboletos.dao.hibernate;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.AliasToBeanResultTransformer;
import org.hibernate.transform.Transformers;
import org.hibernate.type.IntegerType;
import org.hibernate.type.LongType;
import org.hibernate.type.StringType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import com.rjconsultores.ventaboletos.dao.UsuarioDAO;
import com.rjconsultores.ventaboletos.dao.sqlbuilder.SQLBuilder;
import com.rjconsultores.ventaboletos.entidad.Empleado;
import com.rjconsultores.ventaboletos.entidad.Usuario;
import com.rjconsultores.ventaboletos.entidad.UsuarioEmpresa;
import com.rjconsultores.ventaboletos.entidad.UsuarioPerfil;
import com.rjconsultores.ventaboletos.entidad.UsuarioUbicacion;
import com.rjconsultores.ventaboletos.vo.caja.UsuarioActivoVO;
import com.rjconsultores.ventaboletos.vo.embarcada.UsuarioEmbarcadaVO;

/**
 * 
 * @author rodrigo
 */
@Repository("usuarioDAO")
public class UsuarioHibernateDAO extends GenericHibernateDAO<Usuario, Integer> implements UsuarioDAO {
	@Autowired
	private SQLBuilder sqlBuilder;

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

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

		return c.list();
	}

	@SuppressWarnings("unchecked")
	public List<Usuario> buscarPeloNome(String nome) {
		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq(ACTIVO, Boolean.TRUE));

		c.add(Restrictions.eq("nombusuario", nome));
		c.addOrder(Order.asc("nombusuario"));

		return c.list();
	}

	public Usuario buscarPeloNomeSenha(String stUsuario, String senha) {
		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq("claveUsuario", stUsuario));
		c.add(Restrictions.eq("senha", senha));
		c.add(Restrictions.eq(ACTIVO, Boolean.TRUE));

		return (Usuario) c.uniqueResult();
	}

	@SuppressWarnings("unchecked")
	public List<Usuario> buscarPorEmpleado(Empleado empleado) {
		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq(ACTIVO, Boolean.TRUE));

		c.add(Restrictions.eq("empleado", empleado));

		return c.list();
	}

	@SuppressWarnings("unchecked")
	public List<Usuario> buscarPelaCveUsuario(String cveUsuario) {
		Query query = getSession().createQuery("select u from Usuario u where u.activo =1 and u.claveUsuario = :clave order by u.claveUsuario");
		query.setParameter("clave", cveUsuario);

		return query.list();
	}

	@SuppressWarnings("unchecked")
	public List<UsuarioActivoVO> buscarUsuariosActivo() {
		String sqlBuscarUsuariosActivo = sqlBuilder.getSQLBuscarUsuariosActivo();

		SQLQuery sql = getSession().createSQLQuery(sqlBuscarUsuariosActivo)
				.addScalar("usuarioId", IntegerType.INSTANCE)
				.addScalar("cveusuario", StringType.INSTANCE)
				.addScalar("nombusuario", StringType.INSTANCE);

		sql.setResultTransformer(new AliasToBeanResultTransformer(UsuarioActivoVO.class));

		return sql.list();
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<Usuario> buscarPeloNomeLike(String nome) {
		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq(ACTIVO, Boolean.TRUE));

		c.add(Restrictions.like("nombusuario", nome, MatchMode.START));
		c.addOrder(Order.asc("nombusuario"));

		return c.list();
	}

	@Override
	public Usuario buscarPeloId(Integer usuarioId) {
		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq("usuarioId", usuarioId));

		return (Usuario) c.uniqueResult();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<UsuarioEmbarcadaVO> buscarPorFuncionSistema(Long funcionSistemaId){
		StringBuilder sQuery = new StringBuilder();
		sQuery.append("select u.usuario_Id as usuarioId, u as nome, u.cveusuario as cveusuario, u.desccontrasena as senha, null as email from usuario u ");
		sQuery.append("where  ");
		sQuery.append("	u.activo = 1 ");
		sQuery.append("	and u.usuario_id in ( ");
		sQuery.append("        select up.usuario_id  ");
		sQuery.append("        from usuario_perfil up  ");
		sQuery.append("        join perfil_funcion pf on pf.perfil_id = up.perfil_id "); 
		sQuery.append("        where pf.funcionsistema_id = :funcionSistemaId AND pf.activo = 1 and up.activo = 1 ");
		sQuery.append("	) ");

		Query qr = getSession().createSQLQuery(sQuery.toString())
			.addScalar("usuarioId", new LongType())
	        .addScalar("nome", new StringType())
	        .addScalar("cveusuario", new StringType())
	        .addScalar("senha", new StringType())
	        .addScalar("email", new StringType())
	        .setResultTransformer(Transformers.aliasToBean(UsuarioEmbarcadaVO.class));

		qr.setLong("funcionSistemaId", funcionSistemaId);
		return (List<UsuarioEmbarcadaVO>)qr.list();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<UsuarioEmbarcadaVO> buscarUsuarioPorPontoVenda(Long puntoVentaId){
		
		StringBuilder sQuery = new StringBuilder();
		sQuery.append("select u.usuario_id as usuarioId, u.nombusuario as nome, u.cveusuario as cveusuario from usuario u ");
		sQuery.append(" left join usuario_ubicacion uu on uu.usuario_id = u.usuario_id "); 
		sQuery.append(" where  ");
		sQuery.append("	uu.puntoventa_id = :puntoVentaId ");
		sQuery.append("	and u.activo = 1 ");
		sQuery.append("	and uu.activo = 1 ");
		Query qr = getSession().createSQLQuery(sQuery.toString())
				.addScalar("usuarioId", new LongType())
		        .addScalar("nome", new StringType())
		        .addScalar("cveusuario", new StringType())
		        .setResultTransformer(Transformers.aliasToBean(UsuarioEmbarcadaVO.class));
		
		qr.setLong("puntoVentaId", puntoVentaId);
		return (List<UsuarioEmbarcadaVO>)qr.list();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<UsuarioEmbarcadaVO> buscarUsuarioPorDispositivo(Long dispositivoEmbarcadaId){
		
		StringBuilder sQuery = new StringBuilder();
		sQuery.append("select u.usuario_id as usuarioId, u.nombusuario as nome, u.cveusuario as cveusuario from usuario u ");
		sQuery.append(" left join embarcada_disp_operador embdispop on embdispop.usuario_id = u.usuario_id "); 
		sQuery.append(" where  ");
		sQuery.append("	embdispop.dispositivoembarcada_id = :dispositivoEmbarcadaId ");
		sQuery.append("	and u.activo = 1 ");
		sQuery.append("	and embdispop.activo = 1 ");
		Query qr = getSession().createSQLQuery(sQuery.toString())
				.addScalar("usuarioId", new LongType())
		        .addScalar("nome", new StringType())
		        .addScalar("cveusuario", new StringType())
		        .setResultTransformer(Transformers.aliasToBean(UsuarioEmbarcadaVO.class));
		
		qr.setLong("dispositivoEmbarcadaId", dispositivoEmbarcadaId);
		return (List<UsuarioEmbarcadaVO>)qr.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<UsuarioEmbarcadaVO> buscarUsuarioEmbarcadaPorUsuariosIds(List<Long> usuariosIdList) {
		StringBuilder sQuery = new StringBuilder();
		sQuery.append(" select u.usuario_id as usuarioId, " );
		sQuery.append(" u.nombusuario as nome, " );
		sQuery.append(" u.cveusuario as cveusuario, ");
		sQuery.append(" desccontrasena as senha, ");
		sQuery.append(" desccorreo as email  ");
		sQuery.append(" from usuario u ");
		sQuery.append(" where  ");
		sQuery.append("	u.usuario_id in (:usuariosIdList)  ");
		sQuery.append("	and u.activo = 1 ");
		Query qr = getSession().createSQLQuery(sQuery.toString())
				.addScalar("usuarioId", new LongType())
		        .addScalar("nome", new StringType())
		        .addScalar("cveusuario", new StringType())
		        .addScalar("senha", new StringType())
		        .addScalar("email", new StringType())
		        .setResultTransformer(Transformers.aliasToBean(UsuarioEmbarcadaVO.class));
		
		qr.setParameterList("usuariosIdList", usuariosIdList);
		return (List<UsuarioEmbarcadaVO>)qr.list();
	}
	
	
	@SuppressWarnings("unchecked")
	@Override
	public List<UsuarioEmbarcadaVO> buscaUsuariosDoPuntoVenta(Long puntoventaId){
		StringBuilder sQuery = new StringBuilder();
		sQuery.append(" select distinct u.usuario_id as usuarioId, " );
		sQuery.append(" u.nombusuario as nome, " );
		sQuery.append(" u.cveusuario as cveusuario, ");
		sQuery.append(" desccontrasena as senha, ");
		sQuery.append(" desccorreo as email ");
		sQuery.append(" from usuario u ");
		sQuery.append(" left join usuario_ubicacion uu on (uu.usuario_id = u.usuario_id) "); 
		sQuery.append(" join OPERADOR_EMBARCADA operEmb  ON (u.USUARIO_ID = operEmb.USUARIO_ID) ");
		sQuery.append(" where ");
		sQuery.append(" uu.puntoventa_id = :puntoventaId ");
		sQuery.append(" and uu.activo = 1 ");
		sQuery.append("	and u.activo = 1 ");
		sQuery.append("	and operEmb.activo = 1 ");
		Query qr = getSession().createSQLQuery(sQuery.toString())
				.addScalar("usuarioId", new LongType())
		        .addScalar("nome", new StringType())
		        .addScalar("cveusuario", new StringType())
		        .addScalar("senha", new StringType())
		        .addScalar("email", new StringType())
		        .setResultTransformer(Transformers.aliasToBean(UsuarioEmbarcadaVO.class));
		
		qr.setLong("puntoventaId", puntoventaId);
		return (List<UsuarioEmbarcadaVO>)qr.list();

	}

	@Override
	public List<UsuarioEmpresa> buscarUsuarioEmpresaList(Integer usuarioId) {
		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq("usuarioId", usuarioId));

		Usuario result = (Usuario)c.uniqueResult();
		return result.getUsuarioEmpresaList();
	}
	
	@Override
	public List<UsuarioUbicacion> buscarUsuarioUbicacionList(Integer usuarioId) {
		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq("usuarioId", usuarioId));

		Usuario result = (Usuario)c.uniqueResult();
		return result.getUsuarioUbicacionList();
	}

	@Override
	public List<UsuarioPerfil> buscarUsuarioPerfilList(Integer usuarioId) {
		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq("usuarioId", usuarioId));

		Usuario result = (Usuario)c.uniqueResult();
		return result.getUsuarioPerfilList();		
	}
	
	
		
}
