package com.rjconsultores.ventaboletos.dao.hibernate;

import java.math.BigDecimal;
import java.util.ArrayList;
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.ConexionRutaCtrlDAO;
import com.rjconsultores.ventaboletos.entidad.ConexionRutaConf;
import com.rjconsultores.ventaboletos.entidad.ConexionRutaCtrl;
import com.rjconsultores.ventaboletos.vo.conexion.ConexionRutaVO;

@Repository("conexionRutaCtrlDAO")
public class ConexionRutaCtrlHibernateDAO extends GenericHibernateDAO<ConexionRutaCtrl, Long> implements ConexionRutaCtrlDAO {

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

	@Override
	public List<ConexionRutaVO> buscarConexionesValidas() {

		StringBuilder sb = new StringBuilder();

		sb.append("SELECT ro.descruta as descLinhaOrigem, ");
		sb.append("       ro.numruta as numRutaOrigen, ");
		sb.append("       rd.descruta as descLinhaDestino, ");
		sb.append("       rd.numruta as numRutaDestino, ");
		sb.append("       po.descparada as tramoOrigen, ");
		sb.append("       pd.descparada as tramoDestino, ");
		sb.append("       crc.conexionrutactrl_id as conexionRutaCtrl, ");
		sb.append("       ro.ruta_id as rutaOrigenId, ");
		sb.append("       rd.ruta_id as rutaDestinonId ");
		sb.append("FROM conexion_ruta_ctrl crc ");
		sb.append("INNER JOIN conexion_ruta_tramo_ctrl crtc ON (crc.conexionrutactrl_id = crtc.conexionrutactrl_id ");
		sb.append("                                             AND crtc.activo = 1) ");
		sb.append("INNER JOIN ruta ro ON (crc.ruta_origen_id = ro.ruta_id ");
		sb.append("                       AND ro.activo =1 )");
		sb.append("INNER JOIN ruta rd ON (crc.ruta_destino_id = rd.ruta_id");
		sb.append("                       AND rd.activo =1)");
		sb.append("INNER JOIN parada po ON (po.parada_id = crtc.origen_id) ");
		sb.append("INNER JOIN parada pd ON (pd.parada_id = crtc.destino_id) ");
		sb.append("WHERE crc.activo =1");
		sb.append("  AND crtc.activo = 1");
		sb.append("  AND ro.activo = 1");
		sb.append(" ORDER BY crtc.conexionrutatramoctrl_id, conexionRutaCtrl   ");

		Query query = getSession().createSQLQuery(sb.toString());
		List<ConexionRutaVO> conexionVOs = new ArrayList<ConexionRutaVO>();

		for (Object o : query.list()) {
			Object[] oc = (Object[]) o;

			ConexionRutaVO conexionVO = new ConexionRutaVO();
			conexionVO.setDescLinhaOrigem((String) oc[0]);
			conexionVO.setNumRutaOrigen(((BigDecimal) oc[1]).intValue());
			conexionVO.setDescLinhaDestino((String) oc[2]);
			conexionVO.setNumRutaDestino(((BigDecimal) oc[3]).intValue());
			conexionVO.setTramoOrigen((String) oc[4]);
			conexionVO.setTramoDestino((String) oc[5]);
			conexionVO.setConexionRutaCtrl(((BigDecimal) oc[6]).intValue());
			conexionVO.setRutaOrigenId(((BigDecimal) oc[7]).intValue());
			conexionVO.setRutaDestinoId(((BigDecimal) oc[8]).intValue());
			conexionVOs.add(conexionVO);
		}

		return conexionVOs;

	}

	@Override
	public List<ConexionRutaVO> buscarConexionesValidas(Integer rutaOrigemId, Integer rutaDestinoId) {

		StringBuilder sb = new StringBuilder();

		sb.append("SELECT ro.descruta as descLinhaOrigem, ");
		sb.append("       ro.numruta as numRutaOrigen, ");
		sb.append("       rd.descruta as descLinhaDestino, ");
		sb.append("       rd.numruta as numRutaDestino, ");
		sb.append("       po.descparada as tramoOrigen, ");
		sb.append("       pd.descparada as tramoDestino, ");
		sb.append("       crc.conexionrutactrl_id as conexionRutaCtrl, ");
		sb.append("       ro.ruta_id as rutaOrigenId, ");
		sb.append("       rd.ruta_id as rutaDestinonId ");
		sb.append("FROM conexion_ruta_ctrl crc ");
		sb.append("INNER JOIN conexion_ruta_tramo_ctrl crtc ON (crc.conexionrutactrl_id = crtc.conexionrutactrl_id ");
		sb.append("                                             AND crtc.activo = 1) ");
		sb.append("INNER JOIN ruta ro ON (crc.ruta_origen_id = ro.ruta_id ");
		sb.append("                       AND ro.activo =1 )");
		sb.append("INNER JOIN ruta rd ON (crc.ruta_destino_id = rd.ruta_id");
		sb.append("                       AND rd.activo =1)");
		sb.append("INNER JOIN parada po ON (po.parada_id = crtc.origen_id) ");
		sb.append("INNER JOIN parada pd ON (pd.parada_id = crtc.destino_id) ");
		sb.append("WHERE crc.activo = 1");
		sb.append("  AND crtc.activo = 1");
		sb.append("  AND ro.activo = 1");
		if (rutaOrigemId != null) {
			sb.append("	and crc.ruta_origen_id =  ").append(rutaOrigemId);
		}
		if (rutaDestinoId != null) {
			sb.append("	and crc.ruta_destino_id =  ").append(rutaDestinoId);
		}
		sb.append(" ORDER BY conexionRutaCtrl,ro.descruta, ");
		sb.append("         rd.descruta,");
		sb.append("         crtc.conexionrutatramoctrl_id ");

		Query query = getSession().createSQLQuery(sb.toString());
		List<ConexionRutaVO> conexionVOs = new ArrayList<ConexionRutaVO>();

		for (Object o : query.list()) {
			Object[] oc = (Object[]) o;

			ConexionRutaVO conexionVO = new ConexionRutaVO();
			conexionVO.setDescLinhaOrigem((String) oc[0]);
			conexionVO.setNumRutaOrigen(((BigDecimal) oc[1]).intValue());
			conexionVO.setDescLinhaDestino((String) oc[2]);
			conexionVO.setNumRutaDestino(((BigDecimal) oc[3]).intValue());
			conexionVO.setTramoOrigen((String) oc[4]);
			conexionVO.setTramoDestino((String) oc[5]);
			conexionVO.setConexionRutaCtrl(((BigDecimal) oc[6]).intValue());
			conexionVO.setRutaOrigenId(((BigDecimal) oc[7]).intValue());
			conexionVO.setRutaDestinoId(((BigDecimal) oc[8]).intValue());
			conexionVOs.add(conexionVO);
		}

		return conexionVOs;
	}

	@Override
	public List<ConexionRutaCtrl> buscarPorConexionConf(ConexionRutaConf conexionRutaConf) {

		Criteria c = getSession().createCriteria(getPersistentClass());
		c.add(Restrictions.eq(ACTIVO, Boolean.TRUE));
		c.add(Restrictions.eq("conexionRutaConf", conexionRutaConf));
		return c.list();
	}

}
