package com.ejie.m62fb.utils.sql;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.ejie.m62fb.dao.ComboP28Dao;
import com.ejie.m62fb.dao.ComboR09Dao;
import com.ejie.m62fb.dao.registroVPP.DireccionesDao;
import com.ejie.m62fb.model.base.AbstractM62FBModel;
import com.ejie.m62fb.model.direccion.Direccion;
import com.ejie.m62fb.model.tipos.AbstractTipoGenericoP28;
import com.ejie.m62fb.model.tipos.AbstractTipoGenericoR09;
import com.ejie.t17i.model.Calle;
import com.ejie.t17i.model.Localidad;
import com.ejie.t17i.model.Municipio;
import com.ejie.t17i.model.Pais;
import com.ejie.t17i.model.Planta;
import com.ejie.t17i.model.Portal;
import com.ejie.t17i.model.Provincia;

/**
 * Clase de utilidades de ResulSet, para recuperar datos de BD.
 * 
XXXX
 */
public class UtilsResulSet {

	/**
	 * Recupera del resulSet un tipo de dato Boolean teniendo en cuenta sus
	 * peculiaridades
	 * 
	 * @param resultSet
	 *            ResultSet
	 * @param column
	 *            Columna a recuperar
	 * 
	 * @return Boolean
	 * 
	 * @throws SQLException
	 *             e
	 */
	public static Boolean getBooleanSN(ResultSet resultSet, String column)
			throws SQLException {
		return BDUtils.formatBooleanFromBD(resultSet.getString(column));
	}

	/**
	 * Recupera del resulSet un indicador teniendo en cuenta sus peculiaridades
	 * 
	 * @param resultSet
	 *            ResultSet
	 * @param column
	 *            Columna a recuperar
	 * 
	 * @return String
	 * 
	 * @throws SQLException
	 *             e
	 */
	public static String getIndicadorSN(ResultSet resultSet, String column)
			throws SQLException {
		return BDUtils.formatIndicadorFromBD(resultSet.getString(column));
	}

	/**
	 * Recupera del resulSet un tipo de dato Integer, devolviendo null (y no 0)
	 * en el caso de que el campo este vacio.
	 * 
	 * @param resultSet
	 *            ResultSet
	 * @param column
	 *            Columna a recuperar
	 * 
	 * @return Integer
	 * 
	 * @throws SQLException
	 *             e
	 */
	public static Integer getInteger(ResultSet resultSet, String column)
			throws SQLException {
		String valorAux = resultSet.getString(column);
		return valorAux != null ? Integer.valueOf(valorAux) : null;
	}

	/**
	 * Recupera del resulSet un tipo de dato Long, devolviendo null (y no 0) en
	 * el caso de que el campo este vacio.
	 * 
	 * @param resultSet
	 *            ResultSet
	 * @param column
	 *            Columna a recuperar
	 * 
	 * @return Long
	 * 
	 * @throws SQLException
	 *             e
	 */
	public static Long getLong(ResultSet resultSet, String column)
			throws SQLException {
		String valorAux = resultSet.getString(column);
		return valorAux != null ? Long.valueOf(valorAux) : null;
	}

	/**
	 * Recupera del resulSet un tipo de dato AbstractTipoGenericoP28,
	 * devolviendo los datos necesarios rellenos (Con JOINs)
	 * 
	 * @param resultSet
	 *            ResultSet
	 * @param column
	 *            Columna a recuperar
	 * @param comboP28Dao
	 *            ComboP28Dao<T>
	 * @param comboClass
	 *            Class del tipo de combo que se quiere recuperar
	 * 
	 * @return Long
	 * 
	 * @throws SQLException
	 *             e
	 */
	public static <T extends AbstractTipoGenericoP28> T getComboP28(
			ResultSet resultSet, String aliasP28, Class<T> comboClass)
			throws SQLException {
		T comboP28 = null;
		try {
			comboP28 = comboClass.getConstructor().newInstance();
		} catch (Exception e) {
			throw new SQLException(
					"Ha ocurrido un error al conseguir el constructor para un comboP28.",
					e);
		}

		aliasP28 = aliasP28.trim();

		comboP28.setNumRegistro(UtilsResulSet.getLong(resultSet, aliasP28
				+ "NUMREGISTRO"));
		comboP28.setCodTabla(resultSet.getString(aliasP28 + "CODTABLA"));
		comboP28.setDescripcionEs(resultSet.getString(aliasP28 + "DESTABLACAS"));
		comboP28.setDescripcionEu(resultSet.getString(aliasP28 + "DESTABLAEUS"));

		return comboP28;
	}

