package com.ejie.ab79.dao.propuestaSancion;

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.model.propuestaSancion.EstadosProSan;
import com.ejie.ab79.model.propuestaSancion.PropuestaSancion;
import com.ejie.x38.dto.TableRequestDto;

/**
 * 
 *  
 *
 */

@Repository
@Transactional
public class PropuestaSancionDaoImpl implements PropuestaSancionDao {

	public static final String[] ORDER_BY_WHITE_LIST = new String[] { "IDPROPUESTASANCION", "IDINSPECICON", "NOTAS",
			"FECHAREGISTRO", "USUARIOREGISTRO", "IDPROSANREMOTO", "IDPROSANREMOTODES" };

	private JdbcTemplate jdbcTemplate;

	/*
	 * ROW_MAPPERS
	 */
	private RowMapper<PropuestaSancion> rwMap = new RowMapper<PropuestaSancion>() {
		public PropuestaSancion mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			PropuestaSancion propuestaSancion = new PropuestaSancion();
			propuestaSancion.setIdPropuestaSancion(resultSet.getInt("IDPROPUESTASANCION"));
			propuestaSancion.setIdInspeccion(resultSet.getInt("IDINSPECCION"));
			propuestaSancion.setNotas(resultSet.getString("NOTAS"));
			propuestaSancion.setFechaRegistro(resultSet.getDate("FECHAREGISTRO"));
			propuestaSancion.setUsuarioRegistro(resultSet.getString("USUARIOREGISTRO"));
			propuestaSancion.setIdPropuestaSancionRemoto(resultSet.getInt("IDPROSANREMOTO"));
			propuestaSancion.setIdentificadorProSanDesc(resultSet.getString("IDPROSANREMOTODES"));
			return propuestaSancion;
		}
	};

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

			EstadosProSan estado = new EstadosProSan();
			estado.setIdEstadoProSan(resultSet.getInt("IDESTADOPROSAN"));
			estado.setDescripcionCastellano(resultSet.getString("DESCRIPCIONCASTELLANO"));
			estado.setDescripcionEuskera(resultSet.getString("DESCRIPCIONEUSKERA"));

			return estado;
		}
	};

	private RowMapper<Integer> rwMapEstadoPropuesta = new RowMapper<Integer>() {
		public Integer mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			return resultSet.getInt("IDESTADOPROSAN");
		}
	};

	@Resource
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	private Map<String, ?> getWhereMap(PropuestaSancion propuestaSancion) {
		StringBuilder where = new StringBuilder(PropuestaSancionDaoImpl.STRING_BUILDER_INIT);
		List<Object> params = new ArrayList<Object>();

		if (propuestaSancion != null && propuestaSancion.getIdPropuestaSancion() != null) {
			where.append(" AND t1.ID_PROPUESTA_SANCION = ? ");
			params.add(propuestaSancion.getIdPropuestaSancion());
		}
		if (propuestaSancion != null && propuestaSancion.getIdInspeccion() != null) {
			where.append(" AND t1.ID_INSPECCION = ? ");
			params.add(propuestaSancion.getIdInspeccion());
		}
		if (propuestaSancion != null && propuestaSancion.getIdPropuestaSancionRemoto() > 0) {
			where.append(" AND t1.IDENTIFICADOR_PRO_SAN =? ");
			params.add(propuestaSancion.getIdPropuestaSancionRemoto());
		}
		Map<String, Object> mapWhere = new HashMap<String, Object>();
		mapWhere.put("query", where);
		mapWhere.put("params", params);
		return mapWhere;
	}

	/*
	 * OPERACIONES CRUD
	 */
	@Override
	public PropuestaSancion addPropuesta(PropuestaSancion propuestaSancion) {
		int idPropuesta = this.jdbcTemplate.queryForObject("SELECT AB79.S_AB7930T00.NEXTVAL FROM DUAL",
				Integer.class);
		propuestaSancion.setIdPropuestaSancion(idPropuesta);

		String query = "INSERT INTO PROPUESTAS_SANCION (ID_PROPUESTA_SANCION, ID_INSPECCION,NOTAS,FECHA_REGISTRO,USUARIO_REGISTRO,IDENTIFICADOR_PRO_SAN) VALUES (?,?,?,sysdate,?,?)";
		this.jdbcTemplate.update(query, propuestaSancion.getIdPropuestaSancion(), propuestaSancion.getIdInspeccion(),
				propuestaSancion.getNotas(), propuestaSancion.getUsuarioRegistro(),
				propuestaSancion.getIdPropuestaSancionRemoto());
		return propuestaSancion;
	}

	public void deletePropuesta(PropuestaSancion propuestaSancion) {
		if (propuestaSancion != null && propuestaSancion.getIdPropuestaSancion() > 0) {
			String query = "DELETE FROM PROPUESTAS_SANCION WHERE ID_PROPUESTA_SANCION = ?";
			this.jdbcTemplate.update(query, propuestaSancion.getIdPropuestaSancion());
		}
	}

	@Override
	public PropuestaSancion find(PropuestaSancion propuestaSancion) {
		StringBuilder query = new StringBuilder("SELECT t1.ID_PROPUESTA_SANCION IDPROPUESTASANCION, "
				+ "	t1.ID_INSPECCION IDINSPECCION," + " t1.NOTAS NOTAS, t1.FECHA_REGISTRO FECHAREGISTRO ,"
				+ " t1.USUARIO_REGISTRO USUARIOREGISTRO, "
				+ "t1.IDENTIFICADOR_PRO_SAN IDPROSANREMOTO, t1.IDENTIFICADOR_PRO_SAN_DES IDPROSANREMOTODES ");
		query.append(" FROM PROPUESTAS_SANCION t1");
		query.append(" WHERE ID_PROPUESTA_SANCION = ?");
		List<PropuestaSancion> listaPropuestas = this.jdbcTemplate.query(query.toString(), this.rwMap,
				propuestaSancion.getIdPropuestaSancion());
		return DataAccessUtils.uniqueResult(listaPropuestas);
	}

	@Override
	public PropuestaSancion findByInspeccion(PropuestaSancion propuestaSancion) {
		StringBuilder query = new StringBuilder("SELECT t1.ID_PROPUESTA_SANCION IDPROPUESTASANCION, "
				+ "	t1.ID_INSPECCION IDINSPECCION," + " t1.NOTAS NOTAS, t1.FECHA_REGISTRO FECHAREGISTRO ,"
				+ " t1.USUARIO_REGISTRO USUARIOREGISTRO, "
				+ "t1.IDENTIFICADOR_PRO_SAN IDPROSANREMOTO, t1.IDENTIFICADOR_PRO_SAN_DES IDPROSANREMOTODES ");
		query.append(" FROM PROPUESTAS_SANCION t1");
		query.append(" WHERE ID_INSPECCION = ?");
		List<PropuestaSancion> listaPropuestas = this.jdbcTemplate.query(query.toString(), this.rwMap,
				propuestaSancion.getIdPropuestaSancion());
		return DataAccessUtils.uniqueResult(listaPropuestas);
	}

	@Override
	public List<PropuestaSancion> findAll(PropuestaSancion propuestaSancion, TableRequestDto tableRequestdto) {
		StringBuilder query = new StringBuilder(
				"SELECT t1.ID_PROPUESTA_SANCION IDPROPUESTASANCION, t1.ID_INSPECCION IDINSPECCION,"
						+ " t1.NOTAS NOTAS , t1.FECHA_REGISTRO FECHAREGISTRO ,"
						+ " t1.USUARIO_REGISTRO USUARIOREGISTRO, "
						+ " t1.IDENTIFICADOR_PRO_SAN IDPROSANREMOTO, t1.IDENTIFICADOR_PRO_SAN_DES IDPROSANREMOTODES ");
		query.append(" FROM PROPUESTAS_SANCION t1");
		// Where clause & params
		Map<String, ?> mapaWhere = this.getWhereMap(propuestaSancion);
		StringBuilder where = new StringBuilder(" WHERE 1=1 ");
		where.append(mapaWhere.get("query"));
		query.append(where);

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

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

	}

	public static final int STRING_BUILDER_INIT = 4096;

	@Override
	public void updatePropuesta(PropuestaSancion filterPropuesta) {
		if (filterPropuesta.getNotas() != null) {
			StringBuilder query = new StringBuilder(
					"UPDATE PROPUESTAS_SANCION SET NOTAS=?, FECHA_ULTMODIFICACION=sysdate, USUARIO_ULTMODIFICACION=? WHERE ID_PROPUESTA_SANCION=?");
			this.jdbcTemplate.update(query.toString(), filterPropuesta.getNotas(),
					filterPropuesta.getUsuarioUltmodificacion(),
					String.valueOf(filterPropuesta.getIdPropuestaSancion()));
		}
		if (filterPropuesta.getIdPropuestaSancionRemoto() > 0) {
			StringBuilder query = new StringBuilder(
					"UPDATE PROPUESTAS_SANCION SET IDENTIFICADOR_PRO_SAN= ?, IDENTIFICADOR_PRO_SAN_DES=? WHERE ID_PROPUESTA_SANCION=?");
			this.jdbcTemplate.update(query.toString(), filterPropuesta.getIdPropuestaSancionRemoto(),
					filterPropuesta.getIdentificadorProSanDesc(),
					String.valueOf(filterPropuesta.getIdPropuestaSancion()));
		}
	}

	/**
	 * Buscar la descripción del estado de una propuesta
	 *
	 * @param idPropuestaRemoto
	 *            Integer
	 * @return String
	 */
	@Override
	public EstadosProSan findDescEstadoPropuesta(Integer idPropuestaRemoto) {
		StringBuilder query = new StringBuilder();

		query.append(
				"SELECT t5918.ID_ESTADO_PRO_SAN IDESTADOPROSAN, t5918.DESCRIPCION_CASTELLANO DESCRIPCIONCASTELLANO, t5918.DESCRIPCION_EUSKERA DESCRIPCIONEUSKERA");
		query.append(" FROM REL_PRO_SAN_SAN T6128, AB59.ESTADOS_PRO_SAN t5918");
		query.append(" WHERE t6128.ID_ESTADO_PRO_SAN = t5918.ID_ESTADO_PRO_SAN AND t6128.ID_PROPUESTA_SANCION = ?");
		List<EstadosProSan> estadoPropuestaList = this.jdbcTemplate.query(query.toString(),
				this.rwMapDescEstadoPropuesta, idPropuestaRemoto);

		return DataAccessUtils.uniqueResult(estadoPropuestaList);

	}

	/**
	 * Buscar el estado de la propuesta de una inspección
	 *
	 * @param idInspeccion
	 *            Integer
	 * @return Integer
	 */
	@Override
	public Integer comprobarEstadoPropuesta(Integer idInspeccion) {

		StringBuilder query = new StringBuilder();
		List<Object> params = new ArrayList<Object>();

		query.append("SELECT t6128.ID_ESTADO_PRO_SAN IDESTADOPROSAN");
		query.append(" FROM REL_PRO_SAN_SAN t6128");
		query.append(" INNER JOIN PROPUESTAS_SANCION t30 ON t6128.ID_PROPUESTA_SANCION = t30.IDENTIFICADOR_PRO_SAN");
		query.append(" WHERE t30.ID_INSPECCION = ?");
		params.add(idInspeccion);

		List<Integer> estadoPropuestaList = this.jdbcTemplate.query(query.toString(), this.rwMapEstadoPropuesta,
				params.toArray());

		return DataAccessUtils.uniqueResult(estadoPropuestaList);

	}
}
