package com.ejie.t17i.dao;

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

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
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.m62fb.utils.sql.LikeInWhere;
import com.ejie.t17i.filters.CalleFilter;
import com.ejie.t17i.model.Calle;
import com.ejie.t17i.model.Municipio;
import com.ejie.t17i.model.Provincia;
import com.ejie.t17i.model.TipoVia;
import com.ejie.x38.dto.JQGridManager;
import com.ejie.x38.dto.JQGridRequestDto;
import com.ejie.x38.util.Constants;

/**
 * <p>
 * Implementaci&oacute;n de servicios DAO para acceder a la tabla CALLE de NORA
 * </p>
 * 
XXXX
 * @see com.ejie.t17i.model.Calle
 * @see com.ejie.t17i.model.Municipio
 * @see com.ejie.t17i.model.Provincia
 * @see com.ejie.t17i.model.TipoVia
 * @see com.ejie.t17i.dao.CalleDao
 */
@Repository
@Transactional
public class CalleDaoImpl implements CalleDao {

	private static final String FIND_ALL_COUNT_SQL = "SELECT COUNT(1) FROM T17_CALLE t1 ";

	private JdbcTemplate jdbcTemplate;
	@Autowired
	private MunicipioDao municipioDao;
	@Autowired
	private TipoViaDao tipoViaDao;

