package com.ejie.y41e.dao;

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

import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.ejie.y41e.common.Y41eConstants;
import com.ejie.y41e.dao.rwmap.Y41eEnvioRowMapper;
import com.ejie.y41e.model.Y41eEnvio;
import com.ejie.y41e.utils.Y41eSqlUtils;

/**
 * Y41eEnviosDaoImpl
 *  
 */

@Repository
@Transactional
public class Y41eEnviosDaoImpl extends Y41eGenericoDaoImpl<Y41eEnvio> implements Y41eEnviosDao {


    public static final String TABLA="Y41E10S01";
    public static final String SECUENCIA="Y41E10Q00";
    public static final String ID_ENVIO_010="ID_ENVIO_010";
    public static final String ID_USUARIO_010="ID_USUARIO_010";
    public static final String DATA_USUARIO_010="DATA_USUARIO_010";
    public static final String ID_ENCUESTA_010="ID_ENCUESTA_010";
    public static final String EMAIL_010="EMAIL_010";
    public static final String PARAM_010="PARAM_010";
    public static final String FEC_RESPUESTA_010="FEC_RESPUESTA_010";
    public static final String FEC_ENVIO_001="FEC_ENVIO_001";
    protected static final String[] ORDER_BY_WHITE_LIST = new String[] { ID_ENVIO_010, ID_USUARIO_010, ID_ENCUESTA_010, EMAIL_010,
            PARAM_010, FEC_RESPUESTA_010, "DESC_PUBL_ES_001", "DESC_PUBL_EU_001", "DESC_INT_ES_001", "DESC_INT_EU_001", FEC_ENVIO_001,
            "DESC_ES_006", "DESC_EU_006", "DESC_ES_007", "DESC_EU_007"};

    /**
     * Y41eEnviosDaoImpl
     */
    public Y41eEnviosDaoImpl() {
        super(Y41eEnvio.class);
    }


    /*
     * ROW_MAPPERS
     */
    private final RowMapper<Y41eEnvio> rwMapPK = new RowMapper<Y41eEnvio>() {
        @Override
        public Y41eEnvio mapRow(ResultSet resultSet, int rowNum) throws SQLException {
            return new Y41eEnvio( resultSet.getLong(ID_ENVIO_010)); 
        }
    };

    /* (non-Javadoc)
     * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getSelect()
     */
    @Override
    protected String getSelect() {
        StringBuilder select = new StringBuilder(Y41eSqlUtils.SELECT)
                .append("DESC_PUBL_ES_001, DESC_PUBL_EU_001, DESC_INT_ES_001,DESC_INT_EU_001,") 
                .append("ID_AREA_001, ID_ORIGEN_001, DESC_ES_006, DESC_EU_006,")
                .append("DESC_ES_007, DESC_EU_007,")
                .append(FEC_ENVIO_001).append(",")
                .append(ID_ENCUESTA_010).append(",")
                .append(ID_ENVIO_010).append(",")
                .append(ID_USUARIO_010).append(",")
                .append(EMAIL_010).append(",")
                .append(FEC_RESPUESTA_010);

        return select.toString();
    }

    /* (non-Javadoc)
     * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getFrom()
     */
    @Override
    protected String getFrom() {
        StringBuilder from = new StringBuilder(Y41eSqlUtils.FROM)
                .append(" Y41E01S01 LEFT JOIN Y41E06S01 ON ID_ORIGEN_001=ID_ORIGEN_006")
                .append(" LEFT JOIN Y41E07S01 ON ID_AREA_001 = ID_AREA_007")
                .append(" JOIN ").append(TABLA).append(" ON ID_ENCUESTA_001 = ").append(ID_ENCUESTA_010);
        return from.toString();
    }

    /* (non-Javadoc)
     * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getRwMap()
     */
    @Override
    protected RowMapper<Y41eEnvio> getRwMap() {
        return new Y41eEnvioRowMapper();
    }

    /* (non-Javadoc)
     * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getPK()
     */
    @Override
    protected String getPK() {
        return ID_ENVIO_010;
    }

    /* (non-Javadoc)
     * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getRwMapPK()
     */
    @Override
    protected RowMapper<Y41eEnvio> getRwMapPK() {
        return this.rwMapPK;
    }

    /* (non-Javadoc)
     * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getWherePK(java.lang.Object, java.util.List)
     */
    @Override
    protected String getWherePK(Y41eEnvio bean, List<Object> params) {
        StringBuilder wherePK = new StringBuilder();
        wherePK.append(Y41eSqlUtils.WHERE).append(ID_ENVIO_010).append("=?");
        params.add(bean.getIdEnvio());
        return wherePK.toString();

    }

    /* (non-Javadoc)
     * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getWhere(java.lang.Object, java.util.List)
     */
    @Override
    protected String getWhere(Y41eEnvio bean, List<Object> params) {
        StringBuilder where = new StringBuilder(Y41eEnviosDaoImpl.STRING_BUILDER_INIT);

        if (bean  != null){
            where.append(Y41eSqlUtils.generarWhereIgual(ID_ENVIO_010, bean.getIdEnvio(), params));
            where.append(Y41eSqlUtils.generarWhereIgual(ID_USUARIO_010, bean.getIdUsuario(), params));
            where.append(Y41eSqlUtils.generarWhereIgual(ID_ENCUESTA_010, bean.getEncuesta().getIdEncuesta(), params));
            where.append(Y41eSqlUtils.generarWhereIgual(EMAIL_010, bean.getEmail(), params));
            where.append(Y41eSqlUtils.generarWhereIgual(FEC_RESPUESTA_010, bean.getFecRespuesta(), params));
        }

        return where.toString();
    }

