package com.ejie.m62fb.utils.sql;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

import com.ejie.m62fb.model.direccion.Direccion;

/**
 * Clase de utilidades de BD.
 * 
 * Transformaciones y formateos especificos de datos de la BD.
 * 
XXXX
 */
public class BDUtils {

	public static final String TRUE = "S";
	public static final String FALSE = "N";

	private static final RoundingMode TIPO_REDONDEO_IMPORTE = RoundingMode.HALF_UP;
	private static final BigDecimal NUMERO_IMPORTE = new BigDecimal(100);
	private static final int DECIMALES_IMPORTE = 2;

	/**
	 * Funcion encargada de formatear un indicador recuperado de BD
	 * 
	 * @param indicador
	 *            String
	 * @return Boolean
	 */
	public static Boolean formatBooleanFromBD(String indicador) {
		return BDUtils.TRUE.equals(indicador);
	}

	/**
	 * Funcion encargada de formatear un Boolean para guardar en BD
	 * 
	 * @param bool
	 *            Boolean
	 * @return String
	 */
	public static String formatBooleanToBD(Boolean bool) {
		return bool != null && bool ? BDUtils.TRUE : BDUtils.FALSE;
	}

	/**
	 * Funcion encargada de formatear un indicador recuperado de BD
	 * 
	 * @param indicador
	 *            String
	 * @return String, "S" si viene una "S" y "N" en caso contrario
	 */
	public static String formatIndicadorFromBD(String indicador) {
		return BDUtils.TRUE.equals(indicador) ? BDUtils.TRUE : BDUtils.FALSE;
	}

	/**
	 * Funcion encargada de formatear un String de un indicador para guardar en
	 * BD
	 * 
	 * @param indValue
	 *            String
	 * @return String, "S" si viene una "S" y "N" en caso contrario
	 */
	public static String formatIndicadorToBD(String indValue) {
		return BDUtils.TRUE.equals(indValue) ? BDUtils.TRUE : BDUtils.FALSE;
	}

	/**
	 * Funcion encargada de formatear los comodines del filtro '*' por los de
	 * Oracle '%'
	 * 
	 * @param valor
	 *            String
	 * @return String
	 */
	public static String formatComodinesFiltroToBD(String valor) {
		String resultado = "";
		if (valor != null) {
			resultado = valor.replace("*", "%");
		}
		return resultado;
	}

	/**
	 * Crea un filtro que iguala el valor
	 * 
	 * @param where
	 *            StringBuilder
	 * @param params
	 *            List<Object>
	 * @param campo
	 *            String
	 * @param value
	 *            Object
	 */
	public static void crearFiltroIgual(StringBuilder where,
			List<Object> params, String campo, Object value) {
		// Filtro
		where.append(" AND ").append(campo).append(" = ? ");
		// Parametro
		params.add(value);
	}

	/**
	 * Crea un filtro que compara en este caso el desde
	 * 
	 * @param where
	 *            StringBuilder
	 * @param params
	 *            List<Object>
	 * @param campo
	 *            String
	 * @param value
	 *            Object
	 */
	public static void crearFiltroDesde(StringBuilder where,
			List<Object> params, String campo, Object value) {
		BDUtils.crearFiltroDesde(where, params, campo, value, true);
	}

	/**
	 * Crea un filtro con boolean para el TRUNC que compara en este caso el
	 * desde
	 * 
	 * @param where
	 *            StringBuilder
	 * @param params
	 *            List<Object>
	 * @param campo
	 *            String
	 * @param value
	 *            Object
	 */
	public static void crearFiltroDesde(StringBuilder where,
			List<Object> params, String campo, Object value, boolean truncable) {
		// Filtro
		if (truncable) {
			where.append(" AND TRUNC(").append(campo).append(") > = ? ");
		} else {
			where.append(" AND ").append(campo).append(" > = ? ");
		}
		// Parametro
		params.add(value);
	}

	/**
	 * Crea un filtro que compara en este caso el hasta
	 * 
	 * @param where
	 *            StringBuilder
	 * @param params
	 *            List<Object>
	 * @param campo
	 *            String
	 * @param value
	 *            Object
	 */
	public static void crearFiltroHasta(StringBuilder where,
			List<Object> params, String campo, Object value) {
		BDUtils.crearFiltroHasta(where, params, campo, value, true);
	}

	/**
	 * Crea un filtro con boolean para el TRUNC que compara en este caso el
	 * hasta
	 * 
	 * @param where
	 *            StringBuilder
	 * @param params
	 *            List<Object>
	 * @param campo
	 *            String
	 * @param value
	 *            Object
	 */
	public static void crearFiltroHasta(StringBuilder where,
			List<Object> params, String campo, Object value, boolean truncable) {
		// Filtro
		if (truncable) {
			where.append(" AND TRUNC(").append(campo).append(") < = ? ");
		} else {
			where.append(" AND ").append(campo).append(" < = ? ");
		}
		// Parametro
		params.add(value);
	}

	/**
	 * Crea un filtro que iguala el valor con LIKE
	 * 
	 * @param where
	 *            StringBuilder
	 * @param params
	 *            List<Object>
	 * @param campo
	 *            String
	 * @param value
	 *            String
	 * @param startsWith
	 *            boolean
	 */
	public static void crearFiltroLike(StringBuilder where,
			List<Object> params, String campo, String value, boolean startsWith) {
		// Filtro
		where.append(" AND UPPER(").append(campo)
				.append(") LIKE ? ESCAPE '\\'");
		where.append(" AND ").append(campo).append(" IS NOT NULL ");
		// Parametro
		if (startsWith) {
			params.add(value.toUpperCase() + "%");
		} else {
			params.add("%" + value.toUpperCase() + "%");
		}
	}

