package com.ejie.ab61.dao.terceros;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

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.ab61.model.terceros.CanalesAviso;
import com.ejie.ab61.model.terceros.DatosTerceros;
import com.ejie.ab61.model.terceros.TiposCanalAviso;

/**
 * CanalesAvisoDaoImpl  
 * 
 *  
 */

@Repository
@Transactional
public class CanalesAvisoDaoImpl implements CanalesAvisoDao {

	public static final String[] ORDER_BY_WHITE_LIST = new String[] { "IDCANALAVISO", "CANALAVISO", "FECHAREGISTRO",
			"USUARIOREGISTRO", "TERCEROSIDTERCERO", "TERCEROSDOCUMENTO", "TERCEROSNOMBRE", "TERCEROSAPELLIDO1",
			"TERCEROSAPELLIDO2", "TERCEROSSEXO", "TERCEROSFECHANACIMIENTO", "TERCEROSCARGO", "TERCEROSIDPAISNACIMIENTO",
			"TERCEROSIDPROVINCIANACIMIENTO", "TERCEROSIDMUNICIPIONACIMIENTO", "TERCEROSTERRITORIONACIMIENTO",
			"TERCEROSLOCALIDADNACIMIENTO", "TERCEROSNUMSEGSOCIAL", "TERCEROSFECHAREGISTRO", "TERCEROSUSUARIOREGISTRO",
			"TERCEROSFECHAULTMODIFICACION", "TERCEROSUSUARIOULTMODIFICACION", "TIPOSCANALAVISOIDTIPOCANALAVISO",
			"TIPOSCANALAVISODESCRIPCIONCASTELLANO", "TIPOSCANALAVISODESCRIPCIONEUSKERA", "TIPOSCANALAVISOFECHAREGISTRO",
			"TIPOSCANALAVISOUSUARIOREGISTRO", "TERCEROSIDTIPOTERCERO", "TERCEROSIDTIPODOCUMENTO",
			"EMPRESASIDTIPOTERCERO" };

	private JdbcTemplate jdbcTemplate;

