package com.ejie.ad74a.dao;

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

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.ad74a.model.DocumentosMedicos;
import com.ejie.ad74a.util.UtilSQL;
import com.ejie.x38.dao.RowNumResultSetExtractor;
import com.ejie.x38.dto.TableManager;
import com.ejie.x38.dto.TableRequestDto;
import com.ejie.x38.dto.TableRowDto;

/**
 * DocumentosMedicosDaoImpl generated by UDA, 05-nov-2024 8:45:47.
 * 
 * @author UDA
 */
@Repository
@Transactional
public class DocumentosMedicosDaoImpl implements DocumentosMedicosDao {

	public static final String[] ORDER_BY_WHITE_LIST = new String[] { "IDEXPEDIENTE00", "OIDDOKUSI18", "NOMBREDOC18" };
	private JdbcTemplate jdbcTemplate;

	/*
	 * ROW_MAPPER
	 */
	private RowMapper<DocumentosMedicos> rwMap = new DocumentosMedicosRwMap();

	private static class DocumentosMedicosRwMap implements RowMapper<DocumentosMedicos> {
		@Override
		public DocumentosMedicos mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			DocumentosMedicos documentosmedicos = new DocumentosMedicos();
			documentosmedicos.setIdExpediente00(UtilSQL.getLong(resultSet, "IDEXPEDIENTE00"));
			documentosmedicos.setOiddokusi18(resultSet.getString("OIDDOKUSI18"));
			documentosmedicos.setNombreDoc18(resultSet.getString("NOMBREDOC18"));

