package com.rjconsultores.ventaboletos.relatorios.impl;

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

import org.apache.commons.lang.math.NumberUtils;
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.RelatorioAgenciaFechamentoBean;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

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

public class RelatorioAgenciaFechamentoNovo extends Relatorio {

	private static Logger log = LogManager.getLogger(RelatorioAgenciaFechamentoNovo.class);
	
	private List<RelatorioAgenciaFechamentoBean> lsDadosRelatorio;

	public RelatorioAgenciaFechamentoNovo(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 fecInicio = parametros.get("fecInicio").toString() + " 00:00:00";
				String fecFinal = parametros.get("fecFinal").toString() + " 23:59:59";
				String empresa = parametros.get("empresa") != null ? parametros.get("empresa").toString() : "";
				String empresaNome = parametros.get("empresaNome") != null ? parametros.get("empresaNome").toString() : "";
				String puntoVenta = parametros.get("NUMPUNTOVENTA") != null ? parametros.get("NUMPUNTOVENTA").toString() : null;
				
				lsDadosRelatorio = new ArrayList<RelatorioAgenciaFechamentoBean>();

				String sql = carregarDadosTotaisdeVenda(puntoVenta, empresa);

				NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql);
				ResultSet rset1 = null;
				ResultSet rset2 = null;
				SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");

				if (parametros.get("MOEDA_ID") != null)
					stmt.setInt("MOEDA_ID", (Integer) parametros.get("MOEDA_ID"));
				else
					stmt.setNull("MOEDA_ID", java.sql.Types.INTEGER);
				
				stmt.setTimestamp("de", new java.sql.Timestamp(sdf.parse(fecInicio).getTime()));
				stmt.setTimestamp("ate", new java.sql.Timestamp(sdf.parse(fecFinal).getTime()));				

				rset1= stmt.executeQuery();

				while (rset1.next()) {
					
					Integer qtdExcesso = NumberUtils.INTEGER_ZERO; 
					Integer qtdSeguro = NumberUtils.INTEGER_ZERO;
					
					BigDecimal valorExcesso = BigDecimal.ZERO;
					BigDecimal valorSeguro  = BigDecimal.ZERO;
					BigDecimal difMaior     = BigDecimal.ZERO;	
					BigDecimal total        = BigDecimal.ZERO;
					
					
					RelatorioAgenciaFechamentoBean agenciaFechamento = new RelatorioAgenciaFechamentoBean();

					agenciaFechamento.setEmpresa(empresaNome);
					String puntoVentaId = rset1.getString("codigo");
					agenciaFechamento.setDescricao(rset1.getString("descricao"));
					
					agenciaFechamento.setValorBilhete(rset1.getBigDecimal("valorBilhete"));
					agenciaFechamento.setValorVch(rset1.getBigDecimal("valorVch"));
					agenciaFechamento.setValorInternet(rset1.getBigDecimal("valorInternet"));
					agenciaFechamento.setValorCancelado(rset1.getBigDecimal("valorCancelado"));
					agenciaFechamento.setValorEstornado(rset1.getBigDecimal("valorEstornado"));
					valorSeguro = rset1.getBigDecimal("valorSeguro");
					
					agenciaFechamento.setQtdBilhete(rset1.getInt("qtdBilhete"));
					agenciaFechamento.setQtdVch(rset1.getInt("qtdVch"));
					agenciaFechamento.setQtdInternet(rset1.getInt("qtdInternet"));
					agenciaFechamento.setQtdCancelado(rset1.getInt("qtdCancelado"));
					agenciaFechamento.setQtdEstornado(rset1.getInt("qtdEstornado"));
					qtdSeguro = rset1.getInt("qtdSeguro");
					
					String strQueryEventoExtra = carregarEventosExtras(puntoVentaId, empresa);
					stmt = new NamedParameterStatement(conexao, strQueryEventoExtra);

					stmt.setTimestamp("de", new java.sql.Timestamp(sdf.parse(fecInicio).getTime()));
					stmt.setTimestamp("ate", new java.sql.Timestamp(sdf.parse(fecFinal).getTime()));

					rset2 = stmt.executeQuery();
					
					if (rset2.next()) {

						qtdSeguro += rset2.getInt("qtdSeguro");
						qtdExcesso = rset2.getInt("qtdExcesso");
						
						valorSeguro  = valorSeguro.add(rset2.getBigDecimal("valorSeguro"));
						valorExcesso = valorExcesso.add(rset2.getBigDecimal("valorExcesso"));			
						difMaior     = difMaior.add(rset2.getBigDecimal("difMaior"));	
						
					}
					
					agenciaFechamento.setQtdExcesso(qtdExcesso);
					agenciaFechamento.setQtdSeguro(qtdSeguro);
					agenciaFechamento.setValorExcesso(valorExcesso);
					agenciaFechamento.setValorSeguro(valorSeguro);
					
					agenciaFechamento.setDifMaior(difMaior);
					total = total.add(rset1.getBigDecimal("valorBilhete")); 
					total = total.add(rset1.getBigDecimal("valorVch")); 
					total = total.add(rset1.getBigDecimal("valorInternet"));
					
					
					total = total.add(difMaior);
					total = total.subtract(rset1.getBigDecimal("valorCancelado")); 
					total = total.subtract(rset1.getBigDecimal("valorEstornado")); 
					total = total.subtract(rset1.getBigDecimal("valorOCD"));
					
					
					agenciaFechamento.setTotal(total);
					
					
					
					
					agenciaFechamento.setValorOCD(rset1.getBigDecimal("valorOCD"));
					
					

					lsDadosRelatorio.add(agenciaFechamento);
					//Estava dando um erro de "maximo de cursores abertos excedido"
					//Colocado isso o erro parou de ocorrer
					rset2.getStatement().close();
					rset2.close();
				}
				