    /* (non-Javadoc)
     * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getWhereLike(java.lang.Object, java.lang.Boolean, java.util.List, java.lang.Boolean)
     */
    @Override
    protected String getWhereLike(Y41eEnvio bean, Boolean startsWith, List<Object> params, Boolean search) {
        StringBuilder where = new StringBuilder(Y41eEnviosDaoImpl.STRING_BUILDER_INIT);
        Locale locale = LocaleContextHolder.getLocale();
        if (bean  != null){
            where.append(Y41eSqlUtils.generarWhereIgual(ID_ENVIO_010, bean.getIdEnvio(), params));
            where.append(Y41eSqlUtils.generarWhereLikeNormalizado(ID_USUARIO_010, bean.getIdUsuario(), params, startsWith));
            where.append(Y41eSqlUtils.generarWhereIgual(ID_ENCUESTA_010, bean.getEncuesta().getIdEncuesta(), params));
            where.append(Y41eSqlUtils.generarWhereLikeNormalizado(EMAIL_010, bean.getEmail(), params, startsWith));
            where.append(Y41eSqlUtils.generarWhereMayorIgual(FEC_RESPUESTA_010, bean.getFecRespuestaInicio(), params));
            where.append(Y41eSqlUtils.generarWhereMenorIgual(FEC_RESPUESTA_010, bean.getFecRespuestaFin(), params));
            //encuesta
            where.append(Y41eSqlUtils.generarWhereLikeNormalizado("DESC_PUBL_"+ locale.getLanguage().toUpperCase() +"_001", bean.getEncuesta().getDescPubl(), params, startsWith));
            where.append(Y41eSqlUtils.generarWhereLikeNormalizado("DESC_INT_"+ locale.getLanguage().toUpperCase() +"_001", bean.getEncuesta().getDescInt(), params, startsWith));
            where.append(Y41eSqlUtils.generarWhereMayorIgual(FEC_ENVIO_001, bean.getEncuesta().getFecEnvioInicio(), params));
            where.append(Y41eSqlUtils.generarWhereMenorIgual(FEC_ENVIO_001, bean.getEncuesta().getFecEnvioFin(), params));
            //area
            where.append(Y41eSqlUtils.generarWhereIgual("ID_AREA_001", bean.getEncuesta().getArea().getIdArea(), params));
            //origen
            where.append(Y41eSqlUtils.generarWhereIgual("ID_ORIGEN_001", bean.getEncuesta().getOrigen().getIdOrigen(), params));
        }
        return where.toString();
    }

    /**
     * Guarda los envíos
     * @param listaEnvios List<Y41eEnvio>
     */
    @Override
    public void guardarEnvios(List<Y41eEnvio> listaEnvios){
        StringBuilder insert = new StringBuilder(Y41eSqlUtils.INSERT)
                .append(TABLA).append(" (")
                .append(ID_ENVIO_010).append(",")
                .append(ID_ENCUESTA_010).append(",")
                .append(ID_USUARIO_010).append(",")
                .append(DATA_USUARIO_010).append(",")
                .append(EMAIL_010).append(",")
                .append(PARAM_010).append(",")
                .append(FEC_RESPUESTA_010).append(")")
                .append("VALUES (")
                .append(SECUENCIA)
                .append(".NEXTVAL,?,?,?,?,?,NULL)");

        final List<Object[]> paramsInsert = new ArrayList<Object[]>();
        List<Object> auxInsert = new ArrayList<Object>();
        for(Y41eEnvio envio:listaEnvios){
            auxInsert.clear();
            auxInsert.add(envio.getEncuesta().getIdEncuesta());
            auxInsert.add(envio.getIdUsuario());
            auxInsert.add(envio.getDataUsuario());
            auxInsert.add(envio.getEmail());
            auxInsert.add(envio.getParam());
            paramsInsert.add(auxInsert.toArray().clone());
        }
        this.getJdbcTemplate().batchUpdate(insert.toString(), paramsInsert);
    }


    @Override
    public Long addEnvioSondeo(Long idEncuesta){
        StringBuilder insert = new StringBuilder(Y41eSqlUtils.INSERT)
                .append(TABLA).append(" (")
                .append(ID_ENVIO_010).append(",")
                .append(ID_ENCUESTA_010).append(",")
                .append(ID_USUARIO_010).append(",")
                .append(FEC_RESPUESTA_010).append(")")
                .append(" VALUES (?,?,?,SYSDATE)");

        final Long elId = this.getNextVal(SECUENCIA);
        final List<Object> params = new ArrayList<Object>();
        params.add(elId);
        params.add(idEncuesta);
        params.add(Y41eConstants.ID_USUARIO_SONDEO);
        this.getJdbcTemplate().update(insert.toString(), params.toArray());
        return elId;
    }


    /**
     * Actualiza la fecha de respuesta
     * @param idEnvio Long
     */
    @Override
    public void actualizarFechaRespuesta(Long idEnvio){
        StringBuilder sql = new StringBuilder(Y41eSqlUtils.UPDATE)
                .append(TABLA).append(" SET ")
                .append(FEC_RESPUESTA_010).append("=SYSDATE")
                .append(Y41eSqlUtils.WHERE)
                .append(ID_ENVIO_010).append("=?");
        this.getJdbcTemplate().update(sql.toString(), idEnvio);
    }

    /* (non-Javadoc)
     * @see com.ejie.y41e.dao.Y41eGenericoDaoImpl#getOrderBy()
     */
    @Override
    protected String[] getOrderBy() {
        return Y41eEnviosDaoImpl.ORDER_BY_WHITE_LIST;
    }


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

}