package com.rjconsultores.ventaboletos.relatorios.impl;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.rjconsultores.ventaboletos.relatorios.utilitarios.DataSource;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.RelatorioW2IBean;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class RelatorioW2ITaxaEmbarqueAnalitico extends Relatorio {

	private List<RelatorioW2IBean> lsDadosRelatorio;
	public RelatorioW2ITaxaEmbarqueAnalitico(Map<String, Object> parametros, Connection conexao) throws Exception {
		super(parametros, conexao);

		this.setCustomDataSource(new DataSource(this) {
			@Override
			public void initDados() throws Exception {

				Connection conexao = this.relatorio.getConexao();
				Map<String, Object> parametros = this.relatorio.getParametros();
				String puntosVentaIds = (String) parametros.get("NUMPUNTOVENTA");
				List<Integer> puntosVentaIdsList = new ArrayList<>();
				boolean isTodasAgencias = false;
				for (String id : puntosVentaIds.split(",")) {
					if("-1".equals(id)) {
						isTodasAgencias = true; 
						break;
					}
						
					puntosVentaIdsList.add(Integer.parseInt(id));
				}
				lsDadosRelatorio = new ArrayList<RelatorioW2IBean>();
				Integer empresaID = (Integer)  parametros.get("EMPRESA_ID");
				Integer origemID =  (Integer)  parametros.get("ORIGEN_ID");
				Integer destinoID = (Integer)  parametros.get("DESTINO_ID");
				
				String sql = getSql(isTodasAgencias ? 0 : puntosVentaIdsList.size(), empresaID, origemID, destinoID);

				NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql);

				ResultSet rset = null;

				java.sql.Date dataInicial = new java.sql.Date(DateUtil.normalizarToFecha((Date) parametros.get("DATA_INICIAL")).getTime());
				java.sql.Date dataFinal   = new java.sql.Date(DateUtil.normalizarToFecha((Date) parametros.get("DATA_FINAL")).getTime());
				
				stmt.setDate("DATA_INICIAL", dataInicial);
	            stmt.setDate("DATA_FINAL", dataFinal);

	            if (empresaID != null)
	                stmt.setInt("EMPRESA_ID", empresaID);
	            if (origemID != null)
	                stmt.setInt("ORIGEN_ID", origemID);
	            if (destinoID != null)
	                stmt.setInt("ORIGEN_ID", destinoID);
	            
	            int paramIndex = 0;
	            if(!isTodasAgencias) {
		            for (Integer id : puntosVentaIdsList) {
		                stmt.setInt("PUNTO_VENTA_"+paramIndex, id);
		                paramIndex++;
		            }
	            }

	            rset = stmt.executeQuery();

				RelatorioW2IBean relatorioW2IBean = null;
				while (rset.next()) {
					relatorioW2IBean = new RelatorioW2IBean();
					relatorioW2IBean.setEmpresaId(rset.getInt("empresaId"));
					relatorioW2IBean.setEmpresa(rset.getString("empresa"));
					relatorioW2IBean.setPuntoVentaId(rset.getInt("puntoVentaId"));
					relatorioW2IBean.setAgencia(rset.getString("agencia"));
					relatorioW2IBean.setNumBilhete(rset.getLong("numBilhete"));
					relatorioW2IBean.setOrigem(rset.getString("origem"));
					relatorioW2IBean.setDestino(rset.getString("destino"));
					relatorioW2IBean.setDataVenda(rset.getDate("dataVenda"));
					relatorioW2IBean.setDataViaje(rset.getDate("dataViaje"));
					relatorioW2IBean.setPoltrona(rset.getString("poltrona"));
					relatorioW2IBean.setStatus(rset.getString("status"));
					relatorioW2IBean.setValorTaxa(rset.getBigDecimal("valorTaxa") == null ? BigDecimal.ZERO : rset.getBigDecimal("valorTaxa"));

					lsDadosRelatorio.add(relatorioW2IBean);
				}

				if (lsDadosRelatorio.size() > 0) {

					setLsDadosRelatorio(lsDadosRelatorio);
				}
			}

		});
	}

	public void setLsDadosRelatorio(List<RelatorioW2IBean> lsDadosRelatorio) {
		this.setCollectionDataSource(new JRBeanCollectionDataSource(lsDadosRelatorio));
		this.lsDadosRelatorio = lsDadosRelatorio;
	}

	@Override
	protected void processaParametros() throws Exception {
	}

	private String getSql(int numPuntosVentaIds, Integer empresaID, Integer origemID ,Integer destinoID) {
		StringBuilder sql = new StringBuilder();
		sql.append("SELECT DISTINCT ");
		sql.append("em.empresa_id AS empresaId, ");
		sql.append("em.nombempresa AS empresa, ");
		sql.append("pv.puntoventa_id AS puntoVentaId, ");
		sql.append("pv.nombpuntoventa As agencia, ");
		sql.append("b.numfoliosistema AS numBilhete, ");
		sql.append("po.descparada AS origem, ");
		sql.append("pd.descparada AS destino, ");
		sql.append("b.fechorviaje dataViaje, ");
		sql.append("b.fechorventa dataVenda, ");
		sql.append("b.numasiento AS poltrona, ");
		sql.append("sx.valortaxa AS valorTaxa, ");
		sql.append("'V' AS status ");
		sql.append("FROM taxpolv sx ");
		sql.append("INNER JOIN boleto b on b.boleto_id=sx.boleto_id ");
		sql.append("INNER JOIN punto_venta pv ON pv.PUNTOVENTA_ID = b.PUNTOVENTA_ID ");
		sql.append("INNER JOIN empresa em ON em.empresa_id=b.empresacorrida_id ");
		sql.append("INNER JOIN parada po ON po.parada_id=b.origen_id ");
		sql.append("INNER JOIN parada pd ON pd.parada_id=b.destino_id ");
		sql.append("INNER JOIN CIUDAD co ON co.ciudad_id=po.ciudad_id ");
		sql.append("INNER JOIN CIUDAD cd ON cd.ciudad_id=pd.ciudad_id ");
		sql.append("WHERE b.fechorventa BETWEEN :DATA_INICIAL AND :DATA_FINAL ");
		sql.append("AND sx.ACTIVO = 1 ");
		if(empresaID != null)
			sql.append("AND em.empresa_id = :EMPRESA_ID ");
		if(origemID != null)
			sql.append("AND po.parada_id = :ORIGEN_ID ");
		if(destinoID != null)
			sql.append("AND pd.parada_id = :DESTINO_ID  ");
		if(numPuntosVentaIds > 0)
			gerarBindPuntoVenta(numPuntosVentaIds, sql);

		sql.append(" UNION ");

		sql.append("SELECT DISTINCT ");
		sql.append("em.empresa_id AS empresaId, ");
		sql.append("em.nombempresa AS empresa, ");
		sql.append("pv.puntoventa_id AS puntoVentaId, ");
		sql.append("pv.nombpuntoventa As agencia, ");
		sql.append("b.numfoliosistema AS numBilhete, ");
		sql.append("po.descparada AS origem, ");
		sql.append("pd.descparada AS destino, ");
		sql.append("b.fechorviaje dataViaje, ");
		sql.append("b.fechorventa dataVenda, ");
		sql.append("b.numasiento AS poltrona, ");
		sql.append("(COALESCE(sx.valortaxa, 0) * -1) AS valorTaxa, ");
		sql.append("'C' AS status ");
		sql.append("FROM taxpolv sx ");
		sql.append("INNER JOIN boleto b on b.boleto_id=sx.boleto_id ");
		sql.append("INNER JOIN punto_venta pv ON pv.PUNTOVENTA_ID = b.PUNTOVENTA_ID ");
		sql.append("INNER JOIN empresa em ON em.empresa_id=b.empresacorrida_id ");
		sql.append("INNER JOIN parada po ON po.parada_id=b.origen_id ");
		sql.append("INNER JOIN parada pd ON pd.parada_id=b.destino_id ");
		sql.append("INNER JOIN CIUDAD co ON co.ciudad_id=po.ciudad_id ");
		sql.append("INNER JOIN CIUDAD cd ON cd.ciudad_id=pd.ciudad_id ");
		sql.append("WHERE b.fechorventa BETWEEN :DATA_INICIAL AND :DATA_FINAL ");
		sql.append("AND sx.indcancelado = 1 ");
		if(empresaID != null)
			sql.append("AND em.empresa_id = :EMPRESA_ID ");
		if(origemID != null)
			sql.append("AND po.parada_id = :ORIGEN_ID ");
		if(destinoID != null)
			sql.append("AND pd.parada_id = :DESTINO_ID  ");

		if(numPuntosVentaIds > 0)
			gerarBindPuntoVenta(numPuntosVentaIds, sql);

		sql.append("ORDER BY dataVenda ASC ");

		return sql.toString();
	}

	private void gerarBindPuntoVenta(int numPuntosVentaIds, StringBuilder sql) {
		if (numPuntosVentaIds > 0) {
	        sql.append("AND b.puntoventa_id IN (");
	        int i;
	        for (i = 0; i < numPuntosVentaIds; i++) {
	            if (i > 0) {
	                sql.append(", ");
	            }
	            	sql.append(":PUNTO_VENTA_"+i);
	        }
	        sql.append(") ");
	    }
	};

}
