package com.ejie.ab79.dao.plantillas;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

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.ab79.comun.Constantes;
import com.ejie.ab79.model.plantillas.Documentos;
import com.ejie.ab79.model.plantillas.Plantillas;
import com.ejie.ab79.model.plantillas.RelExpPla;
import com.ejie.ab79.model.plantillas.TiposPlantilla;
import com.ejie.ab79.model.procedimientos.Procedimientos;
import com.ejie.x38.dto.TableManager;
import com.ejie.x38.dto.TableRequestDto;

/**
 * PlantillasDaoImpl  
 * 
 *  
 */

@Repository
@Transactional
public class PlantillasDaoImpl implements PlantillasDao {

	public static final String[] ORDER_BY_WHITE_LIST = new String[] { "IDPLANTILLA", "DESCRIPCIONCASTELLANO",
			"DESCRIPCIONEUSKERA", "OBSERVACIONES", "DOCPLANTILLA", "TAREA", "FECHAREGISTRO", "USUARIOREGISTRO",
			"FECHAULTMODIFICACION", "USUARIOULTMODIFICACION", "TIPOSPLANTILLAIDTIPOPLANTILLA", "RUTA", "IDRELEXPPLA",
			"TIPOSPLANTILLADESCASTELLANO", "TIPOSPLANTILLADESEUSKERA", "TIPOSPLANTILLAFECHAREGISTRO",
			"TIPOSPLANTILLAUSUARIOREGISTRO", "PROCEDIMIENTOSIDPROCEDIMIENTO", "PROCEDIMIENTOSCODPROCEDUREID",
			"PROCEDIMIENTOSFOLDERID", "PROCEDIMIENTOSFOLDERNUMBER", "PROCAMPOSTITULOEXPEDIENTE",
			"PROCEDIMIENTOSFECHAREGISTRO", "PROCEDIMIENTOSUSUARIOREGISTRO", "PROCEDIMIENTOSIDDIRECCION", "ARCHIVO",
			"NOMBREDOCUMENTO", "PROCEDIMIENTOSIDAREA" };

	private JdbcTemplate jdbcTemplate;

	/*
	 * ROW_MAPPERS
	 */
	private RowMapper<Plantillas> rwMap = new RowMapper<Plantillas>() {
		public Plantillas mapRow(ResultSet resultSet, int rowNum) throws SQLException {

			/* Plantillas */
			Plantillas plantillas = new Plantillas();
			plantillas.setIdPlantilla(resultSet.getInt("IDPLANTILLA"));
			plantillas.setDescripcionCastellano(resultSet.getString("DESCRIPCIONCASTELLANO"));
			plantillas.setDescripcionEuskera(resultSet.getString("DESCRIPCIONEUSKERA"));
			plantillas.setOrigen(resultSet.getInt("ORIGEN"));
			/* RelExpPla */
			RelExpPla relExpPlaAux = new RelExpPla();
			relExpPlaAux.setRuta(resultSet.getString("RUTA"));
			plantillas.setRelExpPla(relExpPlaAux);
			/* Tipos Plantilla */
			TiposPlantilla tiposPlantillaAux = new TiposPlantilla();
			tiposPlantillaAux.setIdTipoPlantilla(resultSet.getLong("IDTIPOPLANTILLA"));
			tiposPlantillaAux.setTaskId(resultSet.getString("TASKID"));
			plantillas.setTiposPlantilla(tiposPlantillaAux);
			/* Procedimientos */
			Procedimientos procedimientosAux = new Procedimientos();
			procedimientosAux.setCodProcedureId(resultSet.getString("ProcedimientosCODPROCEDUREID"));
			plantillas.setProcedimientos(procedimientosAux);

			return plantillas;
		}
	};