	/** RowMapper para el resultado de la sentencia FIND_SQL */
	private final RowMapper<Calle> rwMapDetail = new RowMapper<Calle>() {
		@Override
		public Calle mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			return new Calle(resultSet.getBigDecimal("ID"),
					resultSet.getString("CALLE_DESC_ES"),
					resultSet.getString("CALLE_DESC_EU"),
					resultSet.getString("ESTADO"),
					resultSet.getBigDecimal("CALLECOD"),
					municipioDao.find(new Municipio(resultSet
							.getString("MUNICIPIOID"), new Provincia(resultSet
							.getString("PROVINCIAID")))),
					tipoViaDao.find(new TipoVia(resultSet
							.getString("TIPOVIAID"))));
		}
	};
	/** RowMapper para el resultado de la sentencia FIND_ALL_SQL */
	private final RowMapper<Calle> rwMap = new RowMapper<Calle>() {
		@Override
		public Calle mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			String nombreEs = resultSet.getString("TIPO_VIA_DESC_ES");
			// int delimiterPos = nombreEs.indexOf("/");
			// if(delimiterPos>0){
			// nombreEs = nombreEs.substring(0, delimiterPos);
			// }
			String nombreEu = resultSet.getString("TIPO_VIA_DESC_EU");
			// delimiterPos = nombreEu.indexOf("/");
			// if(delimiterPos>0){
			// nombreEu = nombreEu.substring(0, delimiterPos);
			// }
			return new Calle(resultSet.getBigDecimal("ID"),
					resultSet.getString("CALLE_DESC_ES"),
					resultSet.getString("CALLE_DESC_EU"),
					resultSet.getString("ESTADO"),
					resultSet.getBigDecimal("CALLECOD"), null, new TipoVia(
							resultSet.getString("TIPOVIAID"), nombreEu,
							nombreEs));

		}
	};
	private final RowMapper<Calle> rwMapCombo = new RowMapper<Calle>() {
		@Override
		public Calle mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			String nombreEs = resultSet.getString("TIPO_VIA_DESC_ES");
			// int delimiterPos = nombreEs.indexOf("/");
			// if(delimiterPos>0){
			// nombreEs = nombreEs.substring(0, delimiterPos);
			// }
			String nombreEu = resultSet.getString("TIPO_VIA_DESC_EU");
			// delimiterPos = nombreEu.indexOf("/");
			// if(delimiterPos>0){
			// nombreEu = nombreEu.substring(0, delimiterPos);
			// }
			return new Calle(resultSet.getBigDecimal("ID"),
					resultSet.getString("CALLE_DESC_ES"), null, null, null,
					null, new TipoVia(resultSet.getString("TIPOVIAID"),
							nombreEu, nombreEs));
		}
	};

	/**
	 * M&eacute;todo que asigna el DataSource a usar para el acceso a BBDD.
	 * 
	 * @param dataSource
	 *            El DataSource a usar.
	 */
	@Resource
	public void setDataSource(final DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	@Transactional(readOnly = true)
	public Calle find(Calle calle) {
		List<Calle> calleList = this.jdbcTemplate.query(CalleDaoSql.SQL_FIND,
				this.rwMapDetail, calle.getId());
		return DataAccessUtils.uniqueResult(calleList);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	@Transactional(readOnly = true)
	public Calle findByCalleCod(Calle calle) {
		List<Calle> calleList = this.jdbcTemplate.query(CalleDaoSql.SQL_FIND_BY_CALLE_COD,
				this.rwMapDetail, calle.getCalleCod());
		return DataAccessUtils.uniqueResult(calleList);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	@Transactional(readOnly = true)
	public List<Calle> findAll(Calle calle, JQGridRequestDto jqGridRequestDto) {
		StringBuilder query = new StringBuilder(
				CalleDaoSql.SQL_FIND_ALL.length())
				.append(CalleDaoSql.SQL_FIND_ALL);
		final List<Object> params = new ArrayList<Object>();

		CalleFilter filtro = new CalleFilter(calle, params, query, null);
		filtro.generarWhereBE();

		if (jqGridRequestDto != null) {
			query = JQGridManager.getPaginationQuery(jqGridRequestDto, query);
		} else {
			Locale locale = LocaleContextHolder.getLocale();
			if (locale.getLanguage().equalsIgnoreCase(Constants.CASTELLANO)) {
				query.append(CalleDaoSql.ORDER_ES);
			} else {
				query.append(CalleDaoSql.ORDER_EU);
			}
		}
		return this.jdbcTemplate.query(query.toString(), rwMap,
				params.toArray());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	@Transactional(readOnly = true)
	public Long findAllCount(Calle calle) {

		final StringBuilder query = new StringBuilder(
				CalleDaoImpl.FIND_ALL_COUNT_SQL.length())
				.append(CalleDaoImpl.FIND_ALL_COUNT_SQL);
		final List<Object> params = new ArrayList<Object>();

		CalleFilter filtro = new CalleFilter(calle, params, query, null);
		filtro.generarWhereBE();

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	@Transactional(readOnly = true)
	public List<Calle> findAllLike(Calle calle,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		StringBuilder query = new StringBuilder(
				CalleDaoSql.SQL_FIND_ALL.length())
				.append(CalleDaoSql.SQL_FIND_ALL);
		final List<Object> params = new ArrayList<Object>();

		CalleFilter filtro = new CalleFilter(calle, params, query,
				new LikeInWhere(true, startsWith));
		filtro.generarWhereBE();
		if (jqGridRequestDto != null) {
			query = JQGridManager.getPaginationQuery(jqGridRequestDto, query);
		} else {
			Locale locale = LocaleContextHolder.getLocale();
			if (locale.getLanguage().equalsIgnoreCase(Constants.CASTELLANO)) {
				query.append(CalleDaoSql.ORDER_ES);
			} else {
				query.append(CalleDaoSql.ORDER_EU);
			}
		}

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

	// /**
	// * Funci&oacute;n que nos compone la clausula where y los
	// par&aacute;metros.
	// *
	// * @param filtro <code>Calle</code> utilizado como filtro.
	// * @param params Listado de parametros para la clausula where.
	// * @param query Clausula where.
	// */
	// protected void whereAppender (Calle filtro, List<Object> params,
	// StringBuilder query){
	// if(filtro!=null){
	// if(filtro.getId()!=null){
	// query.append(" AND t1.ID = ?");
	// params.add(filtro.getId());
	// }
	// if(filtro.getNombreEs()!=null){
	// query.append(" AND t1.DS_O = ?");
	// params.add(filtro.getNombreEs());
	// }
	// if(filtro.getNombreEu()!=null){
	// query.append(" AND t1.DS_E = ?");
	// params.add(filtro.getNombreEu());
	// }
	// if(filtro.getMunicipio()!=null){
	// if(filtro.getMunicipio().getProvincia()!=null &&
	// filtro.getMunicipio().getProvincia().getId()!=null){
	// query.append(" AND t1.PROVINCIA_ID = ?");
	// params.add(filtro.getMunicipio().getProvincia().getId());
	// }
	// if(filtro.getMunicipio().getId()!= null){
	// query.append(" AND t1.MUNICIPIO_ID = ?");
	// params.add(filtro.getMunicipio().getId());
	// }
	// }
	// if(filtro.getTipoVia()!=null){
	// if(filtro.getTipoVia().getId()!=null){
	// query.append(" AND t1.TIPO_VIA_ID = ?");
	// params.add(filtro.getTipoVia().getId());
	// }
	// if(filtro.getTipoVia().getNombreEs()!=null){
	// query.append(" AND t2.DS_C = ?");
	// params.add(filtro.getTipoVia().getNombreEs());
	// }
	// if(filtro.getTipoVia().getNombreEu()!=null){
	// query.append(" AND t2.DS_E = ?");
	// params.add(filtro.getTipoVia().getNombreEu());
	// }
	// }
	// if(filtro.getEstado()!=null){
	// query.append(" AND t1.ESTADO = ?");
	// params.add(filtro.getEstado());
	// }
	// }
	// }
}