			return documentosmedicos;
		}
	}

	private RowMapper<DocumentosMedicos> rwMapPK = new RowMapper<DocumentosMedicos>() {
		public DocumentosMedicos mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			// El ID tabla/vista importante para el reorder con alguna row seleccionada
			DocumentosMedicos documentosmedicos = new DocumentosMedicos();
			documentosmedicos.setIdExpediente00(UtilSQL.getLong(resultSet, "IDEXPEDIENTE00"));
			return documentosmedicos;
		}
	};

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

	/*
	 * OPERACIONES CRUD
	 */

	/**
	 * Finds a single row in the DocumentosMedicos table.
	 *
	 * @param documentosmedicos DocumentosMedicos
	 * @return DocumentosMedicos
	 */
	@Transactional(readOnly = true)
	public DocumentosMedicos find(DocumentosMedicos documentosmedicos) {
		String query = DocumentosMedicosDaoSql.SQL_FIND;
		List<DocumentosMedicos> documentosmedicosList = this.jdbcTemplate.query(query, this.rwMap,
				documentosmedicos.getIdExpediente00());
		return DataAccessUtils.uniqueResult(documentosmedicosList);
	}

	/**
	 * Finds rows in the DocumentosMedicos table using like.
	 *
	 * @param documentosmedicos DocumentosMedicos
	 * @param TableRequestDto   TableRequestDto
	 * @return List<DocumentosMedicos>
	 */
	@Transactional(readOnly = true)
	public List<DocumentosMedicos> findAllLike(DocumentosMedicos documentosmedicos, TableRequestDto tableRequestDto) {

		StringBuilder query = new StringBuilder(DocumentosMedicosDaoSql.SQL_FIND_ALL);
		List<Object> params = new ArrayList<Object>();

		// Where clause & Params
		query.append(DocumentosMedicosDaoSql.SQL_WHERE_ALL);
		query.append(this.getWhere(documentosmedicos, params));

		if (tableRequestDto != null) {
			query = TableManager.getPaginationQuery(tableRequestDto, query,
					DocumentosMedicosDaoImpl.ORDER_BY_WHITE_LIST);
		}
		return this.jdbcTemplate.query(query.toString(), this.rwMap, params.toArray());
	}

	/**
	 * Counts rows in the DocumentosMedicos table using like.
	 *
	 * @param documentosmedicos DocumentosMedicos
	 * @return Long
	 */
	@Transactional(readOnly = true)
	public Long findAllLikeCount(DocumentosMedicos documentosmedicos) {

		StringBuilder query = new StringBuilder(DocumentosMedicosDaoSql.SQL_FIND_ALL_COUNT);
		List<Object> params = new ArrayList<Object>();

		// Where clause & Params
		query.append(DocumentosMedicosDaoSql.SQL_WHERE_ALL);
		query.append(this.getWhere(documentosmedicos, params));

		return this.jdbcTemplate.queryForObject(query.toString(), Long.class, params.toArray());
	}

	/**
	 * Reorder the data list of DocumentosMedicos selected for rup_table
	 *
	 * @param documentosmedicos DocumentosMedicos
	 * @param tableRequestDto   TableRequestDto
	 * @return List<TableRowDto<DocumentosMedicos>>
	 */
	@Override
	public List<TableRowDto<DocumentosMedicos>> reorderSelection(DocumentosMedicos documentosmedicos,
			TableRequestDto tableRequestDto) {
		// SELECT
		StringBuilder query = new StringBuilder(DocumentosMedicosDaoSql.SQL_FIND_ALL);
		List<Object> params = new ArrayList<Object>();

		// FILTRADO
		// Where clause & Params
		query.append(DocumentosMedicosDaoSql.SQL_WHERE_ALL);
		query.append(this.getWhere(documentosmedicos, params));

		// SQL para la reordenación
		StringBuilder sbReorderSelectionSQL = TableManager.getReorderQuery(query, tableRequestDto,
				DocumentosMedicos.class, params, DocumentosMedicosDaoSql.ALIAS_ID_TABLA);

		return this.jdbcTemplate.query(sbReorderSelectionSQL.toString(),
				new RowNumResultSetExtractor<DocumentosMedicos>(this.rwMapPK, tableRequestDto), params.toArray());
	}

	/**
	 * Search method for rup_table
	 *
	 * @param filterParams    DocumentosMedicos
	 * @param searchParams    DocumentosMedicos
	 * @param tableRequestDto TableRequestDto
	 * @param startsWith      Boolean
	 * @return List<TableRowDto<DocumentosMedicos>>
	 */
	@Override
	public List<TableRowDto<DocumentosMedicos>> search(DocumentosMedicos filter, DocumentosMedicos search,
			TableRequestDto tableRequestDto) {
		StringBuilder query = new StringBuilder(DocumentosMedicosDaoSql.SQL_FIND_ALL);
		List<Object> params = new ArrayList<Object>();
		List<Object> searchParams = new ArrayList<Object>();

		// TABLAS_ALIAS
		List<String> fromAlias = new ArrayList<String>();
		fromAlias.add(DocumentosMedicosDaoSql.ALIAS_DOCUMENTOSMEDICOS);

		// FILTRADO
		// Where clause & Params
		query.append(DocumentosMedicosDaoSql.SQL_WHERE_ALL);
		query.append(this.getWhere(filter, params));

		// BUSQUEDA
		String searchSQL = this.getWhere(search, searchParams);

		// SQL
		StringBuilder sbReorderSelectionSQL = TableManager.getSearchQuery(query, tableRequestDto,
				DocumentosMedicos.class, params, searchSQL, searchParams, fromAlias,
				DocumentosMedicosDaoSql.ALIAS_ID_TABLA);

		return this.jdbcTemplate.query(sbReorderSelectionSQL.toString(),
				new RowNumResultSetExtractor<DocumentosMedicos>(this.rwMapPK, tableRequestDto), params.toArray());
	}

	/*
	 * MÉTODOS PRIVADOS
	 */

	/**
	 * Returns a map with the needed value to create the conditions to filter by the
	 * DocumentosMedicos entity
	 *
	 * @param documentosmedicos DocumentosMedicos 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.
	 */
	// CHECKSTYLE:OFF CyclomaticComplexity - Generación de código de UDA
	private String getWhere(DocumentosMedicos documentosmedicos, List<Object> params) {
		StringBuilder where = new StringBuilder(DocumentosMedicosDaoImpl.STRING_BUILDER_INIT);

		if (documentosmedicos != null) {
			where.append(
					UtilsSQL.generarWhereIgual(DocumentosMedicosDaoSql.ALIAS_DOCUMENTOSMEDICOS + ".ID_EXPEDIENTE_00",
							documentosmedicos.getIdExpediente00(), params));
			where.append(UtilsSQL.generarWhereLike(DocumentosMedicosDaoSql.ALIAS_DOCUMENTOSMEDICOS + ".OIDDOKUSI_18",
					documentosmedicos.getOiddokusi18(), params));
			where.append(UtilsSQL.generarWhereLike(DocumentosMedicosDaoSql.ALIAS_DOCUMENTOSMEDICOS + ".NOMBRE_DOC_18",
					documentosmedicos.getNombreDoc18(), params));

		}

		return where.toString();
	}

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

	private static class UtilsSQL {
		public static String generarWhereIgual(String campo, Object valor, List<Object> params) {
			StringBuilder query = new StringBuilder(DocumentosMedicosDaoImpl.STRING_BUILDER_INIT);
			if (null != valor) {
				query.append(" AND ").append(campo).append(" = ? ");
				params.add(valor);
			}

			return query.toString();
		}

		public static String generarWhereLike(String campo, String valor, List<Object> params) {
			StringBuilder query = new StringBuilder(DocumentosMedicosDaoImpl.STRING_BUILDER_INIT);
			if (null != valor) {
				query.append(" AND UPPER(").append(campo).append(") LIKE ? ESCAPE  '\\'");
				params.add("%" + valor.toUpperCase() + "%");
				query.append(" AND ").append(campo).append(" IS NOT NULL ");
			}

			return query.toString();
		}
	}
}
