package com.ejie.ad74a.dao.iml;

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

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.dao.SolicitantesDao;
import com.ejie.ad74a.model.Ad74aBeneficiarioDFBBean;
import com.ejie.ad74a.model.Direcciones;
import com.ejie.ad74a.model.Solicitantes;
import com.ejie.ad74a.util.UtilSQL;
import com.ejie.ad74a.util.constantes.ConstantesBatch;

/**
 * SolicitantesDaoImpl generated by UDA, 10-feb-2023 12:13:19.
 * 
 * @author UDA
 */

@Repository
@Transactional
public class SolicitantesDaoImpl implements SolicitantesDao {
	
	private static final Logger logger = LoggerFactory.getLogger(SolicitantesDaoImpl.class);

	public static final String[] ORDER_BY_WHITE_LIST = new String[] { "IDSOLICITANTE01", "TIPOIDENTIFICADOR01",
			"IDENTIFICADOR01", "NOMBRE01", "APELLIDO101", "APELLIDO201", "SEXO01", "FNACIMIENTO01", "NUMSS01",
			"NUMTIS01", "FALTATELEASISTENCIA01", "BENEFICIARIO01", "FBENEFICIARIO01", "FBAJA01", "FINICIO01",
			"NUMABONADO01", "OBSERVACIONES01", "NOREINTENTAR01", "IDIOMASERVICIO01", "IDIOMASOLICITANTE01",
			"OTROIDIOMA01", "TLFNOSERVICIO01", "TLFNOMOVIL01", "EMAIL01", "TIPOBENEFICIARIO01", "FRETIRADA01",
			"MANTENERINST01", "EXENCION01", "EXONERACION01", "INSTALADO01", "IDMOTIVOBAJA01", "USUALTA01", "USUMODIF01",
			"FALTA01", "FMODIF01", "CUENTASIDCUENTA05", "CUENTASNUMCUENTA05", "CUENTASCODTIPOIDENTITULAR05",
			"CUENTASIDENTITULAR05", "CUENTASIDSOLICITANTE05", "CUENTASUSUHISTORICO05", "CUENTASFHISTORICO05",
			"CUENTASFALTA05", "CUENTASUSUALTA05", "PERFILESIDPERFIL07", "PERFILESMAYOR65DEP07",
			"PERFILESMAYOR65RIESGODEP07", "PERFILESMAYOR75SOLA07", "PERFILESDISINTELECTUAL07", "PERFILESDISFISICA07",
			"PERFILESDISSENSORIAL07", "PERFILESENFMENTAL07", "PERFILESRIESGOAISLAMIENTO07", "PERFILESPISOTUTELADO07",
			"PERFILESFALTA07", "PERFILESUSUALTA07", "DIRECCIONESIDDIRECCION06", "DIRECCIONESCALLE06", "DIRECCIONESCP06",
			"DIRECCIONESIDCALLE06", "DIRECCIONESIDLOCALIDAD06", "DIRECCIONESIDMUNICIPIO06", "DIRECCIONESIDPAIS06",
			"DIRECCIONESIDPORTAL06", "DIRECCIONESIDPROVINCIA06", "DIRECCIONESLETRA06", "DIRECCIONESLOCALIDAD06",
			"DIRECCIONESMUNICIPIO06", "DIRECCIONESPAIS06", "DIRECCIONESPISO06", "DIRECCIONESPORTAL06",
			"DIRECCIONESESCALERA06", "DIRECCIONESPROVINCIA06", "DIRECCIONESIDSOLICITANTE06",
			"DIRECCIONESUSUHISTORICO06", "DIRECCIONESFHISTORICO06", "DIRECCIONESFALTA06", "DIRECCIONESUSUALTA06",
			"PERFILESIDPISO07", "VALIDVALORACION08", "VALFVALORACION08", "VALTIPOVALORACION08",
			"VALCONTRATOACTUACION08", "VALMODOVALORACION08", "VALIDNIVELSOPORTE08", "VALALTORIESGO08",
			"VALNIVELMALTRATO08", "VALNIVELSUICIDIO08", "VALPERIODICIDADPROPUESTA08", "VALPERIODICIDADACORDADA08",
			"VALPROPUESTAACEPTADA08", "VALIDSOLICITANTE08", "VALUSUHISTORICO08", "VALFHISTORICO08", "VALFALTA08",
			"VALUSUALTA08", "ValMOTIVORETRASO08" };

	private JdbcTemplate jdbcTemplate;

	public static final String SEQUENCE_SOLICITANTE = "SEQ_SOLICITANTES";
	public static final String SEQUENCE_NUM_ABONADO = "SEQ_NUM_ABONADO";