	private RowMapper<Plantillas> rwMapPlantilla = new RowMapper<Plantillas>() {
		public Plantillas mapRow(ResultSet resultSet, int rowNum) throws SQLException {

			Plantillas plantilla = new Plantillas();
			plantilla.setIdPlantilla(resultSet.getInt("IDPLANTILLA"));
			plantilla.setDescripcionCastellano(resultSet.getString("DESCRIPCIONCASTELLANO"));
			plantilla.setDescripcionEuskera(resultSet.getString("DESCRIPCIONEUSKERA"));

			return plantilla;
		}
	};

	private RowMapper<Plantillas> rwMapPlantillaDeDocumentoProcedimiento = new RowMapper<Plantillas>() {
		public Plantillas mapRow(ResultSet resultSet, int rowNum) throws SQLException {

			Plantillas plantilla = new Plantillas();
			plantilla.setIdPlantilla(resultSet.getInt("IDPLANTILLA"));
			plantilla.setDescripcionCastellano(resultSet.getString("DESCRIPCIONCASTELLANO"));
			plantilla.setDescripcionEuskera(resultSet.getString("DESCRIPCIONEUSKERA"));

			Procedimientos procedimiento = new Procedimientos();
			procedimiento.setIdProcedimiento(resultSet.getInt("IDPROCEDIMIENTO"));
			plantilla.setProcedimientos(procedimiento);

			Documentos documento = new Documentos();
			documento.setTipo(resultSet.getInt("TIPO"));
			plantilla.setDocumento(documento);

			return plantilla;
		}
	};

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

