/**
 * 
 */
package com.rjconsultores.ventaboletos.relatorios.impl;

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

import com.rjconsultores.ventaboletos.relatorios.negocio.CalculoImposto;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.DataSource;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.ExceptionConfiguracao;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.RelatorioTaxasLinhaBean;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.utilerias.MoneyHelper;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
 
/**
 * @author Bruno H. G. Gouvea <bruno@rjconsultores.com.br>
 * 
 */
public class RelatorioTaxasLinha extends Relatorio {

	private List<RelatorioTaxasLinhaBean> lsDadosRelatorio;
	
	/**
	 * @param parametros
	 * @param conexao
	 * @throws Exception
	 */
	public RelatorioTaxasLinha(Map<String, Object> parametros, Connection conexao) throws Exception {
		super(parametros, conexao);
		CalculoImposto.limpaCache();

		this.setCustomDataSource(false, 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");
				Boolean isSubNoShow = (Boolean) parametros.get("B_SUBTRAIR_NO_SHOW");
				
				Boolean isTxEmbarque = (Boolean) parametros.get("IS_TX_EMBARQUE");
				Boolean isPedagio = (Boolean) parametros.get("IS_PEDAGIO");
				Boolean isSeguro = (Boolean) parametros.get("IS_SEGURO");
				Boolean isSeguroW2I = (Boolean) parametros.get("IS_SEGUROOPCIONAL");
				
				lsDadosRelatorio = new ArrayList<RelatorioTaxasLinhaBean>();

				String sql = getSql(puntosVentaIds, isSubNoShow);
				
				NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql);

				ResultSet rset1 = null;

				stmt.setInt("TIPO_DATA", (Integer) parametros.get("TIPO_DATA"));
				stmt.setTimestamp("DATA_INICIAL", new Timestamp(DateUtil.inicioFecha((Date) parametros.get("DATA_INICIAL")).getTime()));
				stmt.setTimestamp("DATA_FINAL", new Timestamp(DateUtil.fimFecha((Date) parametros.get("DATA_FINAL")).getTime()));

				if (parametros.get("EMPRESA_ID") != null)
					stmt.setInt("EMPRESA_ID", (Integer) parametros.get("EMPRESA_ID"));
				else
					stmt.setNull("EMPRESA_ID", java.sql.Types.INTEGER);

				if (parametros.get("ORIGEN_ID") != null && parametros.get("ORIGEN_ID") != "" && ((Integer) parametros.get("ORIGEN_ID") != -1))
					stmt.setInt("ORIGEN_ID", (Integer) parametros.get("ORIGEN_ID"));
				else
					stmt.setNull("ORIGEN_ID", java.sql.Types.INTEGER);

				if (parametros.get("DESTINO_ID") != null && parametros.get("DESTINO_ID") != "" && ((Integer) parametros.get("DESTINO_ID") != -1))
					stmt.setInt("DESTINO_ID", (Integer) parametros.get("DESTINO_ID"));
				else
					stmt.setNull("DESTINO_ID", java.sql.Types.INTEGER);

				rset1 = stmt.executeQuery();

				
				while (rset1.next()) {
					Boolean isValidado = false;
					BigDecimal valorIcms;
					// Se não for pra subtrair o ICMS, realiza o calculo e adiciona o mesmo
						if(!(Boolean) parametros.get("B_SUBTRAIR_ICMS")){
							 valorIcms = BigDecimal.ZERO;
						}else{
							valorIcms = rset1.getBigDecimal("ICMS") == null ? BigDecimal.ZERO : rset1.getBigDecimal("ICMS");
						}
						String indInterestadual = rset1.getString("INTERESTADUAL");
						Integer idEstado = rset1.getInt("ORIGEM_ESTADO_ID");
						Integer empresaId = rset1.getInt("EMPRESA_ID");
						
						BigDecimal importeTaxaEmbarque = rset1.getBigDecimal("IMPORTETAXAEMBARQUE") == null ? BigDecimal.ZERO : rset1.getBigDecimal("IMPORTETAXAEMBARQUE");
						BigDecimal importePedagio = rset1.getBigDecimal("IMPORTEPEDAGIO") == null ? BigDecimal.ZERO : rset1.getBigDecimal("IMPORTEPEDAGIO");
						BigDecimal importeSeguro = rset1.getBigDecimal("IMPORTESEGURO") == null ? BigDecimal.ZERO : rset1.getBigDecimal("IMPORTESEGURO");

						BigDecimal totalEmbarque = rset1.getBigDecimal("TOTAL_EMBARQUE") == null ? BigDecimal.ZERO : rset1.getBigDecimal("TOTAL_EMBARQUE");
						BigDecimal totalPedagio = rset1.getBigDecimal("TOTAL_PEDAGIO") == null ? BigDecimal.ZERO : rset1.getBigDecimal("TOTAL_PEDAGIO");
						BigDecimal totalSeguro = rset1.getBigDecimal("TOTAL_SEGURO") == null ? BigDecimal.ZERO : rset1.getBigDecimal("TOTAL_SEGURO");
						
						String prefixo = rset1.getString("PREFIXO") == null ? "" : rset1.getString("PREFIXO");
						String cidadeOrigem = rset1.getString("CIDADE_ORIGEM") == null ? "" : rset1.getString("CIDADE_ORIGEM");
						String cidadeDestino= rset1.getString("CIDADE_DESTINO") == null ? "" : rset1.getString("CIDADE_DESTINO");
						
						String nombEmpresa = rset1.getString("NOMBEMPRESA") == null ? "" : rset1.getString("NOMBEMPRESA");
						String nombPuntoVenta = rset1.getString("NOMBPUNTOVENTA") == null ? "" : rset1.getString("NOMBPUNTOVENTA");
						BigDecimal embarque_vendidos = rset1.getBigDecimal("EMBARQUE_VENDIDOS") == null ? BigDecimal.ZERO : rset1.getBigDecimal("EMBARQUE_VENDIDOS");
						BigDecimal pedagio_vendidos = rset1.getBigDecimal("PEDAGIO_VENDIDOS") == null ? BigDecimal.ZERO : rset1.getBigDecimal("PEDAGIO_VENDIDOS");
						BigDecimal seguro_vendidos = rset1.getBigDecimal("SEGURO_VENDIDOS") == null ? BigDecimal.ZERO : rset1.getBigDecimal("SEGURO_VENDIDOS");
						
						BigDecimal qtdSeguroOpcionalCancelado = rset1.getBigDecimal("QTD_SEGUROOPCIONALCANCELADO") == null ? BigDecimal.ZERO : rset1.getBigDecimal("QTD_SEGUROOPCIONALCANCELADO");
						BigDecimal totalValorSeguroOpcionalCancelado = rset1.getBigDecimal("TOTAL_SEG_CANCELADO") == null ? BigDecimal.ZERO : rset1.getBigDecimal("TOTAL_SEG_CANCELADO");
						BigDecimal qtdSeguroOpcionalVendidos = rset1.getBigDecimal("QTD_SEGUROOPCIONALVENDIDOS") == null ? BigDecimal.ZERO : rset1.getBigDecimal("QTD_SEGUROOPCIONALVENDIDOS");
						BigDecimal totalValorseguroOpcionalVendido = rset1.getBigDecimal("TOTAL_SEG_VENDIDO") == null ? BigDecimal.ZERO : rset1.getBigDecimal("TOTAL_SEG_VENDIDO");
						
						
						RelatorioTaxasLinhaBean taxasLinha = new RelatorioTaxasLinhaBean();
						
						if(!importeTaxaEmbarque.equals(BigDecimal.ZERO) && (Boolean) this.relatorio.getParametros().get("B_SUBTRAIR_ICMS")){
							valorIcms = CalculoImposto.getValorImposto(this.relatorio.getConexao(), idEstado, empresaId, indInterestadual, BigDecimal.ZERO, BigDecimal.ZERO, importeTaxaEmbarque, BigDecimal.ZERO);
							importeTaxaEmbarque = MoneyHelper.subtrair(importeTaxaEmbarque, valorIcms);
						}
						taxasLinha.setIMPORTETAXAEMBARQUE(importeTaxaEmbarque);
						
						if(!importePedagio.equals(BigDecimal.ZERO) && (Boolean) this.relatorio.getParametros().get("B_SUBTRAIR_ICMS")){
							valorIcms = CalculoImposto.getValorImposto(this.relatorio.getConexao(), idEstado, empresaId, indInterestadual, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, importePedagio);
							importePedagio = MoneyHelper.subtrair(importePedagio, valorIcms);
						}
						taxasLinha.setIMPORTEPEDAGIO(importePedagio);
						
						if(!importeSeguro.equals(BigDecimal.ZERO) && (Boolean) this.relatorio.getParametros().get("B_SUBTRAIR_ICMS")){
							valorIcms = CalculoImposto.getValorImposto(this.relatorio.getConexao(), idEstado, empresaId, indInterestadual, BigDecimal.ZERO, importeSeguro, BigDecimal.ZERO, BigDecimal.ZERO);
							importeSeguro = MoneyHelper.subtrair(importeSeguro, valorIcms);
						}
						taxasLinha.setIMPORTESEGURO(importeSeguro);
						
						if(!totalEmbarque.equals(BigDecimal.ZERO) && (Boolean) this.relatorio.getParametros().get("B_SUBTRAIR_ICMS")){
							//Mantis 16205 - Alinhado com a Junia
							//Estava sendo feita a subtracao do ICMS duas vezes, no valor unitario (Emb., Ped. e Seg.) e no totalizador (T Emb., T. Ped. e T. Seg.)
							//Assim os valores não batiam quando se multiplicava o valor unitario pela Q. EMB. por serem calculos independentes.
							//Agora o valor unitario é subtraido pelo ICMS e os totalizadores sao calculados pela multiplicado do Q. EMB.
							
//							valorIcms = CalculoImposto.getValorImposto(this.relatorio.getConexao(), idEstado, empresaId, indInterestadual, BigDecimal.ZERO, BigDecimal.ZERO, totalEmbarque , BigDecimal.ZERO);
//							totalEmbarque = MoneyHelper.subtrair(totalEmbarque, valorIcms);
							totalEmbarque = importeTaxaEmbarque.multiply(embarque_vendidos);
							
						}
						taxasLinha.setTOTAL_EMBARQUE(totalEmbarque);
						
						if(!totalPedagio.equals(BigDecimal.ZERO) && (Boolean) this.relatorio.getParametros().get("B_SUBTRAIR_ICMS")){
							//Mantis 16205 - Alinhado com a Junia
							//Estava sendo feita a subtracao do ICMS duas vezes, no valor unitario (Emb., Ped. e Seg.) e no totalizador (T Emb., T. Ped. e T. Seg.)
							//Assim os valores não batiam quando se multiplicava o valor unitario pela Q. EMB. por serem calculados independentes.
							//Agora o valor unitario é subtraído pelo ICMS e os totalizadores sao calculados pela multiplicacao do Q. EMB.
							
//							valorIcms = CalculoImposto.getValorImposto(this.relatorio.getConexao(), idEstado, empresaId, indInterestadual, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, totalPedagio);
//							totalPedagio = MoneyHelper.subtrair(totalPedagio, valorIcms);
							totalPedagio = importePedagio.multiply(pedagio_vendidos);
						}
						taxasLinha.setTOTAL_PEDAGIO(totalPedagio);
						
						if(!totalSeguro.equals(BigDecimal.ZERO) && (Boolean) this.relatorio.getParametros().get("B_SUBTRAIR_ICMS")){
							//Mantis 16205 - Alinhado com a Junia
							//Estava sendo feita a subtração do ICMS duas vezes, no valor unitario (Emb., Ped. e Seg.) e no totalizador (T Emb., T. Ped. e T. Seg.)
							//Assim os valores não batiam quando se multiplicava o valor unitario pela Q. EMB. por serem calculos independentes.
							//Agora o valor unitario é subtraído pelo ICMS e os totalizadores sao calculados pela multiplicação do Q. EMB.
							
//							valorIcms = CalculoImposto.getValorImposto(this.relatorio.getConexao(), idEstado, empresaId, indInterestadual, BigDecimal.ZERO, totalSeguro, BigDecimal.ZERO, BigDecimal.ZERO);
//							totalSeguro = MoneyHelper.subtrair(totalSeguro, valorIcms);
							totalSeguro = importeSeguro.multiply(seguro_vendidos);
						}
						taxasLinha.setTOTAL_SEGURO(totalSeguro);
						
						taxasLinha.setPREFIXO(prefixo);
						taxasLinha.setCIDADE_ORIGEM(cidadeOrigem);
						taxasLinha.setCIDADE_DESTINO(cidadeDestino);
						
						taxasLinha.setNOMBEMPRESA(nombEmpresa);
						taxasLinha.setNOMBPUNTOVENTA(nombPuntoVenta);
						
						taxasLinha.setEMBARQUE_VENDIDOS(embarque_vendidos);
						taxasLinha.setPEDAGIO_VENDIDOS(pedagio_vendidos);
						taxasLinha.setSEGURO_VENDIDOS(seguro_vendidos);
						
						taxasLinha.setQtdSeguroOpcionalCancelado(qtdSeguroOpcionalCancelado);
						taxasLinha.setTotalValorSeguroOpcionalCancelado(totalValorSeguroOpcionalCancelado);
						taxasLinha.setQtdSeguroOpcionalVendidos(qtdSeguroOpcionalVendidos);
						taxasLinha.setTotalValorseguroOpcionalVendido(totalValorseguroOpcionalVendido);
																		
						if( importeTaxaEmbarque.doubleValue() > 0 && isTxEmbarque ) {
							isValidado = true;
						}else if( importeSeguro.doubleValue() > 0 && isSeguro ) {
							isValidado = true;
						}else if( importePedagio.doubleValue() > 0 && isPedagio ) {
							isValidado = true;
						}else if((taxasLinha.getTotalValorSeguroOpcionalCancelado().compareTo(BigDecimal.ZERO)==1 || taxasLinha.getTotalValorseguroOpcionalVendido().compareTo(BigDecimal.ZERO)==1)  && isSeguroW2I ) {
							isValidado = true;
						}
						
						if( isValidado ) {
							lsDadosRelatorio.add(taxasLinha);
						}

					}
				
				if (lsDadosRelatorio.size() > 0) {

					setLsDadosRelatorio(lsDadosRelatorio);
				}
			}
			
		});
	}

	public void setLsDadosRelatorio(List<RelatorioTaxasLinhaBean> lsDadosRelatorio) {
		this.setCollectionDataSource(new JRBeanCollectionDataSource(lsDadosRelatorio));
		this.lsDadosRelatorio = lsDadosRelatorio;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio#processaParametros()
	 */
	@Override
	protected void processaParametros() throws Exception {
	}

	public HashMap<String, Object> getConfigImposto(Integer idEstado, Integer puntoVentaId) throws Exception {
		HashMap<String, Object> cacheConfig = null;

		try {
			cacheConfig = (HashMap<String, Object>) CalculoImposto.getConfigImpostoByEstadoOrigem(this.getConexao(), idEstado, puntoVentaId);
		} catch (Exception e) {
			if (e instanceof ExceptionConfiguracao)
				this.addInfoMsg(e.getMessage());
			else
				throw e;
		}

		return cacheConfig;
	}

	private String getSql(String puntosVentaIds, Boolean isSubNoShow) {
		StringBuilder sql = new StringBuilder();

		sql.append(" SELECT RT.PREFIXO, ");
		sql.append("        PO.DESCPARADA CIDADE_ORIGEM, ");
		sql.append("        PD.DESCPARADA CIDADE_DESTINO, ");
		sql.append("        COALESCE(CJ.IMPORTETAXAEMBARQUE,0) AS IMPORTETAXAEMBARQUE, ");
		sql.append("        COALESCE(CJ.IMPORTEPEDAGIO,0) AS IMPORTEPEDAGIO, ");
		sql.append("        COALESCE(CJ.IMPORTESEGURO,0) AS IMPORTESEGURO, ");
		sql.append("        EM.NOMBEMPRESA, ");
		sql.append("        EM.EMPRESA_ID, ");
		sql.append("        CJ.PUNTOVENTA_ID, ");
		sql.append("        PV.NOMBPUNTOVENTA, ");
		sql.append("        SUM(CASE WHEN (CJ.IMPORTETAXAEMBARQUE>0 and cj.indcancelacion = 0  ) THEN 1 WHEN (CJ.IMPORTETAXAEMBARQUE>0 and cj.indcancelacion = 1 ) then -1 ELSE 0 END) EMBARQUE_VENDIDOS, ");
		sql.append("        SUM(CASE WHEN (CJ.IMPORTEPEDAGIO>0 and cj.indcancelacion = 0  ) THEN 1 WHEN (CJ.IMPORTEPEDAGIO>0 and cj.indcancelacion = 1 ) THEN -1 ELSE 0 END) PEDAGIO_VENDIDOS, ");
		sql.append("        SUM(CASE WHEN (CJ.IMPORTESEGURO>0 and cj.indcancelacion = 0  ) THEN 1 WHEN (CJ.IMPORTESEGURO>0 and cj.indcancelacion = 1 ) THEN -1 ELSE 0 END) SEGURO_VENDIDOS, ");
		sql.append("        CO.ESTADO_ID ORIGEM_ESTADO_ID, ");
		sql.append("        CD.ESTADO_ID DESTINO_ESTADO_ID, ");
		sql.append("        CASE ");
		sql.append("          WHEN CO.ESTADO_ID <> CD.ESTADO_ID THEN ");
		sql.append("           'S' ");
		sql.append("          ELSE ");
		sql.append("           'N' ");
		sql.append("        END INTERESTADUAL, ");
		sql.append("        SUM( (case when cj.indcancelacion = 0  then 1  else -1 end) * CJ.IMPORTETAXAEMBARQUE) TOTAL_EMBARQUE, ");
		sql.append("        SUM( (case when cj.indcancelacion = 0  then 1  else -1 end) * CJ.IMPORTEPEDAGIO) TOTAL_PEDAGIO, ");
		sql.append("        SUM( (case when cj.indcancelacion = 0  then 1  else -1 end) * CJ.IMPORTESEGURO) TOTAL_SEGURO, ");
		sql.append("        EST.ICMS AS ICMS, ");
		sql.append("        SUM( (case when sx.status =0 then 1 else 0.0  end)) QTD_SEGUROOPCIONALCANCELADO, ");
        sql.append("        SUM( (case when sx.status =0 then sx.valor  else 0.0 end )) TOTAL_SEG_CANCELADO, ");
        sql.append("        SUM( (case when sx.status >0 then 1 else 0.0 end )) QTD_SEGUROOPCIONALVENDIDOS, ");
        sql.append("        SUM( (case when sx.status >0 then sx.valor else 0.0 end )) TOTAL_SEG_VENDIDO ");
		
		sql.append("FROM  CAJA CJ ");
		sql.append("INNER JOIN PUNTO_VENTA 		PV ON CJ.PUNTOVENTA_ID     = PV.PUNTOVENTA_ID ");
		sql.append("INNER JOIN EMPRESA     		EM ON CJ.EMPRESACORRIDA_ID = EM.EMPRESA_ID ");
		sql.append("INNER JOIN PARADA      		PO ON CJ.ORIGEN_ID         = PO.PARADA_ID ");
		sql.append("INNER JOIN PARADA      		PD ON CJ.DESTINO_ID        = PD.PARADA_ID ");
		sql.append("INNER JOIN CIUDAD      		CO ON PO.CIUDAD_ID         = CO.CIUDAD_ID ");
		sql.append("INNER JOIN ESTADO 			EST ON EST.ESTADO_ID = CO.estado_ID ");
		sql.append("INNER JOIN CIUDAD      		CD ON PD.CIUDAD_ID         = CD.CIUDAD_ID ");
		sql.append("LEFT JOIN  CORRIDA     		CR ON (CJ.CORRIDA_ID = CR.CORRIDA_ID AND CJ.FECCORRIDA = CR.FECCORRIDA) ");
		sql.append("LEFT JOIN  RUTA        		RT ON RT.RUTA_ID 		  = CJ.RUTA_ID ");
		sql.append("LEFT JOIN  SEGPOLV          SX ON SX.BOLETO_ID        = CJ.TRANSACAO_ID ");
		sql.append("LEFT JOIN  TAXPOLV     		TX ON TX.BOLETO_ID        = CJ.TRANSACAO_ID ");
		
		sql.append("WHERE (CJ.IMPORTETAXAEMBARQUE>0 OR CJ.IMPORTEPEDAGIO>0 OR CJ.IMPORTESEGURO>0 OR SX.VALOR>0 OR TX.VALORTAXA > 0) ");
		sql.append("AND CJ.INDSTATUSOPERACION = 'F' ");
		sql.append("AND CJ.INDREIMPRESION = 0 ");
		sql.append("AND DECODE(:TIPO_DATA, 1, CJ.FECHORVENTA, 2, CJ.FECCORRIDA) BETWEEN :DATA_INICIAL AND :DATA_FINAL ");
		sql.append("AND EM.EMPRESA_ID = COALESCE(:EMPRESA_ID, EM.EMPRESA_ID) ");
		
		if (isSubNoShow) {
			sql.append("    AND CJ.MOTIVOCANCELACION_ID NOT IN (23,27) ");
		}
		if (!puntosVentaIds.equals("Todas")) {
			sql.append("    AND PV.PUNTOVENTA_ID IN (").append(puntosVentaIds).append(") ");
		}
		sql.append("    AND PO.PARADA_ID = COALESCE(:ORIGEN_ID, PO.PARADA_ID) ");
		sql.append("    AND PD.PARADA_ID = COALESCE(:DESTINO_ID, PD.PARADA_ID) ");

		sql.append("  GROUP BY RT.PREFIXO, ");
		sql.append("           PO.DESCPARADA, ");
		sql.append("           PD.DESCPARADA, ");
		sql.append("           COALESCE(CJ.IMPORTETAXAEMBARQUE,0), ");
		sql.append("           COALESCE(CJ.IMPORTEPEDAGIO,0), ");
		sql.append("           COALESCE(CJ.IMPORTESEGURO,0), ");
		sql.append("           CO.ESTADO_ID, ");
		sql.append("           CD.ESTADO_ID, ");
		sql.append("           EM.NOMBEMPRESA, ");
		sql.append("           EM.EMPRESA_ID, ");
		sql.append("       	   CJ.PUNTOVENTA_ID, ");
		sql.append("           PV.NOMBPUNTOVENTA, ");
		sql.append("           EST.ICMS ");

		sql.append("  ORDER BY EM.NOMBEMPRESA,PV.NOMBPUNTOVENTA ,PO.DESCPARADA, PD.DESCPARADA ");
		
		return sql.toString();
	}
}