package com.rjconsultores.ventaboletos.relatorios.impl;

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

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

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

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

public class RelatorioVendasConexaoRuta extends Relatorio {
	
	private static Logger log = LogManager.getLogger(RelatorioVendasConexaoRuta.class);

	private List<RelatorioVendasConexaoRutaBean> lsDadosRelatorio;
	
	private Timestamp fecInicio;
	private Timestamp fecFinal;

	private static final String FILTRO_POR_TODOS = "-1";
	
	public RelatorioVendasConexaoRuta(Map<String, Object> parametros, Connection conexao) throws Exception {
		super(parametros, conexao);
		
		this.setCustomDataSource(new DataSource(this) {

			@Override
			public void initDados() throws Exception {
				Map<String, Object> parametros = this.relatorio.getParametros();
				fecInicio = new Timestamp(DateUtil.inicioFecha((Date) parametros.get("DATA_INICIAL")).getTime());
				fecFinal = new Timestamp(DateUtil.fimFecha((Date) parametros.get("DATA_FINAL")).getTime());
				
				Connection conexao = this.relatorio.getConexao();
				processarVendasConexao(conexao, parametros);
				
				setCollectionDataSource(new JRBeanCollectionDataSource(lsDadosRelatorio));
			}

		});
	}
	
	private void processarVendasConexao(Connection conexao, Map<String, Object> parametros) {
		ResultSet rset = null;
		NamedParameterStatement stmt = null;
		
		try {
			
			stmt = carregarNamedParameterStatement(conexao, parametros);
			rset = stmt.executeQuery();
			processarResultado(rset);				
			fecharConexaoBanco(conexao, stmt, rset);

		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		
	}
	
	private void fecharConexaoBanco(Connection conexao, NamedParameterStatement stmt, ResultSet rset) {
		try {
			if(rset != null && !rset.isClosed()) {
				rset.close();
			}
			if(stmt != null && !stmt.isClosed()) {
				stmt.close();
			}
			if(conexao != null && !conexao.isClosed()) {
				conexao.close();
			}
		} catch (SQLException e) {
			log.error(e.getMessage(), e);
		}
	}

	private void processarResultado(ResultSet rset) throws SQLException {
		if(lsDadosRelatorio == null) {
			lsDadosRelatorio = new ArrayList<RelatorioVendasConexaoRutaBean>();
		}
		
		BigDecimal total = BigDecimal.ZERO;
		while (rset.next()) {
			
			
			RelatorioVendasConexaoRutaBean bean = new RelatorioVendasConexaoRutaBean();
			
			bean.setNumBpe((Integer) rset.getInt("numBPE"));
			bean.setPreco((BigDecimal) rset.getObject("preco"));
			bean.setTaxaEmbarque((BigDecimal) rset.getObject("taxaEmbarque"));
			bean.setPedagio((BigDecimal) rset.getBigDecimal("pedagio"));
			bean.setSeguro((BigDecimal) rset.getBigDecimal("seguro"));
			bean.setBilhete((String) rset.getObject("bilhete"));
			bean.setNumeroAgencia((Integer) rset.getInt("numeroAgencia"));
			bean.setNomeAgencia((String) rset.getString("nomeAgencia"));
			bean.setServico((Integer) rset.getInt("servico"));
			bean.setPoltrona((String) rset.getObject("poltrona"));
			bean.setNumLinha((String) rset.getString("numLinha"));
			bean.setDescricaoLinha((String) rset.getObject("descricaoLinha"));
			bean.setCodOrigem((String) rset.getString("codOrigem"));
			bean.setDescricaoOrigem((String) rset.getObject("descricaoOrigem"));
			bean.setCodDestino((String) rset.getString("codDestino"));
			bean.setDescricaoDestino((String) rset.getObject("descricaoDestino"));
			bean.setDataEmbarque((Date) rset.getObject("dataEmbarque"));
			bean.setDataVenda((Date) rset.getObject("dataVenda"));
			bean.setCveusuario((String) rset.getObject("cveusuario")); 
			bean.setNumoperacion((String) rset.getObject("numoperacion"));
			bean.setClasseServico((String) rset.getObject("classeServico"));
			bean.setSubSerie((String) rset.getObject("subSerie"));
			bean.setDescricaoConexao((String) rset.getObject("descricaoConexao"));
			bean.setIdCadastroConexao((Integer) rset.getInt("IdCadastroConexao"));
			bean.setDescuento((String) rset.getObject("descuento"));
			total = total.add(bean.getPreco() != null ? bean.getPreco() : BigDecimal.ZERO);	
			total = total.add(bean.getTaxaEmbarque() != null ? bean.getTaxaEmbarque() : BigDecimal.ZERO);	
			total = total.add(bean.getPedagio() != null ? bean.getPedagio() : BigDecimal.ZERO);
			total = total.add(bean.getSeguro() != null ? bean.getSeguro() : BigDecimal.ZERO);
			lsDadosRelatorio.add(bean);
		}
		
		if (lsDadosRelatorio.size() > 0) {

			parametros.put("TOTAL", total);
		}
		
	}
	
	private NamedParameterStatement carregarNamedParameterStatement(Connection conexao, Map<String, Object> parametros) throws SQLException {
		String sql = getSql(parametros);
		log.info(sql);
		
		NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql);
		
		if(fecInicio != null) {
			stmt.setTimestamp("fecInicio", fecInicio);
		}
		if(fecFinal != null) {
			stmt.setTimestamp("fecFinal", fecFinal);
		}

		return stmt;
	}

