/**
 * 
 */
package com.ejie.ad74a.dao.iml;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.Optional;

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

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import com.ejie.ad74a.dao.PrecioDao;
import com.ejie.ad74a.model.PrecioBeneficiario;
import com.ejie.ad74a.model.PrecioPublico;

/**
 * Implementacion de la capa de persistencia para las entidades: 
 * AD74A77T00 PRECIOS_PUBLICOS y AD74A91T00 PRECIOS_BENEFICIARIO
 * @author BICUGUAL
 *
 */
@Repository
public class PrecioDaoImpl implements PrecioDao {

	public static final String T_PRECIOS_PUBLICOS = "AD74A.AD74A77T00";
	public static final String T_PRECIOS_BENEFICIARIO = "AD74A.AD74A91T00";
	
	JdbcTemplate jdbcTemplate;
	
	@Resource
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}
	
	
	
	@Override
	public Optional<PrecioPublico> findPrecioPublicoByFInicioMes(Date fInicioMes, Date fFinMes) {
		
		try {
			
			String sql = "SELECT ID_PRECIO_PUBLICO_77, "
							+ "F_VIGENCIA_DESDE_77, "
							+ "F_VIGENCIA_HASTA_77, "
							+ "PRECIO_PUBLICO_77 "
						+ "FROM "+ T_PRECIOS_PUBLICOS +" p "
						+ "WHERE F_VIGENCIA_DESDE_77 <= ? "
							+ "AND (F_VIGENCIA_HASTA_77 IS NULL OR F_VIGENCIA_HASTA_77 > ?) "
						+ "ORDER BY F_VIGENCIA_DESDE_77";
		
			return Optional.ofNullable(jdbcTemplate.queryForObject(sql, new PrecioPublicoMapper(), fFinMes, fInicioMes));
			
		} catch (DataAccessException e) {
			return Optional.empty();
		}
		
	}
	
	@Override
	public List<PrecioPublico> findAllPreciosPublicos() {
		
		String sql = "SELECT "
				+ "ID_PRECIO_PUBLICO_77, "
				+ "F_VIGENCIA_DESDE_77, "
				+ "F_VIGENCIA_HASTA_77, "
				+ "PRECIO_PUBLICO_77 "
			+ "FROM "+ T_PRECIOS_PUBLICOS + " p "
			+ "ORDER BY F_VIGENCIA_DESDE_77";
		
		return jdbcTemplate.query(sql, new PrecioPublicoMapper());
	}
	
	@Override
	public List<PrecioBeneficiario> findPreciosBeneficiarioByIdSolicitanteAndFInicioMes(Long idSolicitante, Date fInicioMes, Date fFinMes) {
		
		String sql = "SELECT "
						+ "ID_PRECIO_BENEFICIARIO_91, "
						+ "ID_SOLICITANTE_91, "
						+ "IND_EXENTO_91, "
						+ "PRECIO_PRIVADO_91, "
						+ "FECHA_INICIO_91, "
						+ "FECHA_FIN_91 "
					+ "FROM "+ T_PRECIOS_BENEFICIARIO + " p "
					+ "WHERE ID_SOLICITANTE_91 = ? "
						+ " AND FECHA_INICIO_91 <= ? "
						+ "AND (FECHA_FIN_91 IS NULL OR FECHA_FIN_91 > ? ) "
					+ "ORDER BY FECHA_INICIO_91";

		return jdbcTemplate.query(sql, new PrecioBeneficiarioMapper(), idSolicitante, fFinMes, fInicioMes);

	}
	
	/**
	 * Mapper para precio publico del servicio
	 * @author BICUGUAL
	 *
	 */
	private class PrecioPublicoMapper implements RowMapper<PrecioPublico> {
		
		public PrecioPublico mapRow(ResultSet rs, int rowNum) throws SQLException {
			
			PrecioPublico item = new PrecioPublico();
			item.setIdPrecioPublico(rs.getLong("ID_PRECIO_PUBLICO_77"));
			item.setfVigenciaDesde(null != rs.getDate("F_VIGENCIA_DESDE_77") ? rs.getDate("F_VIGENCIA_DESDE_77").toLocalDate() : null);
			item.setfVigenciaHasta(null != rs.getDate("F_VIGENCIA_HASTA_77") ? rs.getDate("F_VIGENCIA_HASTA_77").toLocalDate() : null);
			item.setImporte(rs.getBigDecimal("PRECIO_PUBLICO_77"));
			
			return item;
		}
	}
	
	/**
	 * Mapper para precios privados del servicio
	 * @author BICUGUAL
	 *
	 */
	private class PrecioBeneficiarioMapper implements RowMapper<PrecioBeneficiario> {
		
		public PrecioBeneficiario mapRow(ResultSet rs, int rowNum) throws SQLException {
			
			PrecioBeneficiario item = new PrecioBeneficiario();
			item.setIdPrecioBeneficiario(rs.getLong("ID_PRECIO_BENEFICIARIO_91"));
			item.setIdSolicitante(rs.getLong("ID_SOLICITANTE_91"));
			item.setFechaInicio(null != rs.getDate("FECHA_INICIO_91") ? rs.getDate("FECHA_INICIO_91").toLocalDate() : null);
			item.setFechaFin(null != rs.getDate("FECHA_FIN_91") ? rs.getDate("FECHA_FIN_91").toLocalDate() : null);
			item.setIndExento(0 == rs.getInt("IND_EXENTO_91") ? Boolean.FALSE : Boolean.TRUE);
			item.setPrecioPrivado(item.getIndExento().booleanValue() ? BigDecimal.ZERO : rs.getBigDecimal("PRECIO_PRIVADO_91"));
			
			return item;
		}
	}
}
