package com.ejie.y41e.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.apache.commons.lang.StringUtils;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.ejie.x38.dto.JQGridRequestDto;
import com.ejie.y41e.dao.rwmap.Y41eDestResultadoRowMapper;
import com.ejie.y41e.dao.rwmap.Y41eEncResultadoRowMapper;
import com.ejie.y41e.dao.rwmap.Y41eResultadosDestinatarioRowMapper;
import com.ejie.y41e.model.Y41eBloque;
import com.ejie.y41e.model.Y41eEncuesta;
import com.ejie.y41e.model.Y41eEnvio;
import com.ejie.y41e.model.Y41ePregunta;
import com.ejie.y41e.model.Y41eResultados;
import com.ejie.y41e.utils.JQGridManagerCustom;
import com.ejie.y41e.utils.Y41eSqlUtils;

/**
 * ResultadosDaoImpl  
 *  
 */

@Repository
@Transactional
public class Y41eResultadosDaoImpl extends Y41eGenericoDaoImpl<Y41eResultados> implements Y41eResultadosDao {


	public static final String TABLA="Y41E11S01";
	public static final String ID_ENVIO_011="ID_ENVIO_011";
	public static final String ID_PREGUNTA_011="ID_PREGUNTA_011 ";
	public static final String ID_BLOQUE_011="ID_BLOQUE_011 ";
	public static final String ID_TIPO_RESPUESTA_011="ID_TIPO_RESPUESTA_011";
	public static final String TEXTO_011="TEXTO_011";
	public static final String FEC_RESPUESTA_010="FEC_RESPUESTA_010";
	public static final String FEC_ENVIO_001="FEC_ENVIO_001";
	public static final String NUM_ENVIOS="NUM_ENVIOS";
	public static final String NUM_RESPUESTAS="NUM_RESPUESTAS";
	public static final String NUM_SIN_RESPUESTAS="NUM_SIN_RESPUESTAS";
	protected static final String[] ORDER_BY_WHITE_LIST = new String[] { ID_ENVIO_011, ID_PREGUNTA_011, ID_TIPO_RESPUESTA_011, TEXTO_011, 
			FEC_RESPUESTA_010, FEC_ENVIO_001};

	/**
	 * Y41eResultadosDaoImpl
	 */
	public Y41eResultadosDaoImpl() {
		super(Y41eResultados.class);
	}