	/**
	 * Crea un filtro para el objeto Direccion
	 * 
	 * @param where
	 *            StringBuilder
	 * @param params
	 *            List<Object>
	 * @param alias
	 *            String
	 * @param direccion
	 *            Direccion
	 */
	public static void crearFiltroDireccion(StringBuilder where,
			List<Object> params, String alias, Direccion direccion) {

		String aliasFnc = alias != null && !alias.trim().isEmpty() ? alias
				+ "." : "";

		if (direccion != null) {
			// // Pais
			// if (direccion.getPais() != null
			// && direccion.getPais().getId() != null) {
			// BDUtils.crearFiltroIgual(where, params, aliasFnc + PAIS,
			// direccion.getPais().getId());
			// }

			// Provincia
			if (direccion.getProvincia() != null
					&& direccion.getProvincia().getId() != null) {
				BDUtils.crearFiltroIgual(where, params, aliasFnc + PROVINCIA,
						direccion.getProvincia().getId());
			}
			// Municipio
			if (direccion.getMunicipio() != null
					&& direccion.getMunicipio().getId() != null) {
				BDUtils.crearFiltroIgual(where, params, aliasFnc + MUNICIPIO,
						direccion.getMunicipio().getId());
			}
			// Localidad
			if (direccion.getLocalidad() != null
					&& direccion.getLocalidad().getId() != null) {
				BDUtils.crearFiltroIgual(where, params, aliasFnc + LOCALIDAD,
						direccion.getLocalidad().getId());
			}
			// Calle
			if (direccion.getCalle() != null
					&& direccion.getCalle().getId() != null) {
				BDUtils.crearFiltroIgual(where, params, aliasFnc + CALLE,
						direccion.getCalle().getId());
			}
			// Portal
			if (direccion.getPortal() != null) {
				// Codigo Postal
				if (!Utilidades
						.isEmpty(direccion.getPortal().getCodigoPostal())) {
					BDUtils.crearFiltroIgual(where, params, aliasFnc
							+ CODIGO_POSTAL, direccion.getPortal()
							.getCodigoPostal().trim());
				}
				// Bloque
				if (!Utilidades.isEmpty(direccion.getPortal().getBloque())) {
					BDUtils.crearFiltroLike(where, params, aliasFnc + BLOQUE,
							direccion.getPortal().getBloque().trim(), false);
				}
				// Numero
				if (!Utilidades.isEmpty(direccion.getPortal().getNumero())) {
					BDUtils.crearFiltroLike(where, params, aliasFnc + NUMERO,
							direccion.getPortal().getNumero().trim(), false);
				}
				// Bis
				if (!Utilidades.isEmpty(direccion.getPortal().getBis())) {
					BDUtils.crearFiltroLike(where, params, aliasFnc + BIS,
							direccion.getPortal().getBis().trim(), false);
				}
			}
			// Planta
			if (direccion.getPlanta() != null) {
				// Escalera
				if (!Utilidades.isEmpty(direccion.getPlanta().getEscalera())) {
					BDUtils.crearFiltroLike(where, params, aliasFnc + ESCALERA,
							direccion.getPlanta().getEscalera().trim(), false);
				}
				// Piso
				if (!Utilidades.isEmpty(direccion.getPlanta().getPiso())) {
					BDUtils.crearFiltroLike(where, params, aliasFnc + PISO,
							direccion.getPlanta().getPiso().trim(), false);
				}
			}
			// Mano
			if (!Utilidades.isEmpty(direccion.getMano())) {
				BDUtils.crearFiltroLike(where, params, aliasFnc + MANO,
						direccion.getMano().trim(), false);
			}
			// Puerta
			if (!Utilidades.isEmpty(direccion.getPuerta())) {
				BDUtils.crearFiltroLike(where, params, aliasFnc + PUERTA,
						direccion.getPuerta().trim(), false);
			}
		}
	}

	/**
	 * Funcion encargada de formatear un importe recuperado de BD
	 * 
	 * @param importe
	 *            BigDecimal
	 * @return BigDecimal
	 */
	public static BigDecimal formatImporteFromBD(BigDecimal importe) {
		if (importe != null) {
			return importe.divide(NUMERO_IMPORTE, DECIMALES_IMPORTE,
					TIPO_REDONDEO_IMPORTE);
		} else {
			return BigDecimal.ZERO;
		}
	}

	/**
	 * Funcion encargada de formatear un importe para guardar en BD
	 * 
	 * @param importe
	 *            Integer
	 * @return Integer
	 */
	public static Integer formatImporteToBD(BigDecimal importe) {
		if (importe != null) {
			return importe.multiply(NUMERO_IMPORTE).intValue();
		} else {
			return BigDecimal.ZERO.intValue();
		}
	}

	public static final String PAIS = "ID_PAIS";
	public static final String PROVINCIA = "ID_PROVINCIA";
	public static final String MUNICIPIO = "ID_MUNICIPIO";
	public static final String LOCALIDAD = "ID_LOCALIDAD";
	public static final String CALLE = "ID_CALLE";
	public static final String BLOQUE = "BLOQUE";
	public static final String NUMERO = "NUMERO";
	public static final String BIS = "BIS";
	public static final String CODIGO_POSTAL = "CODIGO_POSTAL";
	public static final String ESCALERA = "ESCALERA";
	public static final String PISO = "PISO";
	public static final String MANO = "MANO";
	public static final String PUERTA = "PUERTA";
}