package com.ejie.ad74a.dao.iml;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
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.ParameterizedPreparedStatementSetter;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.ejie.ad74a.dao.NotifPostalesDao;
import com.ejie.ad74a.model.NotifPostales;
import com.ejie.x38.dto.TableManager;
import com.ejie.x38.dto.TableRequestDto;

/**
 * NotifPostalesDaoImpl generated by UDA, 09-ene-2024 16:08:21.
 * 
 * @author UDA
 */

@Repository
@Transactional
public class NotifPostalesDaoImpl implements NotifPostalesDao {

	private static final String QUERY_WHERE = "query";
	private static final String PARAMS_WHERE = "params";

	protected static final String[] ORDER_BY_WHITE_LIST = new String[] { "IDNOTIFPOSTAL88", "TIPONOT88",
			"IDTAREATRAM88", "IDENVIOPOSTAL88", "IDCOLECCIONPOSTAL88", "POSTALINBOXID88", "CODSITUACIONPOSTAL88",
			"FECHASITUACION88", "FINALIZADA88", "SITUACIONPOSTALES88", "SITUACIONPOSTALEU88", "FREGISTRO11",
			"NUMEXPEDIENTE00", "DESCES37", "DESCEU37", "IDENTIFICADOR01", "NOMBRE01", "APELLIDO101", "APELLIDO201" };

	private JdbcTemplate jdbcTemplate;

	public static final String SEQUENCE_NOTIFPOSTALES = "SEQ_NOTIF_POSTALES";
	private static final String SELECT_FROM = "SELECT t1.ID_NOTIF_POSTAL_88 IDNOTIFPOSTAL88, t1.TIPO_NOT_88 TIPONOT88, t1.ID_TAREA_TRAM_88 IDTAREATRAM88, "
			+ "t1.ID_ENVIO_POSTAL_88 IDENVIOPOSTAL88, t1.ID_COLECCION_POSTAL_88 IDCOLECCIONPOSTAL88, "
			+ "t1.POSTAL_INBOX_ID_88 POSTALINBOXID88, t1.COD_SITUACION_POSTAL_88 CODSITUACIONPOSTAL88, "
			+ "t1.FECHA_SITUACION_88 FECHASITUACION88, t1.FINALIZADA_88 FINALIZADA88, "
			+ "t1.SITUACION_POSTAL_ES_88 SITUACIONPOSTALES88, t1.SITUACION_POSTAL_EU_88 SITUACIONPOSTALEU88 "
			+ "FROM NOTIF_POSTALES t1 ";

