package com.ejie.ab79.dao.expedientes;

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.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.ab79.comun.Constantes;
import com.ejie.ab79.model.expedientes.DatosDirecciones;
import com.ejie.ab79.model.expedientes.Expedientes;
import com.ejie.ab79.model.inspecciones.Inspecciones;
import com.ejie.ab79.model.procedimientos.Aplicaciones;
import com.ejie.ab79.model.procedimientos.Direcciones;
import com.ejie.ab79.model.procedimientos.Procedimientos;
import com.ejie.x38.dto.TableManager;
import com.ejie.x38.dto.TableRequestDto;

/**
 * ExpedientesDaoImpl  
 * 
 *  
 */

@Repository
@Transactional
public class ExpedientesDaoImpl implements ExpedientesDao {

	public static final String[] ORDER_BY_WHITE_LIST = new String[] { "IDEXPEDIENTE", "IDPROCEDIMIENTO",
			"IDTERRITORIOHISTORICO", "FOLDERID", "FOLDERNUMBER", "TITULO", "FECHAENTRADA", "FECHADOCFOR",
			"FECHAULTAPOR", "FECHAENVULTREQ", "FECHAACUULTREQ", "FECHADOCCOM", "FECHARESOLUCION", "FECHAACURES",
			"FECHAINCOACION", "FECHAINCUMPLIMIENTO", "FECHARENUNCIA", "FECHADESISTIMIENTO", "FECHACIERRE",
			"FECHARECURSO", "FECHAREGISTRO", "USUARIOREGISTRO", "IDPROVINCIAFISCAL", "FECHAJUSTIFICACION",
			"FECHAULTMODIFICACION", "USUARIOULTMODIFICACION", "IDPROCEDIMIENTO", "DESCCASTELLANO", "DESCEUSKERA",
			"IDEXPEDIENTEORIGEN", "IDTIPODOCUMENTO", "IDENTEST" };

	private JdbcTemplate jdbcTemplate;