	/*
	 * ROW_MAPPERS
	 */
	/**
	 * rwMap
	 */
	private final RowMapper<Y41eResultados> rwMap = new RowMapper<Y41eResultados>() {
		@Override
		public Y41eResultados mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			Y41eResultados resultados = new Y41eResultados();
			resultados.getEnvio().setIdEnvio(resultSet.getLong(ID_ENVIO_011));
			resultados.getBloque().setIdBloque(resultSet.getLong(ID_BLOQUE_011));
			resultados.getPregunta().setIdPregunta(resultSet.getLong(ID_PREGUNTA_011));
			resultados.getRespuesta().setIdTipoRespuesta(resultSet.getLong(ID_TIPO_RESPUESTA_011));
			resultados.setTexto(resultSet.getString(TEXTO_011));
			return resultados; 
		} 
	};

	/**
	 * rwMapPK
	 */
	private final RowMapper<Y41eResultados> rwMapPK = new RowMapper<Y41eResultados>() {
		@Override
		public Y41eResultados mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			Y41eResultados resultados = new Y41eResultados();
			resultados.getEnvio().setIdEnvio(resultSet.getLong(ID_ENVIO_011));
			resultados.getPregunta().setIdPregunta(resultSet.getLong(ID_PREGUNTA_011));
			resultados.getBloque().setIdBloque(resultSet.getLong(ID_BLOQUE_011));
			return resultados; 
		}
	};

	/**
	 * rwMapResultadosPreguntas
	 */
	private final RowMapper<Y41eResultados> rwMapResultadosPreguntas = new RowMapper<Y41eResultados>() {
		@Override
		public Y41eResultados mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			Y41eResultados resultados = new Y41eResultados();
			resultados.getRespuesta().setIdTipoRespuesta(resultSet.getLong("ID_TIPO_RESPUESTA_009"));
			resultados.getRespuesta().setDescEs(resultSet.getString("DESC_ES_009"));
			resultados.getRespuesta().setDescEu(resultSet.getString("DESC_EU_009"));
			resultados.setNumRespuestas(resultSet.getLong("NUM_RESPUESTAS"));
			resultados.setPorcentaje(resultSet.getLong("PORCENTAJE"));
			return resultados;
		}
	};

	/**
	 * rwMapResultadosPreguntasTexto
	 */
	private final RowMapper<Y41eResultados> rwMapResultadosPreguntasTexto = new RowMapper<Y41eResultados>() {
		@Override
		public Y41eResultados mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			Y41eResultados resultados = new Y41eResultados();
			resultados.setTexto(resultSet.getString(TEXTO_011));
			return resultados;
		}
	};

	/* (non-Javadoc)
	 * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getSelect()
	 */
	@Override
	protected String getSelect() {
		StringBuilder select = new StringBuilder("SELECT ")
				.append(ID_ENVIO_011).append(",")
				.append(ID_BLOQUE_011).append(",")
				.append(ID_PREGUNTA_011).append(",")
				.append(ID_TIPO_RESPUESTA_011).append(",")
				.append(TEXTO_011);
		return select.toString();
	}

	/* (non-Javadoc)
	 * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getFrom()
	 */
	@Override
	protected String getFrom() {
		StringBuilder from = new StringBuilder(" FROM ").append(TABLA);
		return from.toString();
	}

	/* (non-Javadoc)
	 * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getRwMap()
	 */
	@Override
	protected RowMapper<Y41eResultados> getRwMap() {
		return this.rwMap;
	}

	/* (non-Javadoc)
	 * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getPK()
	 */
	@Override
	protected String getPK() {
		StringBuilder selectPk = new StringBuilder(ID_ENVIO_011).append(",").append(ID_PREGUNTA_011);
		return selectPk.toString();
	}

	/* (non-Javadoc)
	 * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getRwMapPK()
	 */
	@Override
	protected RowMapper<Y41eResultados> getRwMapPK() {
		return this.rwMapPK;
	}

	/* (non-Javadoc)
	 * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getWherePK(java.lang.Object, java.util.List)
	 */
	@Override
	protected String getWherePK(Y41eResultados bean, List<Object> params) {
		StringBuilder wherePK = new StringBuilder();
		wherePK.append(Y41eSqlUtils.WHERE)
		.append(ID_ENVIO_011).append("=?")
		.append(Y41eSqlUtils.AND)
		.append(ID_BLOQUE_011).append("=?")
		.append(Y41eSqlUtils.AND)
		.append(ID_PREGUNTA_011).append("=?");
		params.add(bean.getEnvio().getIdEnvio());
		params.add(bean.getBloque().getIdBloque());
		params.add(bean.getPregunta().getIdPregunta());
		return wherePK.toString();

	}

	/* (non-Javadoc)
	 * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getWhere(java.lang.Object, java.util.List)
	 */
	@Override
	protected String getWhere(Y41eResultados bean, List<Object> params) {
		StringBuilder where = new StringBuilder(Y41eResultadosDaoImpl.STRING_BUILDER_INIT);

		if (bean  != null){
			where.append(Y41eSqlUtils.generarWhereIgual(ID_ENVIO_011, bean.getEnvio().getIdEnvio(), params));
			where.append(Y41eSqlUtils.generarWhereIgual(ID_BLOQUE_011, bean.getBloque().getIdBloque(), params));
			where.append(Y41eSqlUtils.generarWhereIgual(ID_PREGUNTA_011, bean.getPregunta().getIdPregunta(), params));
			where.append(Y41eSqlUtils.generarWhereIgual(ID_TIPO_RESPUESTA_011, bean.getRespuesta().getIdTipoRespuesta(), params));
			where.append(Y41eSqlUtils.generarWhereIgual(TEXTO_011, bean.getTexto(), params));
		}

		return where.toString();
	}

	/* (non-Javadoc)
	 * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getWhereLike(java.lang.Object, java.lang.Boolean, java.util.List, java.lang.Boolean)
	 */
	@Override
	protected String getWhereLike(Y41eResultados bean, Boolean startsWith, List<Object> params, Boolean search) {
		StringBuilder where = new StringBuilder(Y41eResultadosDaoImpl.STRING_BUILDER_INIT);
		if (bean  != null){
			where.append(Y41eSqlUtils.generarWhereIgual(ID_ENVIO_011, bean.getEnvio().getIdEnvio(), params));
			where.append(Y41eSqlUtils.generarWhereIgual(ID_BLOQUE_011, bean.getBloque().getIdBloque(), params));
			where.append(Y41eSqlUtils.generarWhereIgual(ID_PREGUNTA_011, bean.getPregunta().getIdPregunta(), params));
			where.append(Y41eSqlUtils.generarWhereIgual(ID_TIPO_RESPUESTA_011, bean.getRespuesta().getIdTipoRespuesta(), params));
			where.append(Y41eSqlUtils.generarWhereLikeNormalizado(TEXTO_011, bean.getTexto(), params, startsWith));
		}
		return where.toString();
	}

	/**
	 * Devuelve los resultados por encuesta
	 * @param filterEncuesta Y41eEncuesta
	 * @param jqGridRequestDto JQGridRequestDto
	 * @param startsWith boolean
	 * @return List<Y41eEncuesta>
	 */
	@Override
	public List<Y41eEncuesta> findAllLikeEncuestas(Y41eEncuesta filterEncuesta, JQGridRequestDto jqGridRequestDto,
			boolean startsWith){
		List<Object> params = new ArrayList<Object>();
		StringBuilder queryEncuestas = new StringBuilder(Y41eSqlUtils.SELECT);
		queryEncuestas.append(this.getCamposEncuestas());
		queryEncuestas.append(this.getFromEncuestas());
		queryEncuestas.append(Y41eSqlUtils.WHERE);
		queryEncuestas.append(this.getWhereLikeEncuesta(filterEncuesta, startsWith, params, false));
		queryEncuestas.append(Y41eSqlUtils.GROUP_BY);
		queryEncuestas.append(this.getCamposEncuestas());

		if (jqGridRequestDto != null) {
			queryEncuestas = JQGridManagerCustom.getPaginationQuery(jqGridRequestDto, queryEncuestas);
		}

		return this.getJdbcTemplate().query(queryEncuestas.toString(), new Y41eEncResultadoRowMapper(), params.toArray());
	}

	/**
	 * Obtiene el número de resultados por encuestas
	 * @param filterEncuesta Y41eEncuesta
	 * @param startsWith boolean 
	 * @return Long
	 */
	@Override
	public Long findAllLikeCountEncuestas(Y41eEncuesta filterEncuesta, boolean startsWith){
		List<Object> params = new ArrayList<Object>();
		StringBuilder query = new StringBuilder(Y41eSqlUtils.SELECT_COUNT)
				.append(Y41eSqlUtils.FROM)
				.append("(")
				.append(Y41eSqlUtils.SELECT_COUNT);
		query.append(this.getFromEncuestas());
		query.append(Y41eSqlUtils.WHERE);
		query.append(this.getWhereLikeEncuesta(filterEncuesta, startsWith, params, false));
		query.append(Y41eSqlUtils.GROUP_BY);
		query.append(this.getCamposEncuestas()).append(")");
		return this.getJdbcTemplate().queryForObject(query.toString(), params.toArray(), Long.class);
	}

	/**
	 * getSelectEncuestas
	 * @return String
	 */
	private String getCamposEncuestas() {
		StringBuilder select = new StringBuilder("ID_ENCUESTA_001, DESC_PUBL_ES_001, DESC_PUBL_EU_001, DESC_INT_ES_001, DESC_INT_EU_001,")
				.append(" ACTIVA_001, ID_ORIGEN_001, DESC_ES_006, DESC_EU_006, ID_AREA_001, DESC_ES_007, DESC_EU_007,")
				.append(" NUM_RESPUESTAS, NUM_SIN_RESPUESTAS, NUM_ENVIOS");
		return select.toString();
	}

	/**
	 * getFromEncuestas
	 * @return String
	 */
	private String getFromEncuestas() {
		StringBuilder select = new StringBuilder(Y41eSqlUtils.FROM)
				.append("Y41E10S01 JOIN Y41E01S01 ON ID_ENCUESTA_001=ID_ENCUESTA_010")
				.append(" LEFT JOIN Y41E06S01 ON ID_ORIGEN_001=ID_ORIGEN_006")
				.append(" LEFT JOIN Y41E07S01 ON ID_AREA_001=ID_AREA_007")
				.append(Y41eSqlUtils.LEFT_JOIN).append("(").append(this.getSelectCountResultados(NUM_ENVIOS)).append(")")
				.append(" T1 ON T1.ID_ENCUESTA_010=ID_ENCUESTA_001")
				.append(Y41eSqlUtils.LEFT_JOIN).append("(").append(this.getSelectCountResultados(NUM_RESPUESTAS)).append(")")
				.append(" T2 ON T2.ID_ENCUESTA_010=ID_ENCUESTA_001")
				.append(Y41eSqlUtils.LEFT_JOIN).append("(").append(this.getSelectCountResultados(NUM_SIN_RESPUESTAS)).append(")")
				.append(" T3 ON T3.ID_ENCUESTA_010=ID_ENCUESTA_001");
		return select.toString();
	}

	/**
	 * Obtiene el where de los resultados
	 * @param bean Y41eEncuesta
	 * @param startsWith Boolean
	 * @param params List<Object>
	 * @param search Boolean
	 * @return String
	 */
	private String getWhereLikeEncuesta(Y41eEncuesta bean, Boolean startsWith, List<Object> params, Boolean search) {
		StringBuilder where = new StringBuilder(Y41eResultadosDaoImpl.STRING_BUILDER_INIT);
		Locale locale = LocaleContextHolder.getLocale();
		where.append(" FEC_RESPUESTA_010 IS NOT NULL ");

		if (bean  != null){
			where.append(Y41eSqlUtils.generarWhereIgual("ID_ENCUESTA_001", bean.getIdEncuesta(), params));
			where.append(Y41eSqlUtils.generarWhereLikeNormalizado("DESC_PUBL_"+ locale.getLanguage().toUpperCase() +"_001", bean.getDescPubl(), params, startsWith));
			where.append(Y41eSqlUtils.generarWhereLikeNormalizado("DESC_INT_"+ locale.getLanguage().toUpperCase() +"_001", bean.getDescInt(), params, startsWith));
			where.append(Y41eSqlUtils.generarWhereIgual("ID_AREA_001", bean.getArea().getIdArea(), params));
			where.append(Y41eSqlUtils.generarWhereIgual("ID_ORIGEN_001", bean.getOrigen().getIdOrigen(), params));
			where.append(Y41eSqlUtils.generarWhereMayorIgual(FEC_ENVIO_001, bean.getFecEnvioInicio(), params));
			where.append(Y41eSqlUtils.generarWhereMenorIgual(FEC_ENVIO_001, bean.getFecEnvioFin(), params));
		}
		return where.toString();
	}

	private String getSelectCountResultados(String tipo){
		StringBuilder sqlCount = new StringBuilder(Y41eResultadosDaoImpl.STRING_BUILDER_INIT);
		sqlCount.append(Y41eSqlUtils.SELECT_COUNT)
		.append(tipo)
		.append(", ID_ENCUESTA_010")
		.append(Y41eSqlUtils.FROM)
		.append("Y41E10S01");
		if(NUM_RESPUESTAS.equals(tipo)){
			sqlCount.append(Y41eSqlUtils.WHERE);
			sqlCount.append(FEC_RESPUESTA_010).append(" IS NOT NULL");
		}else if(NUM_SIN_RESPUESTAS.equals(tipo)){
			sqlCount.append(Y41eSqlUtils.WHERE);
			sqlCount.append(FEC_RESPUESTA_010).append(" IS NULL");
		}
		sqlCount.append(Y41eSqlUtils.GROUP_BY).append("ID_ENCUESTA_010");
		return sqlCount.toString();
	}

	/**
	 * Obtien las respuestas y los resultados de cada una
	 * @param resultado Y41eResultados
	 * @param idBloque Long
	 * @param idPregunta Long
	 * @return List<Y41eResultados>
	 */
	@Override
	public List<Y41eResultados> getResultadosPreguntas(Y41eResultados resultado, Long idBloque, Long idPregunta){
		List<Object> paramsResultados = new ArrayList<Object>();
		StringBuilder sqlResultados = new StringBuilder(Y41eResultadosDaoImpl.STRING_BUILDER_INIT);
		sqlResultados.append(Y41eSqlUtils.SELECT).append(" ID_TIPO_RESPUESTA_009, DESC_ES_009, DESC_EU_009,")
		.append(" NVL(NUM_RESPUESTAS,0) NUM_RESPUESTAS, NVL(PORCENTAJE,0) PORCENTAJE")
		.append(Y41eSqlUtils.FROM).append(" Y41E09S01")
		.append(Y41eSqlUtils.JOIN).append(" Y41E04S01 ON ID_TIPO_PREGUNTA_004=ID_TIPO_PREGUNTA_009")
		.append(Y41eSqlUtils.LEFT_JOIN).append(" (")
		.append(Y41eSqlUtils.SELECT).append(" ID_TIPO_RESPUESTA_011, NUM_RESPUESTAS, PORCENTAJE , ID_PREGUNTA_011")
		.append(Y41eSqlUtils.FROM).append("(")
		.append(Y41eSqlUtils.SELECT)
		.append(" ID_TIPO_RESPUESTA_011, ID_PREGUNTA_011,")
		.append(" COUNT(1) OVER (PARTITION BY ID_PREGUNTA_011, ID_TIPO_RESPUESTA_011) NUM_RESPUESTAS,")
		.append(" ROUND(COUNT(1) OVER (PARTITION BY ID_PREGUNTA_011, ID_TIPO_RESPUESTA_011)/COUNT(1) OVER (PARTITION BY ID_PREGUNTA_011) *100) PORCENTAJE")
		.append(Y41eSqlUtils.FROM).append(" Y41E10S01")
		.append(Y41eSqlUtils.JOIN).append(TABLA).append(" ON ID_ENVIO_010=").append(ID_ENVIO_011)
		.append(Y41eSqlUtils.WHERE).append(" ID_ENCUESTA_010=?")
		.append(Y41eSqlUtils.AND).append(ID_BLOQUE_011).append("=?")
		.append(" AND id_tipo_respuesta_011 IS NOT NULL");

		paramsResultados.add(resultado.getEnvio().getEncuesta().getIdEncuesta());
		paramsResultados.add(idBloque);

		sqlResultados.append(Y41eSqlUtils.generarWhereMayorIgual(FEC_RESPUESTA_010, resultado.getEnvio().getFecRespuestaInicio(), paramsResultados));
		sqlResultados.append(Y41eSqlUtils.generarWhereMenorIgual(FEC_RESPUESTA_010, resultado.getEnvio().getFecRespuestaFin(), paramsResultados));
		sqlResultados.append(")");
		sqlResultados.append(Y41eSqlUtils.GROUP_BY)
		.append(" ID_TIPO_RESPUESTA_011, NUM_RESPUESTAS, PORCENTAJE, ID_PREGUNTA_011)")
		.append(" ON ID_TIPO_RESPUESTA_009=ID_TIPO_RESPUESTA_011 AND ID_PREGUNTA_004=ID_PREGUNTA_011")
		.append(Y41eSqlUtils.WHERE).append(" ID_PREGUNTA_004=?")
		.append(Y41eSqlUtils.ORDER_BY).append(" ORDEN_009");

		paramsResultados.add(idPregunta);

		return this.getJdbcTemplate().query(sqlResultados.toString(), rwMapResultadosPreguntas ,paramsResultados.toArray());
	}

	/**
	 * Obtiene los resultados de las preguntas de tipo texto
	 * @param resultado Y41eResultados
	 * @param idPregunta Long
	 * @param idBloque Long
	 * @return ist<Y41eResultados>
	 */
	@Override
	public List<Y41eResultados> getResultadosPreguntasTexto(Y41eResultados resultado, Long idBloque, Long idPregunta){
		List<Object> paramsResultadosTexto = new ArrayList<Object>();
		StringBuilder sqlResultadosTexto = new StringBuilder(Y41eResultadosDaoImpl.STRING_BUILDER_INIT);
		sqlResultadosTexto.append(Y41eSqlUtils.SELECT).append(TEXTO_011)
		.append(Y41eSqlUtils.FROM).append(TABLA)
		.append(Y41eSqlUtils.JOIN).append(" Y41E10S01 ON ID_ENVIO_010=").append(ID_ENVIO_011)
		.append(Y41eSqlUtils.WHERE).append(" ID_ENCUESTA_010=?")
		.append(Y41eSqlUtils.AND).append(ID_BLOQUE_011).append("=?")
		.append(Y41eSqlUtils.AND).append(ID_PREGUNTA_011).append("=?")
		.append(Y41eSqlUtils.AND).append(ID_TIPO_RESPUESTA_011).append(" IS NULL");

		paramsResultadosTexto.add(resultado.getEnvio().getEncuesta().getIdEncuesta());
		paramsResultadosTexto.add(idBloque);
		paramsResultadosTexto.add(idPregunta);

		sqlResultadosTexto.append(Y41eSqlUtils.generarWhereMayorIgual(FEC_RESPUESTA_010, resultado.getEnvio().getFecRespuestaInicio(), paramsResultadosTexto));
		sqlResultadosTexto.append(Y41eSqlUtils.generarWhereMenorIgual(FEC_RESPUESTA_010, resultado.getEnvio().getFecRespuestaFin(), paramsResultadosTexto));

		return this.getJdbcTemplate().query(sqlResultadosTexto.toString(), rwMapResultadosPreguntasTexto ,paramsResultadosTexto.toArray());

	}

	/**
	 * Devuelve los resultados por destinatario
	 * @param filter Y41eEnvio
	 * @param jqGridRequestDto JQGridRequestDto
	 * @param startsWith boolean
	 * @return List<Y41eEnvio>
	 */
	@Override
	public List<Y41eEnvio> findAllLikeDestinatario(Y41eEnvio filter, JQGridRequestDto jqGridRequestDto, boolean startsWith){
		List<Object> paramsDest = new ArrayList<Object>();
		StringBuilder queryDestinatario = new StringBuilder(Y41eSqlUtils.SELECT)
				.append(" ID_ENVIO_010, ID_USUARIO_010, ID_ENCUESTA_010, ").append(FEC_RESPUESTA_010).append(",")
				.append(FEC_ENVIO_001).append(" ,DESC_PUBL_ES_001, DESC_PUBL_EU_001, DESC_INT_ES_001, DESC_INT_EU_001,")
				.append(" ID_ORIGEN_001, DESC_ES_006, DESC_EU_006, ID_AREA_001, DESC_ES_007, DESC_EU_007");
		queryDestinatario.append(this.getFromDestinatario());
		queryDestinatario.append(Y41eSqlUtils.WHERE);
		queryDestinatario.append(this.getWhereLikeDestinatario(filter, startsWith, paramsDest, false));

		if (jqGridRequestDto != null) {
			queryDestinatario = JQGridManagerCustom.getPaginationQuery(jqGridRequestDto, queryDestinatario);
		}

		return this.getJdbcTemplate().query(queryDestinatario.toString(), new Y41eDestResultadoRowMapper(), paramsDest.toArray());
	}

	/**
	 * Obtiene el número de resultados por destinatario
	 * @param filter Y41eEnvio
	 * @param startsWith boolean
	 * @return Long
	 */
	@Override
	public Long findAllLikeCountDestinatarios(Y41eEnvio filter, boolean startsWith){
		List<Object> paramsDest = new ArrayList<Object>();
		StringBuilder query = new StringBuilder(Y41eSqlUtils.SELECT_COUNT);
		query.append(this.getFromDestinatario());
		query.append(Y41eSqlUtils.WHERE);
		query.append(this.getWhereLikeDestinatario(filter, startsWith, paramsDest, false));
		return this.getJdbcTemplate().queryForObject(query.toString(), paramsDest.toArray(), Long.class);
	}


	/**
	 * Obtiene el where de la consulta de destinatarios
	 * @param filter Y41eEnvio
	 * @param startsWith boolean
	 * @param paramsDest List<Object>
	 * @param search Boolean
	 * @return String
	 */
	private String getWhereLikeDestinatario(Y41eEnvio filter, boolean startsWith, List<Object> paramsDest, boolean search) {
		StringBuilder where = new StringBuilder(Y41eResultadosDaoImpl.STRING_BUILDER_INIT);
		Locale locale = LocaleContextHolder.getLocale();
		where.append(FEC_RESPUESTA_010).append(" IS NOT NULL");

		if (filter  != null){
			where.append(Y41eSqlUtils.generarWhereIgual("ID_ENVIO_010", filter.getIdEnvio(), paramsDest));
			where.append(Y41eSqlUtils.generarWhereIgual("ID_ENCUESTA_010", filter.getEncuesta().getIdEncuesta(), paramsDest));
			where.append(Y41eSqlUtils.generarWhereLikeNormalizado("DESC_PUBL_"+ locale.getLanguage().toUpperCase() +"_001", filter.getEncuesta().getDescPubl(), paramsDest, startsWith));
			where.append(Y41eSqlUtils.generarWhereLikeNormalizado("DESC_INT_"+ locale.getLanguage().toUpperCase() +"_001", filter.getEncuesta().getDescInt(), paramsDest, startsWith));
			where.append(Y41eSqlUtils.generarWhereLikeNormalizado("ID_USUARIO_010", filter.getIdUsuario(), paramsDest, startsWith));
			where.append(Y41eSqlUtils.generarWhereIgual("ID_AREA_001", filter.getEncuesta().getArea().getIdArea(), paramsDest));
			where.append(Y41eSqlUtils.generarWhereIgual("ID_ORIGEN_001", filter.getEncuesta().getOrigen().getIdOrigen(), paramsDest));
			where.append(Y41eSqlUtils.generarWhereMayorIgual(FEC_ENVIO_001, filter.getEncuesta().getFecEnvioInicio(), paramsDest));
			where.append(Y41eSqlUtils.generarWhereMenorIgual(FEC_ENVIO_001, filter.getEncuesta().getFecEnvioFin(), paramsDest));
			where.append(Y41eSqlUtils.generarWhereMayorIgual(FEC_RESPUESTA_010, filter.getFecRespuestaInicio(), paramsDest));
			where.append(Y41eSqlUtils.generarWhereMenorIgual(FEC_RESPUESTA_010, filter.getFecRespuestaFin(), paramsDest));
		}
		return where.toString();

	}

	/**
	 * Obtiene el from para la select de destinatario
	 * @return String
	 */
	private String getFromDestinatario() {
		StringBuilder selectDest = new StringBuilder(Y41eSqlUtils.FROM)
				.append("Y41E10S01 JOIN Y41E01S01 ON ID_ENCUESTA_010=ID_ENCUESTA_001")
				.append(" LEFT JOIN Y41E06S01 ON ID_ORIGEN_001=ID_ORIGEN_006")
				.append(" LEFT JOIN Y41E07S01 ON ID_AREA_001=ID_AREA_007");
		return selectDest.toString();

	}

	/**
	 * Obtiene los resultados de la encuesta para el usuario indicado
	 * @param envio Y41eEnvio
	 * @return List<Y41eResultados>
	 */
	@Override
	public List<Y41eResultados> getResultadosDestinatario(Y41eEnvio envio){
		List<Object> params = new ArrayList<Object>();
		StringBuilder sqlResultados = new StringBuilder(Y41eResultadosDaoImpl.STRING_BUILDER_INIT);
		sqlResultados.append(Y41eSqlUtils.SELECT)
		.append(" ID_USUARIO_010, FEC_RESPUESTA_010, ID_ENCUESTA_001, DESC_PUBL_ES_001, DESC_PUBL_EU_001,")
		.append(" ID_BLOQUE_002, DESC_PUBL_ES_002, DESC_PUBL_EU_002, ID_PREGUNTA_004, DESC_PUBL_ES_004, DESC_PUBL_EU_004,")
		.append(" ID_TIPO_RESPUESTA_009, DESC_ES_009, DESC_EU_009, TEXTO_011")
		.append(Y41eSqlUtils.FROM).append(" Y41E05S01")
		.append(Y41eSqlUtils.JOIN).append(" Y41E03S01 ON ID_BLOQUE_003=ID_BLOQUE_005")
		.append(Y41eSqlUtils.JOIN).append(" Y41E02S01 ON ID_BLOQUE_003=ID_BLOQUE_002")
		.append(Y41eSqlUtils.JOIN).append(" Y41E01S01 ON ID_ENCUESTA_001=ID_ENCUESTA_003")
		.append(Y41eSqlUtils.JOIN).append(" Y41E04S01 ON ID_PREGUNTA_004=ID_PREGUNTA_005")
		.append(Y41eSqlUtils.JOIN).append(" Y41E10S01 ON ID_ENCUESTA_001=ID_ENCUESTA_010")
		.append(Y41eSqlUtils.LEFT_JOIN).append(" Y41E11S01 ON ID_ENVIO_010=ID_ENVIO_011 AND ID_PREGUNTA_004=ID_PREGUNTA_011 AND ID_BLOQUE_011=ID_BLOQUE_003")
		.append(Y41eSqlUtils.JOIN).append(" Y41E08S01 ON ID_TIPO_PREGUNTA_008=ID_TIPO_PREGUNTA_004")
		.append(Y41eSqlUtils.LEFT_JOIN).append(" Y41E09S01 ON ID_TIPO_RESPUESTA_009=ID_TIPO_RESPUESTA_011 AND ID_TIPO_PREGUNTA_009=ID_TIPO_PREGUNTA_004")
		.append(Y41eSqlUtils.WHERE).append(" ID_ENVIO_010=?")
		.append(Y41eSqlUtils.ORDER_BY).append("ORDEN_BLOQ_003 ASC, ORDEN_PREG_005 ASC");

		params.add(envio.getIdEnvio());

		return this.getJdbcTemplate().query(sqlResultados.toString(), new Y41eResultadosDestinatarioRowMapper() ,params.toArray());
	}

	/**
	 * Guardar las respuestas del usuario
	 * @param encuesta Y41eEncuesta
	 * @param idEnvio Long
	 */
	@Override
	public void guardarRespuestas(Y41eEncuesta encuesta, Long idEnvio){

		StringBuilder insert = new StringBuilder(Y41eSqlUtils.INSERT)
				.append(TABLA).append(" (")
				.append(ID_ENVIO_011).append(",")
				.append(ID_BLOQUE_011).append(",")
				.append(ID_PREGUNTA_011).append(",")
				.append(ID_TIPO_RESPUESTA_011).append(",")
				.append(TEXTO_011).append(")")
				.append("VALUES (?,?,?,?,?)");


		final List<Object[]> paramsInsert = new ArrayList<Object[]>();
		List<Object> auxInsert = new ArrayList<Object>();
		for(Y41eBloque bloque: encuesta.getListaBloques()){
			for(Y41ePregunta pregunta: bloque.getListaPreguntas()){
				auxInsert.clear();
				auxInsert.add(idEnvio);
				auxInsert.add(bloque.getIdBloque());
				auxInsert.add(pregunta.getIdPregunta());
				if(pregunta.getResultado().getRespuesta().getIdTipoRespuesta()!=null && pregunta.getResultado().getRespuesta().getIdTipoRespuesta()>0){
					auxInsert.add(pregunta.getResultado().getRespuesta().getIdTipoRespuesta());
				}else{
					auxInsert.add(null);
				}
				if(StringUtils.isNotBlank(pregunta.getResultado().getTexto())){
					auxInsert.add(StringUtils.substring(pregunta.getResultado().getTexto(), 0, 500));
				}else{
					auxInsert.add(null);
				}
				paramsInsert.add(auxInsert.toArray().clone());
			}

		}
		this.getJdbcTemplate().batchUpdate(insert.toString(), paramsInsert);
	}

	/* (non-Javadoc)
	 * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getOrderBy()
	 */
	@Override
	protected String[] getOrderBy() {
		return Y41eResultadosDaoImpl.ORDER_BY_WHITE_LIST;
	}

	/**
	 * StringBuilder initilization value
	 */
	public static final int STRING_BUILDER_INIT = 4096;

}