	/**
	 * Recupera del resulSet un tipo de dato Long, devolviendo null (y no 0) en
	 * el caso de que el campo este vacio. (Sin JOINs)
	 * 
	 * @param resultSet
	 *            ResultSet
	 * @param column
	 *            Columna a recuperar
	 * @param comboP28Dao
	 *            ComboP28Dao<T>
	 * @param comboClass
	 *            Class del tipo de combo que se quiere recuperar
	 * 
	 * @return Long
	 * 
	 * @throws SQLException
	 *             e
	 */
	@Deprecated
	public static <T extends AbstractTipoGenericoP28> T getComboP28(
			ResultSet resultSet, String column, ComboP28Dao<T> comboP28Dao,
			Class<T> comboClass) throws SQLException {
		T filter = null;
		try {
			filter = comboClass.getConstructor(String.class).newInstance(
					resultSet.getString(column));
		} catch (Exception e) {
			throw new SQLException(
					"Ha ocurrido un error al conseguir el constructor para un comboP28.",
					e);
		}
		return comboP28Dao.find(filter);
	}

	/**
	 * Recupera del resulSet un tipo de dato Long, devolviendo null (y no 0) en
	 * el caso de que el campo este vacio.
	 * 
	 * @param resultSet
	 *            ResultSet
	 * @param column
	 *            Columna a recuperar
	 * @param comboP28Dao
	 *            ComboP28Dao<T>
	 * @param comboClass
	 *            Class del tipo de combo que se quiere recuperar
	 * 
	 * @return Long
	 * 
	 * @throws SQLException
	 *             e
	 */
	@Deprecated
	public static <T extends AbstractTipoGenericoR09> T getComboR09(
			ResultSet resultSet, String column, ComboR09Dao<T> comboR09Dao,
			Class<T> comboClass) throws SQLException {
		T filter = null;
		try {
			filter = comboClass.getConstructor(String.class).newInstance(
					resultSet.getString(column));
		} catch (Exception e) {
			throw new SQLException(
					"Ha ocurrido un error al conseguir el constructor para un comboP28.",
					e);
		}
		return comboR09Dao.find(filter);
	}
	/**
	 * Recupera del resulSet un tipo de dato Long, devolviendo null (y no 0) en
	 * el caso de que el campo este vacio.
	 * 
	 * @param resultSet
	 *            ResultSet
	 * @param column
	 *            Columna a recuperar
	 * @param comboP28Dao
	 *            ComboP28Dao<T>
	 * @param comboClass
	 *            Class del tipo de combo que se quiere recuperar
	 * 
	 * @return Long
	 * 
	 * @throws SQLException
	 *             e
	 */
	@Deprecated
	public static <T extends AbstractTipoGenericoR09> T getComboR09Tabla(
			ResultSet resultSet, String column, ComboR09Dao<T> comboR09Dao,
			Class<T> comboClass) throws SQLException {
		T filter = null;
		try {
			filter = comboClass.getConstructor(String.class).newInstance(
					resultSet.getString(column));
		} catch (Exception e) {
			throw new SQLException(
					"Ha ocurrido un error al conseguir el constructor para un comboP28.",
					e);
		}
		return comboR09Dao.findTabla(filter);
	}

	/**
	 * Recupera del resulSet un tipo de dato String
	 * 
	 * @param resultSet
	 *            ResultSet
	 * @param column
	 *            Columna a recuperar
	 * 
	 * @return String
	 * 
	 * @throws SQLException
	 *             e
	 */
	public static String getString(ResultSet resultSet, String column)
			throws SQLException {
		if (column == null || column.trim().isEmpty()
				|| resultSet.getString(column) == null
				|| resultSet.getString(column).trim().isEmpty()) {
			return null;
		}
		return resultSet.getString(column);
	}

