package com.ejie.m62fb.dao.registroVPP;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.springframework.dao.support.DataAccessUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.ejie.m62fb.model.ViviendaSolicitada;
import com.ejie.m62fb.model.tipos.RegimenAcceso;
import com.ejie.m62fb.model.tipos.RegimenTenencia;
import com.ejie.m62fb.utils.constants.AppConstantes;
import com.ejie.m62fb.utils.sql.BDUtils;
import com.ejie.m62fb.utils.sql.UtilsResulSet;
import com.ejie.x38.dto.JQGridManager;
import com.ejie.x38.dto.JQGridRequestDto;

/**
 * viviendaSolicitadaDaoImpl.
 * 
XXXX
 */
@Repository
@Transactional
public class ViviendaSolicitadaDaoImpl implements ViviendaSolicitadaDao {
	private JdbcTemplate jdbcTemplate;

	/*
	 * ROW_MAPPERS
	 */
	private final RowMapper<ViviendaSolicitada> rwMap = new RowMapper<ViviendaSolicitada>() {
		@Override
		public ViviendaSolicitada mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			ViviendaSolicitada viviendaSolicitada = new ViviendaSolicitada();

			// Identificador Vivienda Solicitada
			viviendaSolicitada.setIdM62r40t0(UtilsResulSet.getBigDecimal(
					resultSet, "IDM62R40T0"));
			// Identificador Solicitud Reserva
			viviendaSolicitada.setIdM62r38t0(UtilsResulSet.getInteger(
					resultSet, "IDM62R38T0"));
			// Nº Orden
			viviendaSolicitada.setNumOrden(UtilsResulSet.getLong(resultSet,
					"NUMORDEN"));
			// Descripcion Motivo Reserva
			viviendaSolicitada.setDesMotivoReserva(UtilsResulSet.getString(
					resultSet, "DESMOTIVORESERVA"));
			// Regimen Acceso
			RegimenAcceso regimenAcceso = new RegimenAcceso();
			regimenAcceso.setCodTabla(UtilsResulSet.getString(resultSet,
					"CODREGACCESO"));
			regimenAcceso.setDescripcionEs(UtilsResulSet.getString(resultSet,
					"DESCREGACCESOES"));
			regimenAcceso.setDescripcionEu(UtilsResulSet.getString(resultSet,
					"DESCREGACCESOEU"));
			viviendaSolicitada.setRegimenAcceso(regimenAcceso);
			// Indicador Vivienda Adaptada
			viviendaSolicitada.setIndVivAdaptada(UtilsResulSet.getIndicadorSN(
					resultSet, "INDVIVADAPTADA"));
			// Numero Dormitorios Vivienda
			viviendaSolicitada.setNumDormitorios(UtilsResulSet.getLong(
					resultSet, "NUMDORMITORIOS"));
			// Superficie Util Vivienda
			viviendaSolicitada.setSupUtilViv(UtilsResulSet.getBigDecimal(
					resultSet, "SUPUTILVIV"));
			// Descripcion Receptor
			viviendaSolicitada.setDesReceptor(UtilsResulSet.getString(
					resultSet, "DESRECEPTOR"));
			// Observaciones
			viviendaSolicitada.setTexObservaciones(UtilsResulSet.getString(
					resultSet, "TEXOBSERVACIONES"));
			// Regimen Tenencia
			RegimenTenencia regimenTenencia = new RegimenTenencia();
			regimenTenencia.setCodTabla(resultSet.getString("CODREGTENENCIA"));
			regimenTenencia.setDescripcionEs(resultSet
					.getString("DESCREGTENENCIAES"));
			regimenTenencia.setDescripcionEu(resultSet
					.getString("DESCREGTENENCIAEU"));
			viviendaSolicitada.setRegimenTenencia(regimenTenencia);
			// Codigo Provincia
			viviendaSolicitada.setCodProvincia(resultSet
					.getString("CODPROVINCIA"));
			// Descripcion Provincia
			viviendaSolicitada.setDescProvincia(resultSet
					.getString("DESCPROVINCIA"));
			// Codigo Municipio
			viviendaSolicitada.setCodMunicipio(resultSet
					.getString("CODMUNICIPIO"));
			// Descripcion Municipio
			viviendaSolicitada.setDescMunicipio(resultSet
					.getString("DESCMUNICIPIO"));
			// AbstractM62FBModel
			UtilsResulSet.getAbstractClass(resultSet, viviendaSolicitada,
					ViviendaSolicitadaDaoSql.ALIAS_VIVIENDASOL);

			return viviendaSolicitada;
		}
	};

	/**
	 * Method use to set the datasource.
	 * 
	 * @param dataSource
	 *            DataSource
	 * @return
	 */
	@Resource
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	/*
	 * OPERACIONES CRUD
	 */

	/**
	 * Inserts a single row in the ViviendaSolicitada table.
	 * 
	 * @param viviendaSolicitada
	 *            ViviendaSolicitada
	 * @return ViviendaSolicitada
	 */
	@Override
	public ViviendaSolicitada add(ViviendaSolicitada viviendaSolicitada) {

		String query = ViviendaSolicitadaDaoSql.SQL_INSERT;

		// Preparar Parametros
		List<Object> params = new ArrayList<Object>();

		// IdM62r38t0
		params.add(viviendaSolicitada.getIdM62r38t0());
		// NumOrden
		params.add(viviendaSolicitada.getNumOrden());
		// DesMotivoReserva
		params.add(viviendaSolicitada.getDesMotivoReserva());

		// CodProvincia
		params.add(viviendaSolicitada.getCodProvincia());
		// CodMunicipio
		params.add(viviendaSolicitada.getCodMunicipio());
		// DesReceptor
		params.add(viviendaSolicitada.getDesReceptor());

		// IndVivAdaptada
		params.add(BDUtils.formatIndicadorToBD(viviendaSolicitada
				.getIndVivAdaptada()));
		// NumDormitorios
		params.add(viviendaSolicitada.getNumDormitorios());
		// SupUtilViv
		params.add(viviendaSolicitada.getSupUtilViv());

		// RegimenAcceso
		params.add(viviendaSolicitada.getRegimenAcceso() != null ? viviendaSolicitada
				.getRegimenAcceso().getCodTabla() : null);
		// RegimenTenencia
		params.add(viviendaSolicitada.getRegimenTenencia() != null ? viviendaSolicitada
				.getRegimenTenencia().getCodTabla() : null);
		// TexObservaciones
		params.add(viviendaSolicitada.getTexObservaciones());

		// AbstractM62FBModel (UsuarioPlatea)
		params.add(AppConstantes.USUARIO_APP_PLATEA);

		// Realizar Insert
		this.jdbcTemplate.update(query, params.toArray());

		return viviendaSolicitada;
	}

	/**
	 * Finds a single row in the ViviendaSolicitada table.
	 * 
	 * @param viviendaSolicitada
	 *            ViviendaSolicitada
	 * @return ViviendaSolicitada
	 */
	@Override
	@Transactional(readOnly = true)
	public ViviendaSolicitada find(ViviendaSolicitada viviendaSolicitada) {
		String query = ViviendaSolicitadaDaoSql.SQL_FIND;

		List<ViviendaSolicitada> viviendaSolicitadaList = this.jdbcTemplate
				.query(query, this.rwMap, viviendaSolicitada.getIdM62r40t0());
		return DataAccessUtils.uniqueResult(viviendaSolicitadaList);
	}

	/**
	 * Finds a list of rows in the ViviendaSolicitada table.
	 * 
	 * @param viviendaSolicitada
	 *            ViviendaSolicitada
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @return List<ViviendaSolicitada>
	 */
	@Override
	@Transactional(readOnly = true)
	public List<ViviendaSolicitada> findAll(
			ViviendaSolicitada viviendaSolicitada,
			JQGridRequestDto jqGridRequestDto) {
		StringBuilder query = new StringBuilder(
				ViviendaSolicitadaDaoSql.SQL_FIND_ALL);

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(viviendaSolicitada);
		StringBuilder where = new StringBuilder(
				ViviendaSolicitadaDaoSql.SQL_WHERE_ALL);
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");

		if (jqGridRequestDto != null) {
			query = JQGridManager.getPaginationQuery(jqGridRequestDto, query);
		}

		return this.jdbcTemplate.query(query.toString(), this.rwMap,
				params.toArray());
	}

	/**
	 * Finds rows in the ViviendaSolicitada table using like.
	 * 
	 * @param viviendaSolicitada
	 *            ViviendaSolicitada
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<ViviendaSolicitada>
	 */
	@Override
	@Transactional(readOnly = true)
	public List<ViviendaSolicitada> findAllLike(
			ViviendaSolicitada viviendaSolicitada,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		StringBuilder query = new StringBuilder(
				ViviendaSolicitadaDaoSql.SQL_FIND_ALL);

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(viviendaSolicitada,
				startsWith);
		StringBuilder where = new StringBuilder(
				ViviendaSolicitadaDaoSql.SQL_WHERE_ALL);
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");

		if (jqGridRequestDto != null) {
			query = JQGridManager.getPaginationQuery(jqGridRequestDto, query);
		}

		return this.jdbcTemplate.query(query.toString(), this.rwMap,
				params.toArray());
	}

	/*
	 * OPERACIONES RUP_TABLE
	 */

	/**
	 * Counts rows in the ViviendaSolicitada table.
	 * 
	 * @param viviendaSolicitada
	 *            ViviendaSolicitada
	 * @return Long
	 */
	@Override
	@Transactional(readOnly = true)
	public Long findAllCount(ViviendaSolicitada viviendaSolicitada) {
		StringBuilder query = new StringBuilder(
				ViviendaSolicitadaDaoSql.SQL_FIND_ALL_COUNT);

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(viviendaSolicitada);
		StringBuilder where = new StringBuilder(
				ViviendaSolicitadaDaoSql.SQL_WHERE_ALL);
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");

		return this.jdbcTemplate.queryForLong(query.toString(),
				params.toArray());
	}

	/**
	 * Counts rows in the ViviendaSolicitada table using like.
	 * 
	 * @param viviendaSolicitada
	 *            ViviendaSolicitada
	 * @param startsWith
	 *            Boolean
	 * @return Long
	 */
	@Override
	@Transactional(readOnly = true)
	public Long findAllLikeCount(ViviendaSolicitada viviendaSolicitada,
			Boolean startsWith) {
		StringBuilder query = new StringBuilder(
				ViviendaSolicitadaDaoSql.SQL_FIND_ALL_COUNT);

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(viviendaSolicitada,
				startsWith);
		StringBuilder where = new StringBuilder(
				ViviendaSolicitadaDaoSql.SQL_WHERE_ALL);
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");

		return this.jdbcTemplate.queryForLong(query.toString(),
				params.toArray());
	}

	/*
	 * MÉTODOS PRIVADOS
	 */

	/**
	 * Returns a map with the needed value to create the conditions to filter by
	 * the ViviendaSolicitada entity
	 * 
	 * @param viviendaSolicitada
	 *            ViviendaSolicitada Bean with the criteria values to filter by.
	 * @return Map created with two keys key query stores the sql query syntax
	 *         key params stores the parameter values to be used in the
	 *         condition sentence.
	 */
	private Map<String, ?> getWhereMap(ViviendaSolicitada viviendaSolicitada) {

		StringBuilder where = new StringBuilder(
				ViviendaSolicitadaDaoSql.STRING_BUILDER_INIT);
		List<Object> params = new ArrayList<Object>();

		if (viviendaSolicitada != null) {
			if (viviendaSolicitada.getIdM62r40t0() != null) {
				BDUtils.crearFiltroIgual(where, params,
						"VIVIENDASOL.ID_M62R40T0",
						viviendaSolicitada.getIdM62r40t0());
			}
			if (viviendaSolicitada.getIdM62r38t0() != null) {
				BDUtils.crearFiltroIgual(where, params,
						"VIVIENDASOL.ID_M62R38T0",
						viviendaSolicitada.getIdM62r38t0());
			}
		}

		Map<String, Object> mapWhere = new HashMap<String, Object>();
		mapWhere.put("query", where);
		mapWhere.put("params", params);

		return mapWhere;
	}

	/**
	 * Returns a map with the needed value to create the conditions to filter by
	 * the ViviendaSolicitada entity
	 * 
	 * @param viviendaSolicitada
	 *            ViviendaSolicitada Bean with the criteria values to filter by.
	 * @param startsWith
	 *            Boolean
	 * @return Map created with two keys key query stores the sql query syntax
	 *         key params stores the parameter values to be used in the
	 *         condition sentence.
	 */
	private Map<String, Object> getWhereLikeMap(
			ViviendaSolicitada viviendaSolicitada, Boolean startsWith) {

		StringBuilder where = new StringBuilder(
				ViviendaSolicitadaDaoSql.STRING_BUILDER_INIT);
		List<Object> params = new ArrayList<Object>();

		if (viviendaSolicitada != null) {
			if (viviendaSolicitada.getIdM62r40t0() != null) {
				BDUtils.crearFiltroIgual(where, params,
						"VIVIENDASOL.ID_M62R40T0",
						viviendaSolicitada.getIdM62r40t0());
			}
			if (viviendaSolicitada.getIdM62r38t0() != null) {
				BDUtils.crearFiltroIgual(where, params,
						"VIVIENDASOL.ID_M62R38T0",
						viviendaSolicitada.getIdM62r38t0());
			}
		}

		Map<String, Object> mapWhere = new HashMap<String, Object>();
		mapWhere.put("query", where);
		mapWhere.put("params", params);

		return mapWhere;
	}
}