	/*
	 * ROW_MAPPERS
	 */
	private RowMapper<Expedientes> rwMap = new RowMapper<Expedientes>() {
		@Override
		public Expedientes mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			return new Expedientes(resultSet.getInt("IDEXPEDIENTE"), resultSet.getInt("IDPROCEDIMIENTO"),
					resultSet.getLong("IDTERRITORIOHISTORICO"), resultSet.getString("FOLDERID"),
					resultSet.getString("FOLDERNUMBER"), resultSet.getString("TITULO"),
					resultSet.getLong("IDPROVINCIAFISCAL"));
		}
	};

	private RowMapper<Expedientes> rwMapFindByFolderId = new RowMapper<Expedientes>() {
		@Override
		public Expedientes mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			Expedientes expedientes = new Expedientes();
			expedientes.setIdExpediente(resultSet.getInt("IDEXPEDIENTE"));
			expedientes.setFolderId(resultSet.getString("FOLDERID"));
			expedientes.setFolderNumber(resultSet.getString("FOLDERNUMBER"));
			expedientes.setTitulo(resultSet.getString("TITULO"));
			Aplicaciones aplicaciones = new Aplicaciones();
			aplicaciones.setUrlAplicacion(resultSet.getString("URLAPLICACION"));
			expedientes.setAplicacion(aplicaciones);

			Procedimientos procedimientos = new Procedimientos();
			procedimientos.setIdProcedimiento(resultSet.getInt("IDPROCEDIMIENTO"));
			procedimientos.setCodProcedureId(resultSet.getString("CODPROCEDUREID"));
			procedimientos.setDescripcionEs(resultSet.getString("DESCCASTELLANO"));
			procedimientos.setDescripcionEu(resultSet.getString("DESCEUSKERA"));
			expedientes.setProcedimientos(procedimientos);

			return expedientes;
		}
	};
	private RowMapper<Expedientes> rwMapFindByIdExpediente = new RowMapper<Expedientes>() {
		@Override
		public Expedientes mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			Expedientes expedientes = new Expedientes();
			expedientes.setIdExpediente(resultSet.getInt("IDEXPEDIENTE"));
			expedientes.setFolderId(resultSet.getString("FOLDERID"));
			expedientes.setFolderNumber(resultSet.getString("FOLDERNUMBER"));
			expedientes.setTitulo(resultSet.getString("TITULO"));
			expedientes.setIdExpedienteOrigen(resultSet.getInt("IDEXPEDIENTEORIGEN"));

			Aplicaciones aplicaciones = new Aplicaciones();
			aplicaciones.setUrlAplicacion(resultSet.getString("URLAPLICACION"));
			expedientes.setAplicacion(aplicaciones);

			expedientes.setRelacionExpediente(resultSet.getInt("RELACIONEXPEDIENTE"));
			Inspecciones inspecciones = new Inspecciones();
			inspecciones.setIdentificadorInspeccion(resultSet.getString("IDENTIFICADORINSPECCION"));
			inspecciones.setIdInspeccion(resultSet.getInt("IDINSPECCION"));
			expedientes.setInspeccion(inspecciones);
			expedientes.setIdProcedimiento(resultSet.getInt("IDPROCEDIMIENTO"));
			/* Procedimientos */
			Procedimientos procedimiento = new Procedimientos();
			procedimiento.setIdProcedimiento(resultSet.getInt("IDPROCEDIMIENTO"));
			procedimiento.setDescripcionEs(resultSet.getString("DESCCASTELLANO"));
			procedimiento.setDescripcionEu(resultSet.getString("DESCEUSKERA"));
			procedimiento.setCodProcedureId(resultSet.getString("CODPROCEDUREID"));

			Direcciones direccion = new Direcciones();
			direccion.setIdDireccion(resultSet.getInt("IDDIRECCION"));
			procedimiento.setDirecciones(direccion);
			expedientes.setProcedimientos(procedimiento);

			return expedientes;
		}
	};

	private RowMapper<Expedientes> rwMapFindExpedienteByIdExpediente = new RowMapper<Expedientes>() {
		@Override
		public Expedientes mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			Expedientes expedientes = new Expedientes();
			expedientes.setIdExpediente(resultSet.getInt("IDEXPEDIENTE"));
			expedientes.setFolderId(resultSet.getString("FOLDERID"));
			expedientes.setFolderNumber(resultSet.getString("FOLDERNUMBER"));
			expedientes.setTitulo(resultSet.getString("TITULO"));
			expedientes.setIdExpedienteOrigen(resultSet.getInt("IDEXPEDIENTEORIGEN"));
			/* Procedimientos */
			Procedimientos procedimiento = new Procedimientos();
			procedimiento.setIdProcedimiento(resultSet.getInt("IDPROCEDIMIENTO"));
			procedimiento.setDescripcionEs(resultSet.getString("DESCCASTELLANO"));
			procedimiento.setDescripcionEu(resultSet.getString("DESCEUSKERA"));
			procedimiento.setCodProcedureId(resultSet.getString("CODPROCEDUREID"));

			Direcciones direccion = new Direcciones();
			direccion.setIdDireccion(resultSet.getInt("IDDIRECCION"));
			procedimiento.setDirecciones(direccion);
			expedientes.setProcedimientos(procedimiento);

			return expedientes;
		}
	};

	private RowMapper<Expedientes> rwMapFindByIdInspeccion = new RowMapper<Expedientes>() {
		@Override
		public Expedientes mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			Expedientes expedientes = new Expedientes();
			expedientes.setIdExpediente(resultSet.getInt("IDEXPEDIENTE"));
			expedientes.setFolderId(resultSet.getString("FOLDERID"));
			expedientes.setFolderNumber(resultSet.getString("FOLDERNUMBER"));
			expedientes.setTitulo(resultSet.getString("TITULO"));
			expedientes.setIdExpedienteOrigen(resultSet.getInt("IDEXPEDIENTEORIGEN"));
			Inspecciones inspecciones = new Inspecciones();
			inspecciones.setIdentificadorInspeccion(resultSet.getString("IDENTIFICADORINSPECCION"));
			inspecciones.setIdInspeccion(resultSet.getInt("IDINSPECCION"));
			expedientes.setInspeccion(inspecciones);
			expedientes.setIdProcedimiento(resultSet.getInt("IDPROCEDIMIENTO"));

			Aplicaciones aplicaciones = new Aplicaciones();
			aplicaciones.setUrlAplicacion(resultSet.getString("URLAPLICACION"));
			expedientes.setAplicacion(aplicaciones);

			/* Procedimientos */
			Procedimientos procedimiento = new Procedimientos();
			procedimiento.setIdProcedimiento(resultSet.getInt("IDPROCEDIMIENTO"));
			procedimiento.setDescripcionEs(resultSet.getString("DESCCASTELLANO"));
			procedimiento.setDescripcionEu(resultSet.getString("DESCEUSKERA"));
			procedimiento.setCodProcedureId(resultSet.getString("CODPROCEDUREID"));
			expedientes.setProcedimientos(procedimiento);
			/* Datos Direcciones */
			DatosDirecciones datosDirecciones = new DatosDirecciones();
			datosDirecciones.setIdentificadorEstablecimiento(resultSet.getString("IDENTEST"));
			expedientes.setDatosDirecciones(datosDirecciones);

			return expedientes;
		}
	};

	private RowMapper<Expedientes> rwMapIdExpediente = new RowMapper<Expedientes>() {
		@Override
		public Expedientes mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			Expedientes expedientes = new Expedientes();
			expedientes.setIdExpediente(resultSet.getInt("IDEXPEDIENTE"));

			Procedimientos procedimientos = new Procedimientos();
			procedimientos.setIdProcedimiento(resultSet.getInt("IDPROCEDIMIENTO"));
			Direcciones direcciones = new Direcciones();
			direcciones.setIdDireccion(resultSet.getInt("IDDIRECCION"));
			procedimientos.setDirecciones(direcciones);
			expedientes.setProcedimientos(procedimientos);

			return expedientes;
		}
	};

	private RowMapper<Expedientes> rwMapDocumentacionExpRel = new RowMapper<Expedientes>() {
		@Override
		public Expedientes mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			Expedientes expediente = new Expedientes();
			expediente.setIdExpediente(resultSet.getInt("IDEXPEDIENTE"));
			expediente.setFolderNumber(resultSet.getString("FOLDERNUMBER"));
			expediente.setTitulo(resultSet.getString("TITULO"));

			Procedimientos procedimiento = new Procedimientos();
			procedimiento.setDescripcionEs(resultSet.getString("DESCCASTELLANO"));
			procedimiento.setDescripcionEu(resultSet.getString("DESCEUSKERA"));
			expediente.setProcedimientos(procedimiento);

			return expediente;
		}
	};

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

	/**
	 * busco datos de expediente segun su Folder_id
	 *
	 * @param expedientes
	 *            Expedientes
	 * @return Expedientes
	 */
	@Override
	@Transactional(readOnly = true)
	public Expedientes findIdExpediente(Expedientes expedientes) {
		String query = "SELECT t1.ID_EXPEDIENTE IDEXPEDIENTE, t1.ID_PROCEDIMIENTO IDPROCEDIMIENTO, t2.ID_DIRECCION IDDIRECCION FROM EXPEDIENTES t1, PROCEDIMIENTOS t2 WHERE t1.FOLDER_ID= ? AND t1.ID_PROCEDIMIENTO = t2.ID_PROCEDIMIENTO";

		List<Expedientes> expedientesList = this.jdbcTemplate.query(query, this.rwMapIdExpediente,
				expedientes.getFolderId());
		return DataAccessUtils.uniqueResult(expedientesList);
	}

	/**
	 * Finds a single row in the Expedientes table.
	 *
	 * @param expedientes
	 *            Expedientes
	 * @return Expedientes
	 */
	@Override
	@Transactional(readOnly = true)
	public Expedientes find(Expedientes expedientes) {
		String query = "SELECT t1.ID_EXPEDIENTE IDEXPEDIENTE, t1.ID_PROCEDIMIENTO IDPROCEDIMIENTO, t1.ID_TERRITORIO_HISTORICO IDTERRITORIOHISTORICO, t1.FOLDER_ID FOLDERID, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO, t1.ID_PROVINCIA_FISCAL IDPROVINCIAFISCAL FROM EXPEDIENTES t1  WHERE t1.ID_EXPEDIENTE = ?  ";

		List<Expedientes> expedientesList = this.jdbcTemplate.query(query, this.rwMap, expedientes.getIdExpediente());
		return DataAccessUtils.uniqueResult(expedientesList);
	}

	@Override
	public boolean findExpedienteCerrado(Expedientes expediente) {
		String query = "SELECT COUNT(1) FROM REL_EXP_FECH t6142, FECHAS_EXPEDIENTE t6144 WHERE t6142.ID_FECHA_EXPEDIENTE = t6144.ID_FECHA_EXPEDIENTE AND t6144.ETIQUETA_FECHA = ? AND t6142.ID_EXPEDIENTE = ?";

		List<Object> params = new ArrayList<Object>();
		params.add(Constantes.FECHA_CIERRE);
		params.add(expediente.getIdExpediente());

		Long expedientesCount = this.jdbcTemplate.queryForObject(query, params.toArray(), Long.class);

		if (expedientesCount > 0) {
			return true;
		} else {
			return false;
		}

	}

	/**
	 * Finds a single row in the Expedientes table por FolderId.
	 *
	 * @param expedientes
	 *            Expedientes
	 * @return Expedientes
	 */
	@Override
	@Transactional(readOnly = true)
	public Expedientes findByFolderId(Expedientes expedientes) {
		String query = "SELECT t1.ID_EXPEDIENTE IDEXPEDIENTE, t1.FOLDER_ID FOLDERID, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO,  t2.ID_PROCEDIMIENTO IDPROCEDIMIENTO, t2.COD_PROCEDURE_ID CODPROCEDUREID, t2.DESCRIPCION_CASTELLANO DESCCASTELLANO, t2.DESCRIPCION_EUSKERA DESCEUSKERA, t3.URL_APLICACION URLAPLICACION FROM EXPEDIENTES t1 , PROCEDIMIENTOS t2, APLICACIONES t3 WHERE t1.FOLDER_ID = ? AND t1.ID_PROCEDIMIENTO= t2.ID_PROCEDIMIENTO(+) AND t2.ID_APLICACION = t3.ID_APLICACION(+) ";

		List<Expedientes> expedientesList = this.jdbcTemplate.query(query, this.rwMapFindByFolderId,
				expedientes.getFolderId());
		return DataAccessUtils.uniqueResult(expedientesList);
	}

	/**
	 * Finds a single row in the Expedientes table por FolderId.
	 *
	 * @param expedientes
	 *            Expedientes
	 * @return Expedientes
	 */
	@Override
	@Transactional(readOnly = true)
	public Expedientes findByIdExpediente(Expedientes expedientes) {

		StringBuilder query = new StringBuilder();

		query.append(
				"SELECT T1.ID_EXPEDIENTE IDEXPEDIENTE, T1.TITULO TITULO, T1.FOLDER_NUMBER FOLDERNUMBER, T1.FOLDER_ID FOLDERID, T1.ID_PROCEDIMIENTO IDPROCEDIMIENTO");
		query.append(
				", T1.ID_EXPEDIENTE_ORIGEN IDEXPEDIENTEORIGEN, T1.RELACION_EXPEDIENTE RELACIONEXPEDIENTE, T3.ID_INSPECCION IDINSPECCION, T3.IDENTIFICADOR_INSPECCION IDENTIFICADORINSPECCION");
		query.append(
				", T2.DESCRIPCION_CASTELLANO DESCCASTELLANO, T2.DESCRIPCION_EUSKERA DESCEUSKERA, t2.COD_PROCEDURE_ID CODPROCEDUREID, T2.ID_DIRECCION IDDIRECCION");
		query.append(" , t5.URL_APLICACION URLAPLICACION");

		query.append(" FROM EXPEDIENTES T1 , INSPECCIONES T3, PROCEDIMIENTOS T2, APLICACIONES t5 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(expedientes);
		StringBuilder where = new StringBuilder(
				" WHERE 1=1 AND t1.ID_EXPEDIENTE = t3.ID_EXPEDIENTE(+) AND T1.ID_PROCEDIMIENTO = T2.ID_PROCEDIMIENTO AND t2.ID_APLICACION = t5.ID_APLICACION ");

		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");
		// Expedientes params = (Expedientes) mapaWhere.get("params");
		List<Expedientes> expedientesList = this.jdbcTemplate.query(query.toString(), this.rwMapFindByIdExpediente,
				params.toArray());

		return DataAccessUtils.uniqueResult(expedientesList);

	}

	/**
	 * Finds a single row in the Expedientes table por FolderId.
	 *
	 * @param expedientes
	 *            Expedientes
	 * @return Expedientes
	 */
	@Override
	@Transactional(readOnly = true)
	public Expedientes findByIdInspeccion(Expedientes expedientes) {

		StringBuilder query = new StringBuilder();

		query.append(
				"SELECT t1.ID_EXPEDIENTE IDEXPEDIENTE, t1.TITULO TITULO, t1.FOLDER_NUMBER FOLDERNUMBER, t1.FOLDER_ID FOLDERID, t1.ID_PROCEDIMIENTO IDPROCEDIMIENTO, t1.ID_EXPEDIENTE_ORIGEN IDEXPEDIENTEORIGEN, t3.ID_INSPECCION IDINSPECCION, t3.IDENTIFICADOR_INSPECCION IDENTIFICADORINSPECCION, t2.DESCRIPCION_CASTELLANO DESCCASTELLANO, t2.DESCRIPCION_EUSKERA DESCEUSKERA, t2.COD_PROCEDURE_ID CODPROCEDUREID, (SELECT IDENTIFICADOR_ESTABLECIMIENTO FROM REL_EXP_DIR t4, DATOS_DIRECCIONES t5 WHERE t4.ID_EXPEDIENTE = t1.ID_EXPEDIENTE AND t4.ID_DIRECCION = t5.ID_DIRECCION AND t5.ID_TIPO_DIRECCION = 2) IDENTEST, t6.URL_APLICACION URLAPLICACION ");

		query.append(" FROM EXPEDIENTES t1, PROCEDIMIENTOS t2, INSPECCIONES t3, APLICACIONES t6 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(expedientes);

		StringBuilder where = new StringBuilder(
				" WHERE 1 = 1 AND t1.ID_EXPEDIENTE = t3.ID_EXPEDIENTE(+) AND t1.ID_PROCEDIMIENTO = t2.ID_PROCEDIMIENTO AND t2.ID_APLICACION = t6.ID_APLICACION(+) ");

		where.append(mapaWhere.get("query"));
		query.append(where);

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

		List<Expedientes> expedientesList = this.jdbcTemplate.query(query.toString(), this.rwMapFindByIdInspeccion,
				params.toArray());

		return DataAccessUtils.uniqueResult(expedientesList);

	}

	@Override
	public Expedientes findByIdExpedienteOrigen(Expedientes expedientesOrigen) {
		StringBuilder query = new StringBuilder();

		query.append(
				"SELECT T1.ID_EXPEDIENTE IDEXPEDIENTE, T1.TITULO TITULO, T1.FOLDER_NUMBER FOLDERNUMBER, T1.FOLDER_ID FOLDERID, T1.ID_PROCEDIMIENTO IDPROCEDIMIENTO");
		query.append(
				", T1.ID_EXPEDIENTE_ORIGEN IDEXPEDIENTEORIGEN, T1.RELACION_EXPEDIENTE RELACIONEXPEDIENTE, T3.ID_INSPECCION IDINSPECCION, T3.IDENTIFICADOR_INSPECCION IDENTIFICADORINSPECCION");
		query.append(
				", T2.DESCRIPCION_CASTELLANO DESCCASTELLANO, T2.DESCRIPCION_EUSKERA DESCEUSKERA, t2.COD_PROCEDURE_ID CODPROCEDUREID, T2.ID_DIRECCION IDDIRECCION");
		query.append(" , t5.URL_APLICACION URLAPLICACION");
		query.append(" FROM EXPEDIENTES T1 , INSPECCIONES T3, PROCEDIMIENTOS T2, APLICACIONES t5 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMapOrigen(expedientesOrigen);
		StringBuilder where = new StringBuilder(
				" WHERE 1=1 AND t1.ID_EXPEDIENTE = t3.ID_EXPEDIENTE(+) AND T1.ID_PROCEDIMIENTO = T2.ID_PROCEDIMIENTO AND t2.ID_APLICACION = t5.ID_APLICACION ");
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");
		// Expedientes params = (Expedientes) mapaWhere.get("params");
		List<Expedientes> expedientesList = this.jdbcTemplate.query(query.toString(), this.rwMapFindByIdExpediente,
				params.toArray());

		return DataAccessUtils.uniqueResult(expedientesList);
	}

	/**
	 * Returns a map with the needed value to create the conditions to filter by
	 * the Expedientes entity
	 *
	 * @param expedientes
	 *            Expedientes 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, ?> getWhereMap(Expedientes expedientes) {

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

		if (expedientes != null && expedientes.getInspeccion() != null
				&& null != expedientes.getInspeccion().getIdInspeccion()) {
			where.append(" AND t3.ID_INSPECCION = ?");
			params.add(expedientes.getInspeccion().getIdInspeccion());
		}
		if (expedientes != null && expedientes.getIdExpediente() != null) {
			where.append(" AND t1.ID_EXPEDIENTE = ?");
			params.add(expedientes.getIdExpediente());
		}

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

		return mapWhere;
	}

	private Map<String, ?> getWhereMapOrigen(Expedientes expedientes) {

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

		if (expedientes != null && expedientes.getIdExpediente() != null) {
			where.append(" AND t1.ID_EXPEDIENTE = ?");
			params.add(expedientes.getIdExpediente());
		}

		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;

	/**
	 * Finds a single row in the Expedientes table por FolderId.
	 *
	 * @param expedientes
	 *            Expedientes
	 * @return Expedientes
	 */
	@Override
	@Transactional(readOnly = true)
	public Expedientes findByExpedienteIdExpediente(Expedientes expedientes) {

		StringBuilder query = new StringBuilder();

		query.append(
				"SELECT T1.ID_EXPEDIENTE IDEXPEDIENTE, T1.TITULO TITULO, T1.FOLDER_NUMBER FOLDERNUMBER, T1.FOLDER_ID FOLDERID, T1.ID_PROCEDIMIENTO IDPROCEDIMIENTO, T1.ID_EXPEDIENTE_ORIGEN IDEXPEDIENTEORIGEN, T2.DESCRIPCION_CASTELLANO DESCCASTELLANO, T2.DESCRIPCION_EUSKERA DESCEUSKERA, t2.COD_PROCEDURE_ID CODPROCEDUREID, T2.ID_DIRECCION IDDIRECCION FROM EXPEDIENTES T1, PROCEDIMIENTOS T2");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(expedientes);
		StringBuilder where = new StringBuilder(" WHERE 1=1 AND T1.ID_PROCEDIMIENTO = T2.ID_PROCEDIMIENTO");

		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");
		// Expedientes params = (Expedientes) mapaWhere.get("params");
		List<Expedientes> expedientesList = this.jdbcTemplate.query(query.toString(),
				this.rwMapFindExpedienteByIdExpediente, params.toArray());

		return DataAccessUtils.uniqueResult(expedientesList);
	}

	@Override
	public List<Expedientes> findDocumentacionExpRel(Expedientes filterExpedientes, TableRequestDto tableRequestDto,
			String documentosTitular) {
		StringBuilder query = new StringBuilder();
		List<Object> params = new ArrayList<Object>();

		if (filterExpedientes.getInspeccion().getIdOrigenInspeccion() == Constantes.ORIGEN_AYUDAS || filterExpedientes
				.getInspeccion().getIdOrigenInspeccion() == Constantes.ORIGEN_ESTABLECIMIENTOS_COMERCIALES) {

			query.append(
					"SELECT t1.ID_EXPEDIENTE IDEXPEDIENTE, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO, t4.DESCRIPCION_CASTELLANO DESCCASTELLANO, t4.DESCRIPCION_EUSKERA DESCEUSKERA ");
			query.append("FROM EXPEDIENTES t1, REL_EXP_TER t2, DATOS_TERCEROS t3, PROCEDIMIENTOS t4 ");
			query.append(
					"WHERE t1.ID_EXPEDIENTE = t2.ID_EXPEDIENTE AND t2.ID_TERCERO = t3.ID_TERCERO AND t1.ID_PROCEDIMIENTO = t4.ID_PROCEDIMIENTO AND t2.ID_TIPO_TERCERO IN ("
							+ Constantes.PARTICIPACION_SOLICITANTE + ", " + Constantes.PARTICIPACION_AFECTADO
							+ ") AND t3.DOCUMENTO IN (?) AND t1.ID_EXPEDIENTE <> ? ");
			params.add(documentosTitular);
			params.add(filterExpedientes.getIdExpediente());

			if (filterExpedientes.getDatosDirecciones() != null
					&& filterExpedientes.getDatosDirecciones().getIdentificadorEstablecimiento() != null) {
				query.append("UNION ");
				query.append(
						"SELECT t1.ID_EXPEDIENTE IDEXPEDIENTE, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO, t4.DESCRIPCION_CASTELLANO DESCCASTELLANO, t4.DESCRIPCION_EUSKERA DESCEUSKERA ");
				query.append(
						"FROM EXPEDIENTES t1, REL_EXP_TER t2, DATOS_TERCEROS t3, PROCEDIMIENTOS t4, DATOS_DIRECCIONES t5 ");
				query.append(
						"WHERE t1.ID_EXPEDIENTE = t2.ID_EXPEDIENTE AND t2.ID_TERCERO = t3.ID_TERCERO AND t1.ID_PROCEDIMIENTO = t4.ID_PROCEDIMIENTO AND t3.ID_TERCERO = t5.ID_TERCERO AND t5.IDENTIFICADOR_ESTABLECIMIENTO = ? AND t1.ID_EXPEDIENTE <> ? ");
				params.add(filterExpedientes.getDatosDirecciones().getIdentificadorEstablecimiento());
				params.add(filterExpedientes.getIdExpediente());
			}
			query.append("UNION ");
			query.append(
					"SELECT t1.ID_EXPEDIENTE IDEXPEDIENTE, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO, t2.DESCRIPCION_CASTELLANO DESCCASTELLANO, t2.DESCRIPCION_EUSKERA DESCEUSKERA ");
			query.append("FROM EXPEDIENTES t1, PROCEDIMIENTOS t2 ");
			query.append(
					"WHERE t1.ID_PROCEDIMIENTO = t2.ID_PROCEDIMIENTO AND t1.RELACION_EXPEDIENTE = ? AND t1.ID_EXPEDIENTE <> ? ");
			params.add(filterExpedientes.getRelacionExpediente());
			params.add(filterExpedientes.getIdExpediente());

			query.append("UNION ");
			query.append(
					"SELECT t1.ID_EXP_HISTORICO IDEXPEDIENTE, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO, t1.NOM_PROCEDIMIENTO DESCCASTELLANO, t1.NOM_PROCEDIMIENTO DESCEUSKERA ");
			query.append("FROM EXP_HISTORICO t1 ");
			query.append("WHERE t1.RELACION_EXPEDIENTE = ? ");
			params.add(filterExpedientes.getRelacionExpediente());

		} else if (filterExpedientes.getInspeccion().getIdOrigenInspeccion() == Constantes.ORIGEN_CAMPAINA
				|| filterExpedientes.getInspeccion().getIdOrigenInspeccion() == Constantes.ORIGEN_INSPECCION_OFICIO
				|| filterExpedientes.getInspeccion().getIdOrigenInspeccion() == Constantes.ORIGEN_DENUNCIAS
				|| filterExpedientes.getInspeccion().getIdOrigenInspeccion() == Constantes.ORIGEN_BUZON_FRAUDE) {

			if (filterExpedientes.getDatosDirecciones() == null) {
				return new ArrayList<Expedientes>();
			} else {
				query.append(
						"SELECT t1.ID_EXPEDIENTE IDEXPEDIENTE, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO, t4.DESCRIPCION_CASTELLANO DESCCASTELLANO, t4.DESCRIPCION_EUSKERA DESCEUSKERA ");
				query.append("FROM EXPEDIENTES t1, REL_EXP_DIR t6151, PROCEDIMIENTOS t4, DATOS_DIRECCIONES t5 ");
				query.append(
						"WHERE t1.ID_EXPEDIENTE = t6151.ID_EXPEDIENTE AND t1.ID_PROCEDIMIENTO = t4.ID_PROCEDIMIENTO AND t6151.ID_DIRECCION = t5.ID_DIRECCION AND t5.IDENTIFICADOR_ESTABLECIMIENTO = ? AND t1.ID_EXPEDIENTE <> ? ");
				params.add(filterExpedientes.getDatosDirecciones().getIdentificadorEstablecimiento());
				params.add(filterExpedientes.getIdExpediente());
			}

		} else if (filterExpedientes.getInspeccion().getIdOrigenInspeccion() == Constantes.ORIGEN_CENSO) {

			query.append(
					"SELECT t1.ID_EXPEDIENTE IDEXPEDIENTE, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO, t2.DESCRIPCION_CASTELLANO DESCCASTELLANO, t2.DESCRIPCION_EUSKERA DESCEUSKERA ");
			query.append("FROM EXPEDIENTES t1, PROCEDIMIENTOS t2 ");
			query.append("WHERE t1.ID_PROCEDIMIENTO = t2.ID_PROCEDIMIENTO AND t1.ID_EXPEDIENTE = ? ");
			params.add(filterExpedientes.getIdExpedienteOrigen());

			query.append("UNION ");
			query.append(
					"SELECT t1.ID_EXPEDIENTE IDEXPEDIENTE, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO, t2.DESCRIPCION_CASTELLANO DESCCASTELLANO, t2.DESCRIPCION_EUSKERA DESCEUSKERA ");
			query.append("FROM EXPEDIENTES t1, PROCEDIMIENTOS t2 ");
			query.append(
					"WHERE t1.ID_PROCEDIMIENTO = t2.ID_PROCEDIMIENTO AND t1.RELACION_EXPEDIENTE = ? AND t1.ID_EXPEDIENTE <> ? ");
			params.add(filterExpedientes.getRelacionExpediente());
			params.add(filterExpedientes.getIdExpediente());

			query.append("UNION ");
			query.append(
					"SELECT t1.ID_EXP_HISTORICO IDEXPEDIENTE, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO, t1.NOM_PROCEDIMIENTO DESCCASTELLANO, t1.NOM_PROCEDIMIENTO DESCEUSKERA ");
			query.append("FROM EXP_HISTORICO t1 ");
			query.append("WHERE t1.RELACION_EXPEDIENTE = ? ");
			params.add(filterExpedientes.getRelacionExpediente());
		}

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

		return this.jdbcTemplate.query(query.toString(), this.rwMapDocumentacionExpRel, params.toArray());
	}

	@Override
	public Long findDocumentacionExpRelCount(Expedientes filterExpedientes, String documentosTitular) {
		StringBuilder query = new StringBuilder();
		List<Object> params = new ArrayList<Object>();

		if (filterExpedientes.getInspeccion().getIdOrigenInspeccion() == Constantes.ORIGEN_AYUDAS || filterExpedientes
				.getInspeccion().getIdOrigenInspeccion() == Constantes.ORIGEN_ESTABLECIMIENTOS_COMERCIALES) {

			query.append("SELECT COUNT(1) FROM ( ");
			query.append(
					"SELECT t1.ID_EXPEDIENTE IDEXPEDIENTE, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO, t4.DESCRIPCION_CASTELLANO DESCCASTELLANO, t4.DESCRIPCION_EUSKERA DESCEUSKERA ");
			query.append("FROM EXPEDIENTES t1, REL_EXP_TER t2, DATOS_TERCEROS t3, PROCEDIMIENTOS t4 ");
			query.append(
					"WHERE t1.ID_EXPEDIENTE = t2.ID_EXPEDIENTE AND t2.ID_TERCERO = t3.ID_TERCERO AND t1.ID_PROCEDIMIENTO = t4.ID_PROCEDIMIENTO AND t2.ID_TIPO_TERCERO IN ("
							+ Constantes.PARTICIPACION_SOLICITANTE + ", " + Constantes.PARTICIPACION_AFECTADO
							+ ") AND t3.DOCUMENTO IN (?) AND t1.ID_EXPEDIENTE <> ? ");
			params.add(documentosTitular);
			params.add(filterExpedientes.getIdExpediente());

			if (filterExpedientes.getDatosDirecciones() != null
					&& filterExpedientes.getDatosDirecciones().getIdentificadorEstablecimiento() != null) {
				query.append("UNION ");
				query.append(
						"SELECT t1.ID_EXPEDIENTE IDEXPEDIENTE, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO, t4.DESCRIPCION_CASTELLANO DESCCASTELLANO, t4.DESCRIPCION_EUSKERA DESCEUSKERA ");
				query.append(
						"FROM EXPEDIENTES t1, REL_EXP_TER t2, DATOS_TERCEROS t3, PROCEDIMIENTOS t4, DATOS_DIRECCIONES t5 ");
				query.append(
						"WHERE t1.ID_EXPEDIENTE = t2.ID_EXPEDIENTE AND t2.ID_TERCERO = t3.ID_TERCERO AND t1.ID_PROCEDIMIENTO = t4.ID_PROCEDIMIENTO AND t3.ID_TERCERO = t5.ID_TERCERO AND t5.IDENTIFICADOR_ESTABLECIMIENTO = ? AND t1.ID_EXPEDIENTE <> ? ");
				params.add(filterExpedientes.getDatosDirecciones().getIdentificadorEstablecimiento());
				params.add(filterExpedientes.getIdExpediente());
			}
			query.append("UNION ");
			query.append(
					"SELECT t1.ID_EXPEDIENTE IDEXPEDIENTE, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO, t2.DESCRIPCION_CASTELLANO DESCCASTELLANO, t2.DESCRIPCION_EUSKERA DESCEUSKERA ");
			query.append("FROM EXPEDIENTES t1, PROCEDIMIENTOS t2 ");
			query.append(
					"WHERE t1.ID_PROCEDIMIENTO = t2.ID_PROCEDIMIENTO AND t1.RELACION_EXPEDIENTE = ? AND t1.ID_EXPEDIENTE <> ? ");
			params.add(filterExpedientes.getRelacionExpediente());
			params.add(filterExpedientes.getIdExpediente());

			query.append("UNION ");
			query.append(
					"SELECT t1.ID_EXP_HISTORICO IDEXPEDIENTE, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO, t1.NOM_PROCEDIMIENTO DESCCASTELLANO, t1.NOM_PROCEDIMIENTO DESCEUSKERA ");
			query.append("FROM EXP_HISTORICO t1 ");
			query.append("WHERE t1.RELACION_EXPEDIENTE = ? ");
			params.add(filterExpedientes.getRelacionExpediente());

			query.append(")");

		} else if (filterExpedientes.getInspeccion().getIdOrigenInspeccion() == Constantes.ORIGEN_CAMPAINA
				|| filterExpedientes.getInspeccion().getIdOrigenInspeccion() == Constantes.ORIGEN_INSPECCION_OFICIO
				|| filterExpedientes.getInspeccion().getIdOrigenInspeccion() == Constantes.ORIGEN_DENUNCIAS
				|| filterExpedientes.getInspeccion().getIdOrigenInspeccion() == Constantes.ORIGEN_BUZON_FRAUDE) {

			if (filterExpedientes.getDatosDirecciones() == null) {
				return new Long(0);
			} else {
				query.append("SELECT COUNT(1) FROM ( ");
				query.append(
						"SELECT t1.ID_EXPEDIENTE IDEXPEDIENTE, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO, t4.DESCRIPCION_CASTELLANO DESCCASTELLANO, t4.DESCRIPCION_EUSKERA DESCEUSKERA ");
				query.append(
						"FROM EXPEDIENTES t1, REL_EXP_TER t2, DATOS_TERCEROS t3, PROCEDIMIENTOS t4, DATOS_DIRECCIONES t5 ");
				query.append(
						"WHERE t1.ID_EXPEDIENTE = t2.ID_EXPEDIENTE AND t2.ID_TERCERO = t3.ID_TERCERO AND t1.ID_PROCEDIMIENTO = t4.ID_PROCEDIMIENTO AND t3.ID_TERCERO = t5.ID_TERCERO AND t5.IDENTIFICADOR_ESTABLECIMIENTO = ? AND t1.ID_EXPEDIENTE <> ? ");
				params.add(filterExpedientes.getDatosDirecciones().getIdentificadorEstablecimiento());
				params.add(filterExpedientes.getIdExpediente());

				query.append(")");
			}

		} else if (filterExpedientes.getInspeccion().getIdOrigenInspeccion() == Constantes.ORIGEN_CENSO) {

			query.append("SELECT COUNT(1) FROM ( ");
			query.append(
					"SELECT t1.ID_EXPEDIENTE IDEXPEDIENTE, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO, t2.DESCRIPCION_CASTELLANO DESCCASTELLANO, t2.DESCRIPCION_EUSKERA DESCEUSKERA ");
			query.append("FROM EXPEDIENTES t1, PROCEDIMIENTOS t2 ");
			query.append("WHERE t1.ID_PROCEDIMIENTO = t2.ID_PROCEDIMIENTO AND t1.ID_EXPEDIENTE = ? ");
			params.add(filterExpedientes.getIdExpedienteOrigen());

			query.append("UNION ");
			query.append(
					"SELECT t1.ID_EXPEDIENTE IDEXPEDIENTE, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO, t2.DESCRIPCION_CASTELLANO DESCCASTELLANO, t2.DESCRIPCION_EUSKERA DESCEUSKERA ");
			query.append("FROM EXPEDIENTES t1, PROCEDIMIENTOS t2 ");
			query.append(
					"WHERE t1.ID_PROCEDIMIENTO = t2.ID_PROCEDIMIENTO AND t1.RELACION_EXPEDIENTE = ? AND t1.ID_EXPEDIENTE <> ? ");
			params.add(filterExpedientes.getRelacionExpediente());
			params.add(filterExpedientes.getIdExpediente());

			query.append("UNION ");
			query.append(
					"SELECT t1.ID_EXP_HISTORICO IDEXPEDIENTE, t1.FOLDER_NUMBER FOLDERNUMBER, t1.TITULO TITULO, t1.NOM_PROCEDIMIENTO DESCCASTELLANO, t1.NOM_PROCEDIMIENTO DESCEUSKERA ");
			query.append("FROM EXP_HISTORICO t1 ");
			query.append("WHERE t1.RELACION_EXPEDIENTE = ? ");
			params.add(filterExpedientes.getRelacionExpediente());

			query.append(")");
		}

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

	@Override
	public void actualizarTituloTerritorioHistorico(Expedientes expediente) {

		if (expediente.getIdTerritorioHistorico() != null) {
			String query = "UPDATE EXPEDIENTES SET TITULO = ?, ID_TERRITORIO_HISTORICO = ?, FECHA_ULTMODIFICACION = SYSDATE, USUARIO_ULTMODIFICACION = ? WHERE ID_EXPEDIENTE = ?";
			this.jdbcTemplate.update(query, expediente.getTitulo(), expediente.getIdTerritorioHistorico(),
					expediente.getUsuarioUltmodificacion(), expediente.getIdExpediente());
		} else {
			String query = "UPDATE EXPEDIENTES SET TITULO = ?, FECHA_ULTMODIFICACION = SYSDATE, USUARIO_ULTMODIFICACION = ? WHERE ID_EXPEDIENTE = ?";
			this.jdbcTemplate.update(query, expediente.getTitulo(), expediente.getUsuarioUltmodificacion(),
					expediente.getIdExpediente());
		}

	}
}