	/*
	 * ROW_MAPPERS
	 */
	private RowMapper<NotifPostales> rwMap = new RowMapper<NotifPostales>() {
		public NotifPostales mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			// Datos del solicitante...
			// Datos de expediente...
			// Datos de tramite...
			// Datos de tarea...
			// Datos de la notificacion postal
			return new NotifPostales(resultSet.getLong("IDNOTIFPOSTAL88"), resultSet.getString("TIPONOT88"),
					resultSet.getInt("IDENVIOPOSTAL88"), resultSet.getInt("IDCOLECCIONPOSTAL88"),
					resultSet.getString("POSTALINBOXID88"), resultSet.getString("CODSITUACIONPOSTAL88"),
					resultSet.getDate("FECHASITUACION88"), resultSet.getInt("FINALIZADA88"),
					resultSet.getString("SITUACIONPOSTALES88"), resultSet.getString("SITUACIONPOSTALEU88"));
		}
	};

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

	/*
	 * OPERACIONES CRUD
	 */

	private static final String UPDATE_QUERY = "UPDATE NOTIF_POSTALES SET COD_SITUACION_POSTAL_88=?, FECHA_SITUACION_88=?, FINALIZADA_88=?, SITUACION_POSTAL_ES_88=?, SITUACION_POSTAL_EU_88=? WHERE ID_NOTIF_POSTAL_88=?";

	/**
	 * Updates a single row in the NotifPostales table.
	 *
	 * @param notifpostales NotifPostales
	 * @return NotifPostales
	 */
	@Override
	public NotifPostales update(NotifPostales notifpostales) {
		this.jdbcTemplate.update(UPDATE_QUERY, notifpostales.getCodSituacionPostal88(),
				notifpostales.getFechaSituacion88(), notifpostales.getFinalizada88(),
				notifpostales.getSituacionPostalEs88(), notifpostales.getSituacionPostalEu88(),
				notifpostales.getIdNotifPostal88());
		return notifpostales;
	}

	@Override
	public List<NotifPostales> updateMultiple(List<NotifPostales> notifPostalesList) {
		this.jdbcTemplate.batchUpdate(UPDATE_QUERY, notifPostalesList, notifPostalesList.size(),
				new ParameterizedPreparedStatementSetter<NotifPostales>() {
					@Override
					public void setValues(PreparedStatement ps, NotifPostales item) throws SQLException {
						int i = 1;
						ps.setObject(i++, item.getCodSituacionPostal88());
						ps.setObject(i++, getSQLDate(item.getFechaSituacion88()));
						ps.setObject(i++, item.getFinalizada88());
						ps.setObject(i++, item.getSituacionPostalEs88());
						ps.setObject(i++, item.getSituacionPostalEu88());
						ps.setObject(i, item.getIdNotifPostal88());
					}

					/*
					 * Prepara una fecha para ponerla en los parametros
					 */
					private java.sql.Date getSQLDate(Date date) {
						if (date != null) {
							return new java.sql.Date(date.getTime());
						}
						return null;
					}
				});
		return notifPostalesList;
	}

	/**
	 * Finds a single row in the NotifPostales table.
	 *
	 * @param notifpostales NotifPostales
	 * @return NotifPostales
	 */
	@Override
	@Transactional(readOnly = true)
	public NotifPostales find(NotifPostales notifpostales) {
		StringBuilder query = new StringBuilder(STRING_BUILDER_INIT);
		query.append(SELECT_FROM);
		query.append(" WHERE t1.ID_NOTIF_POSTAL_88 = ?  ");
		List<NotifPostales> notifpostalesList = this.jdbcTemplate.query(query.toString(), this.rwMap,
				notifpostales.getIdNotifPostal88());
		return DataAccessUtils.uniqueResult(notifpostalesList);
	}

	/**
	 * Finds rows in the NotifPostales table using like.
	 *
	 * @param notifpostales   NotifPostales
	 * @param tableRequestDto TableRequestDto
	 * @param startsWith      Boolean
	 * @return List<NotifPostales>
	 */
	@Override
	@Transactional(readOnly = true)
	public List<NotifPostales> findAllLike(NotifPostales notifpostales, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		StringBuilder query = new StringBuilder(STRING_BUILDER_INIT);
		query.append(SELECT_FROM);

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(notifpostales, startsWith);
		StringBuilder where = new StringBuilder(STRING_BUILDER_INIT);
		where.append(" WHERE 1=1 ");
		where.append(mapaWhere.get(QUERY_WHERE));
		query.append(where);

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

		if (tableRequestDto != null) {
			query = TableManager.getPaginationQuery(tableRequestDto, query, NotifPostalesDaoImpl.ORDER_BY_WHITE_LIST);
		}

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

	/**
	 * Counts rows in the NotifPostales table using like.
	 *
	 * @param notifpostales NotifPostales
	 * @param startsWith    Boolean
	 * @return Long
	 */
	@Override
	@Transactional(readOnly = true)
	public Long findAllLikeCount(NotifPostales notifpostales, Boolean startsWith) {
		StringBuilder query = new StringBuilder("SELECT COUNT(1) FROM NOTIF_POSTALES t1, TAREAS_TRAMITE t2, ");
		query.append("TRAMITES_EXPEDIENTE t3, EXPEDIENTES t4, MAESTRO_TRAMITES t5, SOLICITANTES t6 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(notifpostales, startsWith);
		StringBuilder where = new StringBuilder(STRING_BUILDER_INIT);
		where.append("WHERE 1=1 ");
		where.append(mapaWhere.get(QUERY_WHERE));
		query.append(where);

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

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

	/*
	 * MÉTODOS PRIVADOS
	 */

	/**
	 * Returns a map with the needed value to create the conditions to filter by the
	 * NotifPostales entity
	 *
	 * @param notifpostales   NotifPostales Bean with the criteria values to filter
	 *                        by.
	 * @param startsWithParam 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.
	 */
	// CHECKSTYLE:OFF CyclomaticComplexity - Generación de código de UDA
	@SuppressWarnings({ "java:S3776", "squid:MethodCyclomaticComplexity", "squid:S138" })
	private Map<String, Object> getWhereLikeMap(NotifPostales notifpostales, Boolean startsWithParam) {
		boolean startsWith = startsWithParam == null ? Boolean.FALSE : startsWithParam.booleanValue();
		StringBuilder where = new StringBuilder(NotifPostalesDaoImpl.STRING_BUILDER_INIT);
		List<Object> params = new ArrayList<>();

		if (notifpostales != null && notifpostales.getIdNotifPostal88() != null) {
			where.append(" AND t1.ID_NOTIF_POSTAL_88 = ?");
			params.add(notifpostales.getIdNotifPostal88());
		}
		if (notifpostales != null && notifpostales.getTipoNot88() != null) {
			where.append(" AND t1.TIPO_NOT_88 = ?");
			params.add(notifpostales.getTipoNot88());
		}
		if (notifpostales != null && notifpostales.getIdEnvioPostal88() != null) {
			where.append(" AND t1.ID_ENVIO_POSTAL_88 = ?");
			params.add(notifpostales.getIdEnvioPostal88());
		}
		if (notifpostales != null && notifpostales.getIdColeccionPostal88() != null) {
			where.append(" AND t1.ID_COLECCION_POSTAL_88 = ?");
			params.add(notifpostales.getIdColeccionPostal88());
		}
		if (notifpostales != null && notifpostales.getPostalInboxId88() != null) {
			where.append(" AND UPPER(t1.POSTAL_INBOX_ID_88) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(notifpostales.getPostalInboxId88().toUpperCase() + "%");
			} else {
				params.add("%" + notifpostales.getPostalInboxId88().toUpperCase() + "%");
			}
			where.append(" AND t1.POSTAL_INBOX_ID_88 IS NOT NULL");
		}
		if (notifpostales != null && notifpostales.getCodSituacionPostal88() != null) {
			where.append(" AND UPPER(t1.COD_SITUACION_POSTAL_88) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(notifpostales.getCodSituacionPostal88().toUpperCase() + "%");
			} else {
				params.add("%" + notifpostales.getCodSituacionPostal88().toUpperCase() + "%");
			}
			where.append(" AND t1.COD_SITUACION_POSTAL_88 IS NOT NULL");
		}
		if (notifpostales != null && notifpostales.getFechaSituacion88() != null) {
			where.append(" AND t1.FECHA_SITUACION_88 = ?");
			params.add(notifpostales.getFechaSituacion88());
		}
		if (notifpostales != null && notifpostales.getFinalizada88() != null) {
			where.append(" AND t1.FINALIZADA_88 = ?");
			params.add(notifpostales.getFinalizada88());
		}
		if (notifpostales != null && notifpostales.getSituacionPostalEs88() != null) {
			where.append(" AND UPPER(t1.SITUACION_POSTAL_ES_88) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(notifpostales.getSituacionPostalEs88().toUpperCase() + "%");
			} else {
				params.add("%" + notifpostales.getSituacionPostalEs88().toUpperCase() + "%");
			}
			where.append(" AND t1.SITUACION_POSTAL_ES_88 IS NOT NULL");
		}
		if (notifpostales != null && notifpostales.getSituacionPostalEu88() != null) {
			where.append(" AND UPPER(t1.SITUACION_POSTAL_EU_88) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(notifpostales.getSituacionPostalEu88().toUpperCase() + "%");
			} else {
				params.add("%" + notifpostales.getSituacionPostalEu88().toUpperCase() + "%");
			}
			where.append(" AND t1.SITUACION_POSTAL_EU_88 IS NOT NULL");
		}

		// Otros campos de filtrado

		if (notifpostales != null && notifpostales.getFechaRegistroInicio() != null) {
			where.append(" AND t2.F_REGISTRO_11 >= ?");
			params.add(notifpostales.getFechaRegistroInicio());
		}
		if (notifpostales != null && notifpostales.getFechaRegistroFin() != null) {
			where.append(" AND t2.F_REGISTRO_11 <= ?");
			params.add(notifpostales.getFechaRegistroFin());
		}
		if (notifpostales != null && notifpostales.getFechaSituacionInicio() != null) {
			where.append(" AND t1.FECHA_SITUACION_88 >= ?");
			params.add(notifpostales.getFechaSituacionInicio());
		}
		if (notifpostales != null && notifpostales.getFechaSituacionFin() != null) {
			where.append(" AND t1.FECHA_SITUACION_88 <= ?");
			params.add(notifpostales.getFechaSituacionFin());
		}
		//El registro debe tener id_envio informado
		if (notifpostales != null && notifpostales.isConIdEnvioInformado()) {
			where.append(" AND t1.ID_ENVIO_POSTAL_88 IS NOT NULL");
		}

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

		return mapWhere;
	}
	// CHECKSTYLE:ON CyclomaticComplexity - Generación de código de UDA

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