	/*
	 * ROW_MAPPERS
	 */
	private RowMapper<CanalesAviso> rwMap = new RowMapper<CanalesAviso>() {
		public CanalesAviso mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			return new CanalesAviso(resultSet.getInt("IDCANALAVISO"), resultSet.getString("CANALAVISO"),
					resultSet.getDate("FECHAREGISTRO"), resultSet.getString("USUARIOREGISTRO"),
					new DatosTerceros(resultSet.getInt("IDTERCERO"), null, null, null, null, null, null, null, null,
							null, null, null, null, null, null),
					new TiposCanalAviso(resultSet.getLong("TiposCanalAvisoIDTIPOCANALAVISO"),
							resultSet.getString("TiposCanalAvisoDESCRIPCIONCASTELLANO"),
							resultSet.getString("TiposCanalAvisoDESCRIPCIONEUSKERA"),
							resultSet.getDate("TiposCanalAvisoFECHAREGISTRO"),
							resultSet.getString("TiposCanalAvisoUSUARIOREGISTRO")));
		}
	};

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

	private RowMapper<CanalesAviso> rwMapTipoCanal = new RowMapper<CanalesAviso>() {
		public CanalesAviso mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			return new CanalesAviso(null, null, null, null,
					new DatosTerceros(null, null, null, null, null, null, null, null, null, null, null, null, null,
							null, null),
					new TiposCanalAviso(resultSet.getLong("IDTIPOCANALAVISO"), null, null, null, null));
		}
	};

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

			CanalesAviso canalesAviso = new CanalesAviso();
			canalesAviso.setCanalAviso(resultSet.getString("CANALAVISO"));

			TiposCanalAviso tipoCanalAvisoAux = new TiposCanalAviso();
			tipoCanalAvisoAux.setIdTipoCanalAviso(resultSet.getLong("IDTIPOCANALAVISO"));

			canalesAviso.setTiposCanalAviso(tipoCanalAvisoAux);

			return canalesAviso;
		}
	};

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

	/*
	 * OPERACIONES CRUD
	 */

	/**
	 * Inserts a single row in the CanalesAviso table.
	 *
	 * @param canalesaviso
	 *            CanalesAviso
	 * @return CanalesAviso
	 */
	public CanalesAviso add(CanalesAviso canalesaviso) {
		String query = "INSERT INTO CANALES_AVISO (ID_CANAL_AVISO, ID_TERCERO, ID_TIPO_CANAL_AVISO, CANAL_AVISO, FECHA_REGISTRO, USUARIO_REGISTRO) VALUES (?,?,?,?,?,?)";
		Object getTercerosIdTerceroAux = null;
		if (canalesaviso.getDatosTerceros() != null && canalesaviso.getDatosTerceros().getIdTercero() != null) {
			getTercerosIdTerceroAux = canalesaviso.getDatosTerceros().getIdTercero();
		}
		Object getTiposCanalAvisoIdTipoCanalAvisoAux = null;
		if (canalesaviso.getTiposCanalAviso() != null
				&& canalesaviso.getTiposCanalAviso().getIdTipoCanalAviso() != null) {
			getTiposCanalAvisoIdTipoCanalAvisoAux = canalesaviso.getTiposCanalAviso().getIdTipoCanalAviso();
		}

		this.jdbcTemplate.update(query, canalesaviso.getIdCanalAviso(), getTercerosIdTerceroAux,
				getTiposCanalAvisoIdTipoCanalAvisoAux, canalesaviso.getCanalAviso(), canalesaviso.getFechaRegistro(),
				canalesaviso.getUsuarioRegistro());
		return canalesaviso;
	}

	/**
	 * Inserts a single row in the CanalesAviso table.
	 *
	 * @param canalesaviso
	 *            CanalesAviso
	 * @return CanalesAviso
	 */
	public CanalesAviso addCanalesAviso(CanalesAviso canalesaviso) {
		String query = "INSERT INTO CANALES_AVISO (ID_CANAL_AVISO, ID_DATO_TERCERO, ID_TIPO_CANAL_AVISO, CANAL_AVISO,FECHA_REGISTRO, USUARIO_REGISTRO) VALUES (AB61.S_AB6116T00.NEXTVAL,?,?,?,?,?)";
		Object getTercerosIdTerceroAux = null;
		if (canalesaviso.getDatosTerceros() != null && canalesaviso.getDatosTerceros().getIdTercero() != null) {
			getTercerosIdTerceroAux = canalesaviso.getDatosTerceros().getIdTercero();
		}
		Object getTiposCanalAvisoIdTipoCanalAvisoAux = null;
		if (canalesaviso.getTiposCanalAviso() != null
				&& canalesaviso.getTiposCanalAviso().getIdTipoCanalAviso() != null) {
			getTiposCanalAvisoIdTipoCanalAvisoAux = canalesaviso.getTiposCanalAviso().getIdTipoCanalAviso();
		}

		this.jdbcTemplate.update(query, getTercerosIdTerceroAux, getTiposCanalAvisoIdTipoCanalAvisoAux,
				canalesaviso.getCanalAviso(), canalesaviso.getFechaRegistro(), canalesaviso.getUsuarioRegistro());
		return canalesaviso;
	}

	/**
	 * Updates a single row in the CanalesAviso table.
	 *
	 * @param canalesaviso
	 *            CanalesAviso
	 * @return CanalesAviso
	 */
	public CanalesAviso update(CanalesAviso canalesaviso) {
		String query = "UPDATE CANALES_AVISO SET ID_TERCERO=?, ID_TIPO_CANAL_AVISO=?, CANAL_AVISO=?, FECHA_REGISTRO=?, USUARIO_REGISTRO=? WHERE ID_CANAL_AVISO=?";
		Object getTercerosIdTerceroAux = null;
		if (canalesaviso.getDatosTerceros() != null && canalesaviso.getDatosTerceros().getIdTercero() != null) {
			getTercerosIdTerceroAux = canalesaviso.getDatosTerceros().getIdTercero();
		}
		Object getTiposCanalAvisoIdTipoCanalAvisoAux = null;
		if (canalesaviso.getTiposCanalAviso() != null
				&& canalesaviso.getTiposCanalAviso().getIdTipoCanalAviso() != null) {
			getTiposCanalAvisoIdTipoCanalAvisoAux = canalesaviso.getTiposCanalAviso().getIdTipoCanalAviso();
		}

		this.jdbcTemplate.update(query, getTercerosIdTerceroAux, getTiposCanalAvisoIdTipoCanalAvisoAux,
				canalesaviso.getCanalAviso(), canalesaviso.getFechaRegistro(), canalesaviso.getUsuarioRegistro(),
				canalesaviso.getIdCanalAviso());
		return canalesaviso;
	}

	/**
	 * Updates a single row in the CanalesAviso table.
	 *
	 * @param canalesaviso
	 *            CanalesAviso
	 * @return CanalesAviso
	 */
	public CanalesAviso updateCanalAviso(CanalesAviso canalesaviso) {
		String query = "UPDATE CANALES_AVISO SET  CANAL_AVISO=?, FECHA_REGISTRO=?, USUARIO_REGISTRO=? WHERE ID_DATO_TERCERO = ? AND ID_TIPO_CANAL_AVISO = ?";
		Object getTercerosIdTerceroAux = null;
		if (canalesaviso.getDatosTerceros() != null && canalesaviso.getDatosTerceros().getIdTercero() != null) {
			getTercerosIdTerceroAux = canalesaviso.getDatosTerceros().getIdTercero();
		}
		Object getTiposCanalAvisoIdTipoCanalAvisoAux = null;
		if (canalesaviso.getTiposCanalAviso() != null
				&& canalesaviso.getTiposCanalAviso().getIdTipoCanalAviso() != null) {
			getTiposCanalAvisoIdTipoCanalAvisoAux = canalesaviso.getTiposCanalAviso().getIdTipoCanalAviso();
		}

		this.jdbcTemplate.update(query, canalesaviso.getCanalAviso(), canalesaviso.getFechaRegistro(),
				canalesaviso.getUsuarioRegistro(), getTercerosIdTerceroAux, getTiposCanalAvisoIdTipoCanalAvisoAux);
		return canalesaviso;
	}

	/**
	 * Buscar que canales tiene un id tercero.
	 *
	 * @param canalesaviso
	 *            CanalesAviso
	 * @return CanalesAviso
	 */
	@Transactional(readOnly = true)
	public Integer findCanalByIdTercero(CanalesAviso canalesAviso) {

		String query = "SELECT COUNT(T1.ID_CANAL_AVISO) AS TOTAL FROM  CANALES_AVISO T1  WHERE T1.ID_DATO_TERCERO = ? AND  T1.ID_TIPO_CANAL_AVISO = ?";
		List<Integer> canalesavisoList = this.jdbcTemplate.query(query, this.rwMapExisteCanal,
				canalesAviso.getDatosTerceros().getIdTercero(),
				canalesAviso.getTiposCanalAviso().getIdTipoCanalAviso());
		return (Integer) DataAccessUtils.uniqueResult(canalesavisoList);

	}

	/**
	 * Busca todos los caneles de aviso de un tercero
	 *
	 * @param canalesaviso
	 *            CanalesAviso
	 * @return CanalesAviso
	 */
	@Transactional(readOnly = true)
	public List<CanalesAviso> findCanalesAvisoByIdTercero(Integer idTercero) {
		String query = "SELECT T1.ID_TIPO_CANAL_AVISO AS IDTIPOCANALAVISO FROM CANALES_AVISO T1 WHERE T1.ID_DATO_TERCERO = ?";
		List<CanalesAviso> canalesAvisoList = this.jdbcTemplate.query(query, this.rwMapTipoCanal, idTercero);
		return canalesAvisoList;
	}

	/**
	 * Buscar que canales tiene un id tercero.
	 *
	 * @param canalesaviso
	 *            CanalesAviso
	 * @return CanalesAviso
	 */
	@Transactional(readOnly = true)
	public Integer findTodosLosCanalByIdTercero(Integer idTercero) {

		String query = "SELECT COUNT(T1.ID_CANAL_AVISO) AS TOTAL FROM  CANALES_AVISO T1  WHERE T1.ID_DATO_TERCERO = ?";
		List<Integer> canalesavisoList = this.jdbcTemplate.query(query, this.rwMapExisteCanal, idTercero);
		return (Integer) DataAccessUtils.uniqueResult(canalesavisoList);

	}

	/**
	 * Finds a single row in the CanalesAviso table.
	 *
	 * @param canalesaviso
	 *            CanalesAviso
	 * @return CanalesAviso
	 */
	@Transactional(readOnly = true)
	public CanalesAviso find(CanalesAviso canalesaviso) {
		String query = "SELECT t1.ID_CANAL_AVISO IDCANALAVISO, t1.CANAL_AVISO CANALAVISO, t1.FECHA_REGISTRO FECHAREGISTRO, t1.USUARIO_REGISTRO USUARIOREGISTRO, t2.ID_TERCERO TERCEROSIDTERCERO, t2.DOCUMENTO TERCEROSDOCUMENTO, t2.NOMBRE TERCEROSNOMBRE, t2.APELLIDO1 TERCEROSAPELLIDO1, t2.APELLIDO2 TERCEROSAPELLIDO2, t2.SEXO TERCEROSSEXO, t2.FECHA_NACIMIENTO TERCEROSFECHANACIMIENTO, t2.CARGO TERCEROSCARGO, t2.ID_PAIS_NACIMIENTO TERCEROSIDPAISNACIMIENTO, t2.ID_PROVINCIA_NACIMIENTO TERCEROSIDPROVINCIANACIMIENTO, t2.ID_MUNICIPIO_NACIMIENTO TERCEROSIDMUNICIPIONACIMIENTO, t2.TERRITORIO_NACIMIENTO TERCEROSTERRITORIONACIMIENTO, t2.LOCALIDAD_NACIMIENTO TERCEROSLOCALIDADNACIMIENTO, t2.NUM_SEG_SOCIAL TERCEROSNUMSEGSOCIAL, t2.FECHA_REGISTRO TERCEROSFECHAREGISTRO, t2.USUARIO_REGISTRO TERCEROSUSUARIOREGISTRO, t2.FECHA_ULTMODIFICACION TERCEROSFECHAULTMODIFICACION, t2.USUARIO_ULTMODIFICACION TERCEROSUSUARIOULTMODIFICACION, t3.ID_TIPO_CANAL_AVISO TIPOSCANALAVISOIDTIPOCANALAVISO, t3.DESCRIPCION_CASTELLANO TIPOSCANALAVISODESCRIPCIONCASTELLANO, t3.DESCRIPCION_EUSKERA TIPOSCANALAVISODESCRIPCIONEUSKERA, t3.FECHA_REGISTRO TIPOSCANALAVISOFECHAREGISTRO, t3.USUARIO_REGISTRO TIPOSCANALAVISOUSUARIOREGISTRO, t4.ID_EMPRESA EMPRESASIDEMPRESA, t4.NOMBRE EMPRESASNOMBRE, t4.NIF EMPRESASNIF, t4.DIRECCION EMPRESASDIRECCION, t4.NUMERO EMPRESASNUMERO, t4.PISO EMPRESASPISO, t4.LETRA EMPRESASLETRA, t4.CODIGO_POSTAL EMPRESASCODIGOPOSTAL, t4.PAGINA_WEB EMPRESASPAGINAWEB, t4.ID_PROVINCIA EMPRESASIDPROVINCIA, t4.ID_MUNICIPIO EMPRESASIDMUNICIPIO, t4.ID_LOCALIDAD EMPRESASIDLOCALIDAD, t4.ID_IAE EMPRESASIDIAE, t4.FECHA_ALTA_EMPRESA EMPRESASFECHAALTAEMPRESA, t4.FECHA_ALTA_ESTABL EMPRESASFECHAALTAESTABL, t4.NUMERO_SOCIOS EMPRESASNUMEROSOCIOS, t4.NUMERO_SOCIAS EMPRESASNUMEROSOCIAS, t4.FECHA_REGISTRO EMPRESASFECHAREGISTRO, t4.USUARIO_REGISTRO EMPRESASUSUARIOREGISTRO, t2.ID_TIPO_TERCERO TERCEROSIDTIPOTERCERO, t2.ID_TIPO_DOCUMENTO TERCEROSIDTIPODOCUMENTO, t4.ID_TIPO_TERCERO EMPRESASIDTIPOTERCERO FROM CANALES_AVISO t1 , TERCEROS t2 , TIPOS_CANAL_AVISO t3 , EMPRESAS t4  WHERE t1.ID_CANAL_AVISO = ?   AND t1.ID_TERCERO= t2.ID_TERCERO(+) AND t1.ID_TIPO_CANAL_AVISO= t3.ID_TIPO_CANAL_AVISO(+) AND t1.ID_EMPRESA= t4.ID_EMPRESA(+)";

		List<CanalesAviso> canalesavisoList = this.jdbcTemplate.query(query, this.rwMap,
				canalesaviso.getIdCanalAviso());
		return (CanalesAviso) DataAccessUtils.uniqueResult(canalesavisoList);
	}

	/**
	 * Removes a single row in the CanalesAviso table.
	 *
	 * @param canalesaviso
	 *            CanalesAviso
	 * @return
	 */
	public void remove(CanalesAviso canalesaviso) {
		String query = "DELETE FROM CANALES_AVISO WHERE ID_CANAL_AVISO=?";
		this.jdbcTemplate.update(query, canalesaviso.getIdCanalAviso());
	}

	/**
	 * Eliminar un tipo de canal de un id tercero
	 *
	 * @param canalesaviso
	 *            CanalesAviso
	 * @return
	 */
	public void removeCanalesByIdTercero(CanalesAviso canalesaviso) {
		String query = "DELETE FROM CANALES_AVISO WHERE ID_TIPO_CANAL_AVISO = ? AND ID_DATO_TERCERO = ? ";
		this.jdbcTemplate.update(query, canalesaviso.getTiposCanalAviso().getIdTipoCanalAviso(),
				canalesaviso.getDatosTerceros().getIdTercero());
	}

	/**
	 * Borrar los canaels de aviso de un tercero
	 *
	 * @param canalesaviso
	 *            CanalesAviso
	 * @return
	 */
	public void removeCanalesTercero(Integer idTercero) {
		String query = "DELETE FROM CANALES_AVISO WHERE ID_DATO_TERCERO=?";
		this.jdbcTemplate.update(query, idTercero);
	}
	// CHECKSTYLE:ON CyclomaticComplexity - Generación de código de UDA

	/**
	 * Buscar los datos del canal de aviso de un tercero
	 *
	 * @param idTercero
	 *            Integer
	 * 
	 * @return List<CanalesAviso>
	 */
	@Transactional(readOnly = true)
	public List<CanalesAviso> findCanalesTercero(Integer idTercero) {

		String query = "SELECT t2.ID_TIPO_CANAL_AVISO IDTIPOCANALAVISO, t1.CANAL_AVISO CANALAVISO FROM CANALES_AVISO t1 INNER JOIN TIPOS_CANAL_AVISO t2 ON t1.ID_TIPO_CANAL_AVISO = t2.ID_TIPO_CANAL_AVISO WHERE ID_DATO_TERCERO = ?";

		return this.jdbcTemplate.query(query, this.rwMapTercero, idTercero);
	}

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