	/**
	 * Recupera del resulSet un tipo de dato BigDecimal
	 * 
	 * @param resultSet
	 *            ResultSet
	 * @param column
	 *            Columna a recuperar
	 * 
	 * @return BigDecimal
	 * 
	 * @throws SQLException
	 *             e
	 */
	public static BigDecimal getBigDecimal(ResultSet resultSet, String column)
			throws SQLException {
		if (column == null || column.trim().isEmpty()) {
			return null;
		}
		return resultSet.getBigDecimal(column);
	}

	/**
	 * Recupera del resulSet los datos comunes del AbstractM62FBModel y los
	 * inserta en el objeto pasado
	 * 
	 * @param resultSet
	 *            ResultSet
	 * @param model
	 *            AbstractM62FBModel
	 * 
	 * @throws SQLException
	 *             e
	 */
	public static void getAbstractClass(ResultSet resultSet,
			AbstractM62FBModel model, String alias) throws SQLException {

		alias = !Utilidades.isEmpty(alias) ? alias.trim() : "";
		// AbstractM62FBModel
		model.setFecAlta(resultSet.getTimestamp(alias + "FECALTA"));
		model.setFecHorUltimaModif(resultSet
				.getTimestamp(alias + "FEHULTMODIF"));
		model.setCodUsuarioUltimaModif(resultSet.getString(alias
				+ "CODUSUULTMODIF"));
	}

	/**
	 * Recupera del resulSet los datos basicos de la Direccion y busca (con el
	 * dao proporcionado) las descripciones necesarias para completar la
	 * Direccion (Sin JOINs)
	 * 
	 * @param resultSet
	 *            ResultSet
	 * @param alias
	 *            String
	 * @param direccionesDao
	 *            DireccionesDao
	 * 
	 * @return Direccion
	 * 
	 * @throws SQLException
	 *             e
	 */
	public static Direccion getDireccionCompleta(ResultSet resultSet,
			String alias, DireccionesDao direccionesDao) throws SQLException {
		Direccion direccion = UtilsResulSet
				.getDireccionBasica(resultSet, alias);
		return direccionesDao != null ? direccionesDao
				.completarDireccion(direccion) : direccion;
	}

	/**
	 * Recupera del resulSet los datos completos de la Direccion (Con JOINs)
	 * 
	 * @param resultSet
	 *            ResultSet
	 * @param aliasTabla
	 *            String
	 * @param prefixDir
	 *            String
	 * 
	 * @return Direccion
	 * 
	 * @throws SQLException
	 *             e
	 */
	public static Direccion getDireccionCompleta(ResultSet resultSet,
			String prefixDir) throws SQLException {

		prefixDir = !Utilidades.isEmpty(prefixDir) ? prefixDir.trim() + "_"
				: "";

		Direccion direccion = new Direccion();

		// Pais
		direccion.setPais(new Pais(resultSet.getString(prefixDir + "IDPAIS")));
		// Provincia
		Provincia provincia = new Provincia();
		provincia.setId(resultSet.getString(prefixDir + "IDPROVINCIA"));
		provincia.setNombre(resultSet.getString(prefixDir + "DESCPROVINCIA"));
		direccion.setProvincia(provincia);
		// Municipio
		Municipio municipio = new Municipio();
		municipio.setProvincia(provincia);
		municipio.setId(resultSet.getString(prefixDir + "IDMUNICIPIO"));
		municipio.setNombre(resultSet.getString(prefixDir + "DESCMUNICIPIO"));
		direccion.setMunicipio(municipio);
		// Localidad
		Localidad localidad = new Localidad();
		localidad.setId(resultSet.getBigDecimal(prefixDir + "IDLOCALIDAD"));
		localidad.setNombre(resultSet.getString(prefixDir + "DESCLOCALIDAD"));
		direccion.setLocalidad(localidad);
		// Calle
		Calle calle = new Calle();
		calle.setId(resultSet.getBigDecimal(prefixDir + "IDCALLE"));
		calle.setNombreEs(resultSet.getString(prefixDir + "DESCCALLEES"));
		calle.setNombreEu(resultSet.getString(prefixDir + "DESCCALLEEU"));
		direccion.setCalle(calle);
		// Portal
		Portal portal = new Portal();
		portal.setBloque(resultSet.getString(prefixDir + "BLOQUE"));
		portal.setNumero(resultSet.getString(prefixDir + "NUMERO"));
		portal.setBis(resultSet.getString(prefixDir + "BIS"));
		portal.setCodigoPostal(resultSet.getString(prefixDir + "CP"));
		direccion.setPortal(portal);
		// Planta
		Planta planta = new Planta();
		planta.setEscalera(resultSet.getString(prefixDir + "ESCALERA"));
		planta.setPiso(resultSet.getString(prefixDir + "PISO"));
		direccion.setPlanta(planta);
		// Mano
		direccion.setMano(resultSet.getString(prefixDir + "MANO"));
		// Puerta
		direccion.setPuerta(resultSet.getString(prefixDir + "PUERTA"));

		return direccion;
	}