	private RowMapper<Solicitantes> rwMapPKPago = new RowMapper<Solicitantes>() {
		public Solicitantes mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			Solicitantes sol = new Solicitantes(UtilSQL.getLong(resultSet, "IDSOLICITANTE01"));
			sol.setfInicio01(resultSet.getDate("FINICIO01"));
			sol.setfBajaPs01(resultSet.getDate("F_BAJA_PS_01"));
			return sol;
		}
	};
	
	private RowMapper<Ad74aBeneficiarioDFBBean> rwMapBeneficiariosDDFF = new RowMapper<Ad74aBeneficiarioDFBBean>() {
		
		public Ad74aBeneficiarioDFBBean mapRow(ResultSet resultSet, int rowNum) throws SQLException {

			
			return new Ad74aBeneficiarioDFBBean(UtilSQL.getLong(resultSet, "IDSOLICITANTE"),
					resultSet.getString("TIPOIDENTIFICADOR"),
					resultSet.getString("IDENTIFICADOR"),
					resultSet.getString("NOMBRE"),
					resultSet.getString("APELLIDO1"),
					resultSet.getString("APELLIDO2"),
					resultSet.getDate("FAPERTURA"),
					resultSet.getDate("FBENEFICIARIO"),
					resultSet.getDate("FBAJA"),
					UtilSQL.getLong(resultSet, "IDMOTIVOBAJA"),
					resultSet.getBigDecimal("PRECIOPUBLICO")
					);
		}
	};
	
	private RowMapper<Solicitantes> rwMapDepDisMasiva = new RowMapper<Solicitantes>() {
		public Solicitantes mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			Solicitantes sol = new Solicitantes(UtilSQL.getLong(resultSet, "IDSOLICITANTE01"));
			sol.setIdentificador01(resultSet.getString("IDENTIFICADOR01"));
			sol.setTipoIdentificador01(resultSet.getString("TIPOIDENTIFICADOR"));
			sol.setNombre01(resultSet.getString("NOMBRE"));
			sol.setApellido101(resultSet.getString("APELLIDO1"));
			sol.setApellido201(resultSet.getString("APELLIDO2"));
			Direcciones dir = new Direcciones();
			dir.setProvincia06(resultSet.getString("IDPROVINCIA06"));			
			sol.setDirecciones(dir);
			sol.setfNacimiento01(resultSet.getDate("FNACIMIENTO01"));
			sol.setIdExpediente00(resultSet.getLong("IDEXPEDIENTE00"));
			return sol;
		}
	};
	
	private RowMapper<Solicitantes> rwMapByDni = new RowMapper<Solicitantes>() {
		public Solicitantes mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			Solicitantes sol = new Solicitantes(UtilSQL.getLong(resultSet, "IDSOLICITANTE01"));	
			sol.setIdExpediente00(UtilSQL.getLong(resultSet, "IDEXPEDIENTE00"));
			return sol;
		}
	};
	private RowMapper<Solicitantes> rwMapByDniBaja = new RowMapper<Solicitantes>() {
		public Solicitantes mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			Solicitantes sol = new Solicitantes(UtilSQL.getLong(resultSet, "IDSOLICITANTE01"));	
			sol.setIdExpediente00(UtilSQL.getLong(resultSet, "IDEXPEDIENTE00"));
			sol.setfBaja01(resultSet.getDate("FBAJA01"));
			return sol;
		}
	};
	/**
	 * Method use to set the datasource.
	 *
	 * @param dataSource DataSource
	 * @return
	 */
	@Resource
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}


	/**
	 * Buscar beneficiarios para utilizar en pagos.
	 * 
	 * @param fechaInicio Date
	 * @param fechaFin    Date
	 * @return List<Solicitantes>
	 */
	@Transactional(readOnly = true)
	public List<Solicitantes> findBeneficiariosPago(Date fechaInicio, Date fechaFin) {
		StringBuilder query = new StringBuilder(
				"SELECT ID_SOLICITANTE_01 IDSOLICITANTE01, F_INICIO_01 FINICIO01, F_BAJA_PS_01 F_BAJA_PS_01 FROM SOLICITANTES");
		query.append(" WHERE BENEFICIARIO_01 = '1'");
		query.append(" AND F_INICIO_01 IS NOT NULL AND F_INICIO_01 <= ?");
		query.append(" AND (F_BAJA_PS_01 IS NULL OR (F_BAJA_PS_01 IS NOT NULL AND F_BAJA_PS_01 > ?))");//Fecha de baja de la prestadora.
		//query.append(" AND id_solicitante_01 IN (160603,282752,171017,160592)");//Para hacer pruebas con determinados beneficiarios
		//query.append(" AND id_solicitante_01 IN (282752)");//Para hacer pruebas con determinados beneficiarios
		query.append(" ORDER BY ID_SOLICITANTE_01");
		return this.jdbcTemplate.query(query.toString(), this.rwMapPKPago, fechaFin, fechaInicio);
	}
	
	public List<Ad74aBeneficiarioDFBBean> findBeneficiariosDDFF(String provincia) throws SQLException{
		
		List<Ad74aBeneficiarioDFBBean> listBeneficiariosBean = null; 	
		StringBuilder query = new StringBuilder();
		
		//Si entra como 1 en sqlDeveloper funciona pero aqu� no.
		if ("1".equals(provincia)) {
			provincia = "01";
		}

		query.append("SELECT t1.ID_SOLICITANTE_01  IDSOLICITANTE,");
		query.append("t1.TIPO_IDENTIFICADOR_01 TIPOIDENTIFICADOR,");
		query.append("t1.IDENTIFICADOR_01 IDENTIFICADOR,");
		query.append("t1.NOMBRE_01 NOMBRE,");
		query.append("t1.APELLIDO1_01 APELLIDO1,");
		query.append("t1.APELLIDO2_01 APELLIDO2,");
		query.append("t2.F_APERTURA_EXP_00 FAPERTURA,");
		query.append("t1.F_BENEFICIARIO_01 FBENEFICIARIO,");
		query.append("t1.F_BAJA_01 FBAJA,");
		query.append("t1.ID_MOTIVO_BAJA_01 IDMOTIVOBAJA,");
		query.append("CASE ");//Si est� exento (tabla 91) = 0, si no est� exento y prec privado not null = precio privado y sino precio publico vigente (tabla 77)
		query.append("WHEN (SELECT ind_exento_91 ");
		query.append("FROM precios_beneficiario ");
		query.append("WHERE t1.id_solicitante_01 = id_solicitante_91 ");
		query.append("AND TRUNC(fecha_inicio_91) <= SYSDATE ");
		query.append("AND NVL(TRUNC(fecha_fin_91), SYSDATE)>= SYSDATE) = 0 AND (SELECT precio_privado_91 ");
		query.append("FROM precios_beneficiario ");
		query.append("WHERE t1.id_solicitante_01 = id_solicitante_91 ");
		query.append("AND TRUNC(fecha_inicio_91) <= SYSDATE ");
		query.append("AND NVL(TRUNC(fecha_fin_91), SYSDATE)>= SYSDATE) IS NOT NULL THEN ");
		query.append("(SELECT precio_privado_91 ");
		query.append("FROM precios_beneficiario ");
		query.append("WHERE t1.id_solicitante_01 = id_solicitante_91 ");
		query.append("AND TRUNC(fecha_inicio_91) <= SYSDATE ");
		query.append("AND NVL(TRUNC(fecha_fin_91), SYSDATE)>= SYSDATE) ");
		query.append("ELSE ");
		query.append("(SELECT precio_publico_77 ");
		query.append("FROM precios_publicos ");
		query.append("WHERE TRUNC(f_vigencia_desde_77) <= SYSDATE ");
		query.append("AND NVL(TRUNC(f_vigencia_hasta_77), SYSDATE)>= SYSDATE) ");
		query.append("END PRECIOPUBLICO ");
		query.append("FROM SOLICITANTES t1,");
		query.append("EXPEDIENTES t2,");
		query.append("DIRECCIONES t3 ");
		query.append("WHERE 1=1 ");
		query.append("AND t1.id_solicitante_01 = t2.id_solicitante_00 ");
		query.append("AND t1.id_direccion_01 = t3.id_direccion_06 ");
		query.append("AND t1.beneficiario_01 = 1 ");
		query.append("AND t2.id_procedimiento_00 IN ('0087002', 'X87_TEA_1') ");
		query.append("AND t3.id_provincia_06 = ? ");
		
		//query.append("AND t1.id_solicitante_01 IN (315814, 298324,238553) ");//Beneficiarios de �lava para pruebas.
		
		query.append("ORDER BY t2.F_APERTURA_EXP_00 DESC");
		
		listBeneficiariosBean = this.jdbcTemplate.query(query.toString(), this.rwMapBeneficiariosDDFF, provincia);
			
		return listBeneficiariosBean;
	}
	
	/**
	 * Buscar beneficiarios para el servicio de interoperabilidad NISAE.
	 * 
	 * @param provincia String provincia de los benericiarios
	 * @return List<Solicitantes> lista de los beneficiarios
	 */
	@Transactional(readOnly = true)
	public List<Solicitantes> findDepDisMasiva(String provincia) {
		StringBuilder query = new StringBuilder(
				"SELECT t2.ID_EXPEDIENTE_00 IDEXPEDIENTE00,t1.IDENTIFICADOR_01 IDENTIFICADOR01, t1.ID_SOLICITANTE_01 IDSOLICITANTE01, t1.NOMBRE_01 NOMBRE, t1.APELLIDO1_01 APELLIDO1, t1.APELLIDO2_01 APELLIDO2, ");
		query.append("t1.TIPO_IDENTIFICADOR_01 TIPOIDENTIFICADOR,T3.ID_PROVINCIA_06 IDPROVINCIA06,T1.F_NACIMIENTO_01 FNACIMIENTO01 ");
		query.append("FROM SOLICITANTES t1,");
		query.append("EXPEDIENTES t2,");
		query.append("DIRECCIONES t3 ");
		query.append("WHERE 1=1 ");
		query.append("AND t1.F_BAJA_01 IS NULL AND t2.AUTORIZA_CONSULTA_00 = 1 ");
		
		//descomentar
		//ejemplos dependencia 225588,315814,164436,210356,275788,292196
		//ejemplos discapacidad 313938,198522,316531,174967
		//ejemplos discapacidad alava ( 480273,480364,480365,480366,480367,480288)
		//query.append("AND id_solicitante_01 in ( 480273,480364,480365,480366,480367,480288 ) ");
		//FIN descomentar
		query.append("AND t1.id_solicitante_01 = t2.id_solicitante_00 ");
		query.append("AND t1.id_direccion_01 = t3.id_direccion_06 ");		
		query.append("AND t1.beneficiario_01 = 1 ");
		query.append("AND t2.id_procedimiento_00 IN ('0087002', 'X87_TEA_1') ");
		if(!ConstantesBatch.COD_TODAS_PROVINCIAS.equalsIgnoreCase(provincia)) {
			query.append("AND t3.id_provincia_06 = ? ");	
			return this.jdbcTemplate.query(query.toString(), this.rwMapDepDisMasiva, provincia);
		}

		return this.jdbcTemplate.query(query.toString(), this.rwMapDepDisMasiva);
		
	}
	
	/**
	 * Buscar beneficiario por dni.
	 * 
	 * @param String dni del benefeciario 	 
	 * @return Solicitantes datos del beneficiario
	 */
	@Transactional(readOnly = true)
	public Solicitantes findBeneficiarioByDni(Solicitantes solicitante) {
		StringBuilder query = new StringBuilder(
				"SELECT t2.ID_EXPEDIENTE_00 IDEXPEDIENTE00,t1.ID_SOLICITANTE_01 IDSOLICITANTE01 FROM SOLICITANTES t1 LEFT JOIN EXPEDIENTES t2 ON ( t1.id_solicitante_01 = t2.id_solicitante_00 AND t2.id_procedimiento_00 IN ('0087002', 'X87_TEA_1')) ");
		query.append(" WHERE t1.BENEFICIARIO_01 = '1'");		
		query.append(" AND t1.F_BAJA_01 IS NULL AND UPPER(t1.IDENTIFICADOR_01) = UPPER(?)");
		List<Solicitantes> solicitantesList = this.jdbcTemplate.query(query.toString(), this.rwMapByDni, solicitante.getIdentificador01());
		
		//hay dnis con varios registros
		Solicitantes resultado=null;
		if (solicitantesList.size()>1){
			logger.error( "SolicitantesDaoImpl - Se ha encontrado varios solicitantes para el identificador, se recupera el primero {}", solicitante.getIdentificador01());
			resultado = solicitantesList.get(0);
		}else {
			resultado = DataAccessUtils.uniqueResult(solicitantesList);
		}
		return resultado;
	}


	@Override
	public Solicitantes findSolicitanteByDni(Solicitantes solFilter) {
		StringBuilder query = new StringBuilder(
				"SELECT t1.F_BAJA_01 FBAJA01,t2.ID_EXPEDIENTE_00 IDEXPEDIENTE00,t1.ID_SOLICITANTE_01 IDSOLICITANTE01 FROM SOLICITANTES t1 LEFT JOIN EXPEDIENTES t2 ON ( t1.id_solicitante_01 = t2.id_solicitante_00 AND t2.id_procedimiento_00 IN ('0087002', 'X87_TEA_1')) ");
		query.append(" WHERE t1.BENEFICIARIO_01 = '1'");		
		query.append(" AND UPPER(t1.IDENTIFICADOR_01) = UPPER(?) order by  t1.F_BAJA_01 desc");
		List<Solicitantes> solicitantesList = this.jdbcTemplate.query(query.toString(), this.rwMapByDniBaja, solFilter.getIdentificador01());
		
		//hay dnis con varios registros
		Solicitantes resultado=null;
		if (solicitantesList.size()>1){
			logger.error( "SolicitantesDaoImpl - Se ha encontrado varios beneficiarios para el identificador, se recupera el que no tenga fecha baja o el que tenga la fecha baja mas alta {}", solFilter.getIdentificador01());
			resultado = solicitantesList.get(0);
		}else {
			resultado = DataAccessUtils.uniqueResult(solicitantesList);
		}
		return resultado;
	}
}