	protected String getSql(Map<String, Object> parametros) {


		StringBuilder sb = new StringBuilder();

		sb.append("SELECT c.numfoliosistema as bilhete,");
		sb.append("       b.num_bpe as numBpe,");
		sb.append("       origen.cveparada as codOrigem,");
		sb.append("       origen.descparada as descricaoOrigem,");
		sb.append("       destino.descparada as descricaoDestino ,");
		sb.append("       destino.cveparada as codDestino,");
		sb.append("       r.numruta as numLinha, ");
		sb.append("       r.descruta as descricaoLinha, ");
		sb.append("       c.corrida_id as servico,");
		sb.append("       cs.descclase as classeServico,");
		sb.append("       c.fechorviaje as dataEmbarque,");
		sb.append("       c.fechorventa dataVenda,");
		sb.append("       c.numasiento as poltrona,");
		sb.append("       c.preciopagado AS preco,");
		sb.append("       c.importetaxaembarque as taxaEmbarque,");
		sb.append("       c.importeseguro as seguro,");
		sb.append("       c.importepedagio as pedagio,");
		sb.append("       pv.numpuntoventa as numeroAgencia, ");
		sb.append("       pv.nombpuntoventa as nomeAgencia, ");
		sb.append("       u.cveusuario as cveusuario, ");
		sb.append("       c.numoperacion as numoperacion, ");
		sb.append("       'BPe' as subSerie, ");
		sb.append("       conf.descricao descricaoConexao, ");
		sb.append("       conf.conexionrutaconf_id IdCadastroConexao, ");
		sb.append("       CONV.descconvenio as descuento ");
		sb.append("FROM caja c ");
		sb.append("JOIN boleto b on (c.transacao_id = b.boleto_id) ");
		sb.append("JOIN marca m ON c.marca_id = m.marca_id ");
		sb.append("JOIN empresa e ON e.empresa_id = m.empresa_id ");
		sb.append("JOIN punto_venta pv ON pv.puntoventa_id = c.puntoventa_id ");
		sb.append("JOIN parada origen ON (origen.parada_id = c.origen_id) ");
		sb.append("JOIN parada destino ON (destino.parada_id = c.destino_id) ");
		sb.append("JOIN ruta r ON (r.ruta_id = c.ruta_id) ");
		sb.append("JOIN clase_servicio cs ON (c.claseservicio_id = cs.claseservicio_id) ");
		sb.append("INNER JOIN vigencia_tarifa vt ON c.fechorventa BETWEEN vt.feciniciovigencia AND vt.fecfinvigencia ");
		sb.append("AND vt.activo = 1 ");	
		sb.append("INNER JOIN usuario u ON (c.usuario_id = u.usuario_id) ");
		sb.append("left join conexion cc on cc.conexionctrl_id = c.conexionctrl_id  ");
		sb.append("join conexion_ruta_tramo_ctrl ctr on ctr.conexionrutatramoctrl_id = cc.conexionrutatramoctrl_id  ");
		sb.append("join conexion_ruta_ctrl ctrl on ctrl.conexionrutactrl_id = ctr.conexionrutactrl_id ");
		sb.append("join conexion_ruta_conf conf on conf.conexionrutaconf_id = ctrl.conexionrutaconf_id  ");
		sb.append("left JOIN CONVENIO_DET CONV_D ON CONV_D.CONVENIODET_ID = c.CONVENIODET_ID  ");
		sb.append(" left join  CONVENIO CONV ON CONV.CONVENIO_ID = CONV_D.CONVENIO_ID  ");
		sb.append("WHERE c.indconexion = 1");
		sb.append("  AND c.indreimpresion = 0");
		sb.append("  AND c.tipoventa_id <> 6");
		sb.append("   AND (c.indstatusboleto = 'V' or c.indstatusboleto = 'T' ) and c.motivocancelacion_id is null ");
		sb.append("  AND c.numoperacion in");
		sb.append("    (SELECT c.numoperacion");
		sb.append("     FROM caja c");
		sb.append("     JOIN marca m ON c.marca_id = m.marca_id");
		sb.append("     JOIN empresa e ON e.empresa_id = m.empresa_id");
		sb.append("     JOIN punto_venta pv ON pv.puntoventa_id = c.puntoventa_id");
		sb.append("     WHERE c.indconexion = 1");
		sb.append("       AND c.indreimpresion = 0 and  (c.indstatusboleto = 'V' or c.indstatusboleto = 'T' ) and c.motivocancelacion_id is null ");
		sb.append("       AND c.tipoventa_id <> 6 ");
		
		if(fecInicio != null) {
			sb.append("AND COALESCE(C.FECHORVENTA_H,C.FECHORVENTA) >= :fecInicio ");
		}
		if(fecFinal != null) {
			sb.append("AND COALESCE(C.FECHORVENTA_H,C.FECHORVENTA) <= :fecFinal ");
		}
		if ((String)parametros.get("EMPRESA_ID") != null && !filtrarTodos("EMPRESA_ID")) {
			sb.append(" AND e.empresa_id IN ("+parametros.get("EMPRESA_ID")+")");
		}
		if ((String)parametros.get("PUNTOVENTA_ID") != null  && !filtrarTodos("PUNTOVENTA_ID")) {
			sb.append(" AND b.puntoventa_id IN ("+parametros.get("PUNTOVENTA_ID")+")");
		}
		
		sb.append(") ");
		sb.append("     group by ");
		sb.append("     c.numfoliosistema ,");
		sb.append("       b.num_bpe ,");
		sb.append("       origen.cveparada ,");
		sb.append("       origen.descparada,");
		sb.append("       destino.descparada ,");
		sb.append("       destino.cveparada ,");
		sb.append("       r.numruta  ,");
		sb.append("       r.descruta  ,");
		sb.append("       c.corrida_id ,");
		sb.append("       cs.descclase ,");
		sb.append("       c.fechorviaje,  ");
		sb.append("       c.fechorventa , ");
		sb.append("       c.numasiento , ");
		sb.append("       c.preciopagado ,");
		sb.append("       c.importetaxaembarque ,");
		sb.append("       c.importeseguro, ");
		sb.append("       c.importepedagio ,");
		sb.append("       pv.numpuntoventa ,");
		sb.append("       pv.nombpuntoventa ,");
		sb.append("       u.cveusuario ,");
		sb.append("       c.numoperacion ,");
		sb.append("       conf.descricao ,");
		sb.append("       conf.conexionrutaconf_id, CONV.descconvenio ");
		sb.append("       order by c.fechorventa, c.numoperacion ");

		
				
		return sb.toString();
		
	}
	
	private boolean filtrarTodos(String parametro) {
		String ids = (String)parametros.get(parametro);
		for (int i = 0; i < ids.split(", ").length; i++) {
			if (FILTRO_POR_TODOS.equals(ids.split(", ")[i])) {
				return true;
			}
		}
		return false;
	}
	
	@Override
	protected void processaParametros() throws Exception {
	}
	
	public List<RelatorioVendasConexaoRutaBean> getLsDadosRelatorio() {
		return lsDadosRelatorio;
	}
	
	@Override
	public String getNome() {
		return super.getNome();
	}

}