				rset1.close();

				if (!lsDadosRelatorio.isEmpty()) {
					setLsDadosRelatorio(lsDadosRelatorio);
				}

			}
		});
	}

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

	@Override
	protected void processaParametros() throws Exception {
	}

	private String carregarDadosTotaisdeVenda(String puntoVenta, String empresa) {

		StringBuilder sql = new StringBuilder();
		
		sql.append(" SELECT CODIGO, "); 
		sql.append("        DESCRICAO, "); 
		sql.append("        SUM(VALORBILHETE) AS VALORBILHETE, "); 
		sql.append("        SUM(QTDBILHETE) AS QTDBILHETE, "); 
		sql.append("        SUM(VALORSEGURO) AS VALORSEGURO, "); 
		sql.append("        SUM(QTDSEGURO) AS QTDSEGURO, "); 
		sql.append("		SUM(VALORVCH) AS VALORVCH, "); 
		sql.append("		SUM(QTDVCH) AS QTDVCH, "); 
		sql.append("		SUM(VALORINTERNET) AS VALORINTERNET, "); 
		sql.append("		SUM(QTDINTERNET) AS QTDINTERNET, ");
		sql.append("		SUM(VALORCANCELADO) AS VALORCANCELADO, "); 
		sql.append("		SUM(QTDCANCELADO) AS QTDCANCELADO, "); 
		sql.append("		SUM(VALORESTORNADO) AS VALORESTORNADO, "); 
		sql.append("		SUM(QTDESTORNADO) AS QTDESTORNADO, "); 
		sql.append("		SUM(VALOROCD) AS VALOROCD "); 		
		sql.append(" FROM ( ");
		sql.append(" SELECT pv.PUNTOVENTA_ID AS codigo, ");
		sql.append("   pv.nombpuntoventa AS descricao, ");
		sql.append("   COALESCE(SUM( ");
		sql.append("   CASE ");
		sql.append("     WHEN c.MOTIVOCANCELACION_ID IS NULL ");
		sql.append("     AND (c.INDREMOTOINVERSO     IS NULL ");
		sql.append("     OR c.INDREMOTOINVERSO        =0) ");
		sql.append("     AND (c.INDSTATUSBOLETO <> 'E' AND c.TIPOVENTA_ID not in (5,12,18)) ");
		sql.append("     THEN ( COALESCE(c.IMPORTEOUTROS,0) + COALESCE(c.IMPORTEPEDAGIO,0) +COALESCE(c.IMPORTETAXAEMBARQUE ,0)+COALESCE(c.preciopagado,0)) ");
		sql.append("     ELSE null ");
		sql.append("   END),0) AS valorBilhete, ");
		sql.append("   COALESCE(COUNT( ");
		sql.append("   CASE ");
		sql.append("     WHEN c.MOTIVOCANCELACION_ID IS NULL ");
		sql.append("     AND (c.INDREMOTOINVERSO     IS NULL ");
		sql.append("     OR c.INDREMOTOINVERSO        =0) ");
		sql.append("     AND (c.INDSTATUSBOLETO <> 'E' AND c.TIPOVENTA_ID not in (5,12,18)) ");
		sql.append("     THEN c.caja_id ");
		sql.append("     ELSE NULL ");
		sql.append("   END),0) AS qtdBilhete, ");
		sql.append("   SUM( ");
		sql.append("   CASE ");
		sql.append("     WHEN c.MOTIVOCANCELACION_ID IS NULL ");
		sql.append("     AND COALESCE(c.IMPORTESEGURO,0) > 0 ");
		sql.append("     THEN c.IMPORTESEGURO ");
		sql.append("     ELSE 0 ");
		sql.append("   END) AS valorSeguro, ");
		sql.append("   COALESCE(COUNT( ");
		sql.append("   CASE ");
		sql.append("     WHEN c.MOTIVOCANCELACION_ID IS NULL ");
		sql.append("     AND COALESCE(c.IMPORTESEGURO,0) > 0 ");
		sql.append("     THEN 1 ");
		sql.append("     ELSE NULL ");
		sql.append("   END),0) AS qtdSeguro, ");
		sql.append("   COALESCE(SUM( ");
		sql.append("   CASE ");
		sql.append("     WHEN c.MOTIVOCANCELACION_ID IS NULL ");
		sql.append("     AND (c.INDSTATUSBOLETO = 'E' OR c.TIPOVENTA_ID in (5,18)) ");
		sql.append("     THEN ( COALESCE(c.IMPORTEOUTROS,0) + COALESCE(c.IMPORTEPEDAGIO,0) +COALESCE(c.IMPORTETAXAEMBARQUE ,0)+COALESCE(c.preciopagado,0)) ");
		sql.append("     ELSE 0 ");
		sql.append("   END),0) AS valorVch, ");
		sql.append("   COALESCE(COUNT( ");
		sql.append("   CASE ");
		sql.append("     WHEN c.MOTIVOCANCELACION_ID IS NULL ");
		sql.append("     AND (c.INDSTATUSBOLETO = 'E' OR c.TIPOVENTA_ID in (5,18)) ");
		sql.append("     THEN 1 ");
		sql.append("     ELSE NULL ");
		sql.append("   END),0) AS qtdVch, ");
		sql.append("   COALESCE(SUM( ");
		sql.append("   CASE ");
		sql.append("     WHEN c.MOTIVOCANCELACION_ID IS NULL ");
		sql.append("     AND c.TIPOVENTA_ID = 12 ");
		sql.append("     THEN ( COALESCE(c.IMPORTEOUTROS,0) + COALESCE(c.IMPORTEPEDAGIO,0) +COALESCE(c.IMPORTETAXAEMBARQUE ,0)+COALESCE(c.preciopagado,0)) ");
		sql.append("     ELSE 0 ");
		sql.append("   END),0) AS valorInternet, ");
		sql.append("   COALESCE(COUNT( ");
		sql.append("   CASE ");
		sql.append("     WHEN c.MOTIVOCANCELACION_ID IS NULL ");
		sql.append("     AND c.TIPOVENTA_ID = 12 ");
		sql.append("     THEN 1 ");
		sql.append("     ELSE NULL ");
		sql.append("   END),0) AS qtdInternet, ");
		sql.append("   COALESCE(SUM( ");
		sql.append("   CASE ");
		sql.append("     WHEN (c.MOTIVOCANCELACION_ID IN (31))");
		sql.append("     THEN ( COALESCE(c.IMPORTEOUTROS,0) + COALESCE(c.IMPORTEPEDAGIO,0) +COALESCE(c.IMPORTETAXAEMBARQUE ,0)+COALESCE(c.preciopagado,0)) ");
		sql.append("     ELSE 0 ");
		sql.append("   END),0) AS valorCancelado, ");
		sql.append("   COALESCE(COUNT( ");
		sql.append("   CASE ");
		sql.append("     WHEN (c.MOTIVOCANCELACION_ID IN (31))");
		sql.append("     THEN 1 ");
		sql.append("     ELSE NULL ");
		sql.append("   END),0) AS qtdCancelado, ");
		sql.append("   COALESCE(SUM( ");
		sql.append("   CASE ");
		sql.append("     WHEN c.MOTIVOCANCELACION_ID IS NOT NULL ");
		sql.append("     AND c.MOTIVOCANCELACION_ID  <> 31 ");
		sql.append("     THEN ( COALESCE(c.IMPORTEOUTROS,0) + COALESCE(c.IMPORTEPEDAGIO,0) +COALESCE(c.IMPORTETAXAEMBARQUE ,0)+COALESCE(c.preciopagado,0)) ");
		sql.append("     ELSE 0 ");
		sql.append("   END),0) AS valorEstornado, ");
		sql.append("   COALESCE(COUNT( ");
		sql.append("   CASE ");
		sql.append("     WHEN c.MOTIVOCANCELACION_ID IS NOT NULL ");
		sql.append("     AND c.MOTIVOCANCELACION_ID  <> 31 ");
		sql.append("     THEN 1 ");
		sql.append("     ELSE NULL ");
		sql.append("   END),0) AS qtdEstornado, ");
		sql.append("   CASE ");
		sql.append("     WHEN (nvl(o.boleto_id,0) <> 0) THEN ");
		sql.append("     SUM(nvl(b.preciopagado, 0) + nvl(b.importetaxaembarque, 0) + nvl(b.importeoutros, 0) + nvl(b.importepedagio, 0) + nvl(b.importeseguro, 0)) ELSE 0 ");
		sql.append("   END AS VALOROCD ");
		sql.append(" FROM CAJA c ");
		sql.append(" INNER JOIN PUNTO_VENTA pv ");
		sql.append(" ON c.PUNTOVENTA_ID = pv.PUNTOVENTA_ID ");
		sql.append(" INNER JOIN marca m ");
		sql.append(" ON m.marca_id     = c.marca_id ");
		sql.append(" INNER JOIN EMPRESA e  ");
		sql.append(" ON e.EMPRESA_ID = m.EMPRESA_ID ");
		sql.append(" INNER JOIN BOLETO b ON b.BOLETO_ID = c.TRANSACAO_ID  ");
		sql.append(" LEFT JOIN OCD o ");
		sql.append(" ON c.TRANSACAOANTERIOR_ID = o.BOLETO_ID AND O.INDPAGO = 1");
		sql.append(" WHERE c.TURNO_ID IS NOT NULL ");
		sql.append(" AND c.FECCORTE BETWEEN :de AND :ate ");
		if (puntoVenta != null && !puntoVenta.equals("-1")) {
			sql.append("        AND c.PUNTOVENTA_ID in (" + puntoVenta + ") ");
		}
		sql.append(" AND c.TIPOVENTA_ID  <> 6 ");
		sql.append(" AND c.INDREIMPRESION = 0 ");
		if (empresa != null && !empresa.equals("")  && !empresa.equals("-1")) {
			sql.append(" AND m.empresa_id     = "+empresa+" ");
		}
		
		sql.append(" AND C.ACTIVO = 1 ");
		sql.append(" AND NVL(C.MONEDA_ID, 1) = :MOEDA_ID ");
		sql.append(" GROUP BY pv.PUNTOVENTA_ID, pv.nombpuntoventa, o.boleto_id  ");
		sql.append(" ORDER BY pv.nombpuntoventa ");
		sql.append(") GROUP BY codigo, descricao ");
		sql.append("  ORDER BY descricao "); 
		
		return sql.toString();

	}
	
	private String carregarEventosExtras(String puntoVenta, String empresa) {

		StringBuilder sql = new StringBuilder();
		sql.append(" SELECT ");
		sql.append("     COALESCE(SUM(CASE WHEN tee.CVETIPOEVENTO = 'DIF_MAIOR' THEN cd.PRECIO ELSE NULL END),0) AS difmaior,  ");
		sql.append("     COALESCE(SUM(CASE WHEN tee.CVETIPOEVENTO = 'EXCESSO_BAGAGEM' THEN cd.PRECIO ELSE NULL END),0) AS valorExcesso,  ");
		sql.append(" 	 COALESCE(COUNT(CASE WHEN tee.CVETIPOEVENTO = 'EXCESSO_BAGAGEM' THEN 1 ELSE NULL END),0) as qtdExcesso,    ");
		sql.append("     COALESCE(SUM(CASE WHEN tee.CVETIPOEVENTO = 'SEGURO_OPCIONAL' THEN cd.PRECIO ELSE NULL END),0) AS valorSeguro,  ");
		sql.append("     COALESCE(COUNT(CASE WHEN tee.CVETIPOEVENTO = 'SEGURO_OPCIONAL' THEN 1 ELSE NULL END),0) as qtdSeguro  ");
		sql.append(" FROM CAJA_DIVERSOS cd ");
		sql.append(" INNER JOIN	EVENTO_EXTRA ee ");
		sql.append("     ON ee.EVENTOEXTRA_ID = cd.EVENTOEXTRA_ID ");
		sql.append(" INNER JOIN TIPO_EVENTO_EXTRA tee ");
		sql.append("     ON ee.TIPOEVENTOEXTRA_ID = tee.TIPOEVENTOEXTRA_ID ");
		sql.append(" WHERE cd.MOTIVOCANCELACION_ID IS NULL ");
		sql.append("   	 AND ee.activo = 1 ");
		sql.append("   	 AND cd.TURNO_ID IS NOT NULL ");
		sql.append("   	 AND tee.CVETIPOEVENTO in ('EXCESSO_BAGAGEM', 'SEGURO_OPCIONAL', 'DIF_MAIOR') ");
		sql.append("     AND cd.FECCORTE BETWEEN :de AND :ate ");
		if (puntoVenta != null && !puntoVenta.equals("-1")) {
			sql.append("     AND cd.PUNTOVENTA_ID = ").append(puntoVenta);
		}
		if (empresa != null && !empresa.equals("")  && !empresa.equals("-1")) {
			sql.append("     AND ee.EMPRESA_ID = "+empresa+" ");
		}
		
		
		log.debug(sql.toString());

		return sql.toString();

	}

}