	/**
	 * Finds rows in the Plantillas table using like.
	 *
	 * @param plantillas
	 *            Plantillas
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @return List<Plantillas>
	 */
	@Transactional(readOnly = true)
	public List<Plantillas> findAll(Plantillas plantillas, TableRequestDto tableRequestDto) {
		StringBuilder query = new StringBuilder();

		query.append(
				"SELECT  t6110.ID_PLANTILLA IDPLANTILLA, t6110.ID_TIPO_PLANTILLA IDTIPOPLANTILLA, t6110.DESCRIPCION_CASTELLANO DESCRIPCIONCASTELLANO");
		query.append(",t6110.DESCRIPCION_EUSKERA DESCRIPCIONEUSKERA, t6110.ORIGEN ORIGEN,  t6111.TASK_ID TASKID");
		query.append(",t6133.RUTA RUTA, t6101.COD_PROCEDURE_ID PROCEDIMIENTOSCODPROCEDUREID");

		query.append(
				" FROM PLANTILLAS t6110, TIPOS_PLANTILLA t6111, PROCEDIMIENTOS t6101, REL_EXP_PLA t6133, DOCUMENTOS t6139, REL_PLA_API t6158, APLICACIONES t6146 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(plantillas);
		StringBuilder where = new StringBuilder();

		where.append(
				" WHERE 1=1 AND t6110.ID_TIPO_PLANTILLA= t6111.ID_TIPO_PLANTILLA(+) AND t6110.ID_PROCEDIMIENTO= t6101.ID_PROCEDIMIENTO(+)");
		where.append(
				" AND t6110.ID_PLANTILLA = t6133.ID_PLANTILLA (+) AND t6110.ID_DOCUMENTO = t6139.ID_DOCUMENTO AND t6110.ID_PLANTILLA = t6158.ID_PLANTILLA AND t6158.ID_APLICACION = t6146.ID_APLICACION ");
		where.append(mapaWhere.get("query"));
		query.append(where);

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

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

		return (List<Plantillas>) this.jdbcTemplate.query(query.toString(), this.rwMap, params.toArray());
	}

	/**
	 * Counts rows in the Plantillas table using like.
	 *
	 * @param plantillas
	 *            Plantillas
	 * @return Long
	 */
	@Transactional(readOnly = true)
	public Long findAllCount(Plantillas plantillas) {
		StringBuilder query = new StringBuilder(
				"SELECT COUNT(1) FROM PLANTILLAS t6110 ,TIPOS_PLANTILLA t6111 ,PROCEDIMIENTOS t6101 , REL_EXP_PLA t6133, DOCUMENTOS t6139, REL_PLA_API t6158, APLICACIONES t6146 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(plantillas);
		StringBuilder where = new StringBuilder(
				" WHERE 1=1 AND t6110.ID_TIPO_PLANTILLA= t6111.ID_TIPO_PLANTILLA(+) AND t6110.ID_PROCEDIMIENTO= t6101.ID_PROCEDIMIENTO(+) AND t6110.ID_PROCEDIMIENTO = t6133.ID_PROCEDIMIENTO(+)   AND t6110.ID_PLANTILLA = t6133.ID_PLANTILLA (+) AND t6110.ID_DOCUMENTO = t6139.ID_DOCUMENTO AND t6110.ID_PLANTILLA = t6158.ID_PLANTILLA AND t6158.ID_APLICACION = t6146.ID_APLICACION ");
		where.append(mapaWhere.get("query"));
		query.append(where);

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

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

	// CHECKSTYLE:ON CyclomaticComplexity - Generaci�n de c�digo de UDA

	/**
	 * Returns a map with the needed value to create the conditions to filter by
	 * the Plantillas entity
	 *
	 * @param plantillas
	 *            Plantillas Bean with the criteria values to filter by.
	 * @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
	private Map<String, Object> getWhereLikeMap(Plantillas plantillas) {

		StringBuilder where = new StringBuilder(PlantillasDaoImpl.STRING_BUILDER_INIT);
		List<Object> params = new ArrayList<Object>();

		where.append(" AND t6146.CODIGO_APLICACION = ?");
		params.add(Constantes.CODIGO_APLICACION.toUpperCase());

		if (plantillas != null && plantillas.getIdPlantilla() != null) {
			where.append(" AND t6110.ID_PLANTILLA = ?");
			params.add(plantillas.getIdPlantilla());
		}
		if (plantillas != null && plantillas.getTiposPlantilla() != null
				&& plantillas.getTiposPlantilla().getIdTipoPlantilla() != null) {
			where.append(" AND t6111.ID_TIPO_PLANTILLA = ?");
			params.add(plantillas.getTiposPlantilla().getIdTipoPlantilla());
		}
		if (plantillas != null && plantillas.getTiposPlantilla() != null
				&& plantillas.getTiposPlantilla().getDescripcionCastellano() != null) {
			where.append(" AND UPPER(t6111.DESCRIPCION_CASTELLANO) like ? ESCAPE  '\\'");
			params.add("%" + plantillas.getTiposPlantilla().getDescripcionCastellano().toUpperCase() + "%");
			where.append(" AND t6111.DESCRIPCION_CASTELLANO IS NOT NULL");
		}
		if (plantillas != null && plantillas.getTiposPlantilla() != null
				&& plantillas.getTiposPlantilla().getDescripcionEuskera() != null) {
			where.append(" AND UPPER(t6111.DESCRIPCION_EUSKERA) like ? ESCAPE  '\\'");
			params.add("%" + plantillas.getTiposPlantilla().getDescripcionEuskera().toUpperCase() + "%");
			where.append(" AND t6111.DESCRIPCION_EUSKERA IS NOT NULL");
		}
		if (plantillas != null && plantillas.getTiposPlantilla() != null
				&& plantillas.getTiposPlantilla().getFechaRegistro() != null) {
			where.append(" AND t6111.FECHA_REGISTRO = ?");
			params.add(plantillas.getTiposPlantilla().getFechaRegistro());
		}
		if (plantillas != null && plantillas.getTiposPlantilla() != null
				&& plantillas.getTiposPlantilla().getUsuarioRegistro() != null) {
			where.append(" AND UPPER(t6111.USUARIO_REGISTRO) like ? ESCAPE  '\\'");
			params.add("%" + plantillas.getTiposPlantilla().getUsuarioRegistro().toUpperCase() + "%");
			where.append(" AND t6111.USUARIO_REGISTRO IS NOT NULL");
		}
		if (plantillas != null && plantillas.getProcedimientos() != null
				&& plantillas.getProcedimientos().getIdProcedimiento() != null) {
			where.append(" AND t6101.ID_PROCEDIMIENTO = ?");
			params.add(plantillas.getProcedimientos().getIdProcedimiento());
		}
		if (plantillas != null && plantillas.getProcedimientos() != null
				&& plantillas.getProcedimientos().getDirecciones() != null
				&& plantillas.getProcedimientos().getDirecciones().getIdDireccion() != null) {
			where.append(" AND t6101.ID_DIRECCION = ?");
			params.add(plantillas.getProcedimientos().getDirecciones().getIdDireccion());
		}
		if (plantillas != null && plantillas.getProcedimientos() != null
				&& plantillas.getProcedimientos().getCodProcedureId() != null) {
			where.append(" AND UPPER(t6101.COD_PROCEDURE_ID) like ? ESCAPE  '\\'");
			params.add("%" + plantillas.getProcedimientos().getCodProcedureId().toUpperCase() + "%");
			where.append(" AND t6101.COD_PROCEDURE_ID IS NOT NULL");
		}
		if (plantillas != null && plantillas.getProcedimientos() != null
				&& plantillas.getProcedimientos().getCamposTituloExpediente() != null) {
			where.append(" AND UPPER(t6101.CAMPOS_TITULO_EXPEDIENTE) like ? ESCAPE  '\\'");
			params.add("%" + plantillas.getProcedimientos().getCamposTituloExpediente().toUpperCase() + "%");
			where.append(" AND t6101.CAMPOS_TITULO_EXPEDIENTE IS NOT NULL");
		}
		if (plantillas != null && plantillas.getOrigen() != null) {
			where.append(" AND t6139.ORIGEN = ?");
			params.add(plantillas.getOrigen());
		}
		if (plantillas != null && plantillas.getProcedimientos() != null
				&& plantillas.getProcedimientos().getUsuarioRegistro() != null) {
			where.append(" AND UPPER(t6101.USUARIO_REGISTRO) like ? ESCAPE  '\\'");
			params.add("%" + plantillas.getProcedimientos().getUsuarioRegistro().toUpperCase() + "%");
			where.append(" AND t6101.USUARIO_REGISTRO IS NOT NULL");
		}
		if (plantillas != null && plantillas.getRelExpPla() != null
				&& plantillas.getRelExpPla().getIdentificador() != null) {
			where.append(" AND t6133.IDENTIFICADOR (+) = ? ");
			params.add(plantillas.getRelExpPla().getIdentificador());
		}
		if (plantillas != null && plantillas.getDescripcionCastellano() != null) {
			where.append(" AND UPPER(t6110.DESCRIPCION_CASTELLANO) like ? ESCAPE  '\\'");
			params.add("%" + plantillas.getDescripcionCastellano().toUpperCase() + "%");
			where.append(" AND t6110.DESCRIPCION_CASTELLANO IS NOT NULL");
		}
		if (plantillas != null && plantillas.getDescripcionEuskera() != null) {
			where.append(" AND UPPER(t6110.DESCRIPCION_EUSKERA) like ? ESCAPE  '\\'");
			params.add("%" + plantillas.getDescripcionEuskera().toUpperCase() + "%");
			where.append(" AND t6110.DESCRIPCION_EUSKERA IS NOT NULL");
		}
		if (plantillas != null && plantillas.getObservaciones() != null) {
			where.append(" AND UPPER(t6110.OBSERVACIONES) like ? ESCAPE  '\\'");
			params.add("%" + plantillas.getObservaciones().toUpperCase() + "%");
			where.append(" AND t6110.OBSERVACIONES IS NOT NULL");
		}
		if (plantillas != null && plantillas.getFechaRegistro() != null) {
			where.append(" AND t6110.FECHA_REGISTRO = ?");
			params.add(plantillas.getFechaRegistro());
		}
		if (plantillas != null && plantillas.getUsuarioRegistro() != null) {
			where.append(" AND UPPER(t6110.USUARIO_REGISTRO) like ? ESCAPE  '\\'");
			params.add("%" + plantillas.getUsuarioRegistro().toUpperCase() + "%");
			where.append(" AND t6110.USUARIO_REGISTRO IS NOT NULL");
		}
		if (plantillas != null && plantillas.getFechaUltmodificacion() != null) {
			where.append(" AND t6110.FECHA_ULTMODIFICACION = ?");
			params.add(plantillas.getFechaUltmodificacion());
		}
		if (plantillas != null && plantillas.getUsuarioUltmodificacion() != null) {
			where.append(" AND UPPER(t6110.USUARIO_ULTMODIFICACION) like ? ESCAPE  '\\'");
			params.add("%" + plantillas.getUsuarioUltmodificacion().toUpperCase() + "%");
			where.append(" AND t6110.USUARIO_ULTMODIFICACION IS NOT NULL");
		}

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

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

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

	@Override
	public List<Plantillas> findTiposPlantillaDeDocumento(Integer idProcedimiento) {
		String query = "SELECT t6110.ID_PLANTILLA IDPLANTILLA, t6110.DESCRIPCION_CASTELLANO DESCRIPCIONCASTELLANO, t6110.DESCRIPCION_EUSKERA DESCRIPCIONEUSKERA FROM PLANTILLAS t6110, DOCUMENTOS t6139 WHERE 1 = 1 AND t6139.TIPO = ? AND t6110.ID_DOCUMENTO = t6139.ID_DOCUMENTO AND t6110.ID_PROCEDIMIENTO = ?";

		return (List<Plantillas>) this.jdbcTemplate.query(query, this.rwMapPlantilla,
				Constantes.TIPO_PLANTILLA_DE_DOCUMENTO, idProcedimiento);
	}

	@Override
	public List<Plantillas> findTiposPlantillaDeDocumentoProcedimiento() {
		String query = "SELECT t6110.ID_PLANTILLA IDPLANTILLA, t6110.DESCRIPCION_CASTELLANO DESCRIPCIONCASTELLANO, t6110.DESCRIPCION_EUSKERA DESCRIPCIONEUSKERA, t6110.ID_PROCEDIMIENTO IDPROCEDIMIENTO, t6139.TIPO FROM PLANTILLAS t6110,  DOCUMENTOS t6139 WHERE 1 = 1 AND t6110.ID_DOCUMENTO = t6139.ID_DOCUMENTO AND t6139.TIPO = ? UNION SELECT t6110.ID_PLANTILLA IDPLANTILLA, t6110.DESCRIPCION_CASTELLANO DESCRIPCIONCASTELLANO, t6110.DESCRIPCION_EUSKERA DESCRIPCIONEUSKERA, t6110.ID_PROCEDIMIENTO IDPROCEDIMIENTO, t6139.TIPO FROM PLANTILLAS t6110, DOCUMENTOS t6139, PROCEDIMIENTOS t6101, APLICACIONES t6146 WHERE 1 = 1 AND t6110.ID_DOCUMENTO = t6139.ID_DOCUMENTO AND t6110.ID_PROCEDIMIENTO = t6101.ID_PROCEDIMIENTO AND t6101.ID_APLICACION = t6146.ID_APLICACION AND t6139.TIPO = ? AND t6146.CODIGO_APLICACION = ? ";

		List<Object> params = new ArrayList<Object>();
		params.add(Constantes.TIPO_PLANTILLA_DE_DOCUMENTO);
		params.add(Constantes.TIPO_PLANTILLA_DE_PLANTILLA);
		params.add(Constantes.CODIGO_APLICACION_MOVIL.toUpperCase());

		return (List<Plantillas>) this.jdbcTemplate.query(query, this.rwMapPlantillaDeDocumentoProcedimiento,
				params.toArray());
	}
}