	/**
	 * Recupera del resulSet los datos basicos de la Direccion y los devuelve
	 * 
	 * @param resultSet
	 *            ResultSet
	 * @param model
	 *            AbstractM62FBModel
	 * 
	 * @throws SQLException
	 *             e
	 */
	public static Direccion getDireccionBasica(ResultSet resultSet, String alias)
			throws SQLException {

		alias = !Utilidades.isEmpty(alias) ? alias.trim() : "";

		String auxStr = null;
		BigDecimal auxBig = null;
		Direccion direccion = new Direccion();

		// Pais
		auxStr = resultSet.getString(alias + "IDPAIS");
		direccion.setPais(auxStr != null ? new Pais(auxStr) : null);
		// Provincia
		auxStr = resultSet.getString(alias + "IDPROVINCIA");
		direccion.setProvincia(auxStr != null ? new Provincia(auxStr) : null);
		// Municipio
		auxStr = resultSet.getString(alias + "IDMUNICIPIO");
		direccion.setMunicipio(auxStr != null ? new Municipio(auxStr, direccion
				.getProvincia()) : null);
		// Localidad
		auxBig = resultSet.getBigDecimal(alias + "IDLOCALIDAD");
		direccion.setLocalidad(auxBig != null ? new Localidad(auxBig) : null);
		// Calle
		auxBig = resultSet.getBigDecimal(alias + "IDCALLE");
		direccion.setCalle(auxBig != null ? new Calle(auxBig) : null);

		// Portal
		Portal portal = new Portal();
		portal.setBloque(resultSet.getString(alias + "BLOQUE"));
		portal.setNumero(resultSet.getString(alias + "NUMERO"));
		portal.setBis(resultSet.getString(alias + "BIS"));
		portal.setCodigoPostal(resultSet.getString(alias + "CODIGOPOSTAL"));
		direccion.setPortal(portal);

		// Planta
		Planta planta = new Planta();
		planta.setEscalera(resultSet.getString(alias + "ESCALERA"));
		planta.setPiso(resultSet.getString(alias + "PISO"));
		direccion.setPlanta(planta);

		// Mano
		direccion.setMano(resultSet.getString(alias + "MANO"));
		// Puerta
		direccion.setPuerta(resultSet.getString(alias + "PUERTA"));

		return direccion;
	}

	/**
	 * Recupera del resulSet un tipo de dato BigDecimal y devuelve nulo si este
	 * tiene el valor por defecto
	 * 
	 * @param resultSet
	 *            ResultSet
	 * @param column
	 *            String: Columna a recuperar
	 * 
	 * @return Bigdecimal
	 * 
	 * @throws SQLException
	 *             e
	 */
	public static BigDecimal getImporte(ResultSet resultSet, String column)
			throws SQLException {
		BigDecimal resultado = resultSet.getBigDecimal(column);
		return BDUtils.formatImporteFromBD(resultado);
	}
}