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

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.rjconsultores.ventaboletos.relatorios.utilitarios.ArrayDataSource;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

public class RelatorioFormaPagamentoAgenciaNovo extends RelatorioDemandas {
	public RelatorioFormaPagamentoAgenciaNovo(Map<String, Object> parametros, Connection conexao) throws Exception {
		super(parametros, conexao);
		this.setCustomDataSource(new ArrayDataSource(this) {
			@Override
			public void initDados() throws Exception {

				Connection conexao = this.relatorio.getConexao();
				Map<String, Object> parametros = this.relatorio.getParametros();

				Date dataInicial = (Date) parametros.get("DATA_INICIAL");
				Date dataFinal = (Date) parametros.get("DATA_FINAL");				
				Integer empresa = (Integer) parametros.get("EMPRESA");
				Integer agencia = (Integer) parametros.get("AGENCIA");				
				Short formaPagoId = (Short) parametros.get("FORMA_PAGO");	        
		        
		        StringBuilder sql = new StringBuilder();
		        sql.append(" SELECT " );
		        sql.append("     c.caja_id                          AS cajaID, " );
		        sql.append("     c.fechorventa                      AS data, " );
		        sql.append("     c.numfoliosistema                  AS bilhete, " );
		        sql.append("     bpe.NBP                            AS bpe, " );
		        sql.append("     pv.nombpuntoventa                  AS agencia, " );
		        sql.append("     p_origen.CVEPARADA                 AS origem , " );
		        sql.append("     p_destino.CVEPARADA                AS destino, " );
		        sql.append("     fpb.descpago                       AS forma_pago_original, " );
		        sql.append("     fp.descpago                        AS forma_pagamento, " );
		        sql.append("     coalesce(c.preciopagado, 0)        AS tarifa, " );
		        sql.append("     coalesce(c.importepedagio, 0)      AS pedagio, " );
		        sql.append("     coalesce(c.importeseguro, 0)       AS seguro, " );
		        sql.append("     coalesce(c.importetaxaembarque, 0) AS taxa, " );
		        sql.append("     coalesce(cfp.importe, 0)           AS valor,  " );
		        sql.append("     coalesce(seg.valor, 0)             AS seg_opcional, " );
		        sql.append("     c.indstatusboleto                  AS status, " );
		        sql.append("     c.indcancelacion,							  " );
		        sql.append("     mc.descmotivo 						AS motivo" );
		        sql.append(" FROM " );
		        sql.append("     caja c " );
		        sql.append("     JOIN caja_formapago cfp ON c.caja_id = cfp.caja_id " );
		        sql.append("     JOIN forma_pago     fp ON cfp.formapago_id = fp.formapago_id " );
		        sql.append("     JOIN boleto_formapago   bfp ON ( c.transacaooriginal_id = bfp.boleto_id ) " );
		        sql.append("     JOIN forma_pago         fpb ON bfp.formapago_id = fpb.formapago_id " );
		        sql.append("     JOIN punto_venta    pv ON pv.puntoventa_id = c.puntoventa_id " );
		        sql.append("     JOIN marca          m  ON m.marca_id = c.marca_id AND m.activo = 1 " );
		        sql.append("     LEFT JOIN motivo_cancelacion mc ON (mc.motivocancelacion_id = c.motivocancelacion_id) " );
		        sql.append("     LEFT JOIN BPE bpe on c.transacao_id = bpe.boleto_id " );
		        sql.append("     JOIN parada p_origen   ON p_origen.parada_id = c.origen_id  " );
		        sql.append("     JOIN parada p_destino  ON p_destino.parada_id = c.destino_id  " );
		        sql.append("     LEFT JOIN segpolv seg ON c.transacao_id = seg.boleto_id " );
		        sql.append(" WHERE " );
		        sql.append("     c.activo = 1 " );
		        sql.append("     AND c.indreimpresion = 0 " );
	        	sql.append("     AND c.fechorventa >= :dataInicial " );
	        	sql.append("     AND c.fechorventa <= :dataFinal " );		        
		        
		        if (empresa != null) {
		        	sql.append(" AND m.empresa_id  = :empresaId ");
		        }
		        
		        if (agencia != null) {
		        	sql.append(" AND c.puntoventa_id = :agenciaId ");
		        }
		        
		        if (formaPagoId != null) {
		        	sql.append(" AND cfp.FORMAPAGO_ID = :formaPagoId ");
		        }
		        
		        sql.append("  ORDER BY data, agencia, bilhete " );

				NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql.toString());
								
				stmt.setDate("dataInicial", DateUtil.inicioFechaSql(dataInicial));
				stmt.setDate("dataFinal", DateUtil.fimFechaSql(dataFinal));
				
				if (empresa != null) {
					stmt.setInt("empresaId", empresa);					
				}
				
				if (agencia != null) {
					stmt.setInt("agenciaId", agencia);					
				}
				
				if (formaPagoId != null ) {
					stmt.setInt("formapagoId", formaPagoId);
				}

				ResultSet rset = stmt.executeQuery();
				String cajaID = StringUtils.EMPTY;

				while (rset.next()) {
				    Map<String, Object> dataResult = new HashMap<>();

				    String motivoCancelamento = getValueOrEmpty(rset, "motivo");
				    String indStatus = getValueOrEmpty(rset, "status");
				    String bpe = getValueOrEmpty(rset, "bpe");

				    Boolean isCancelamento = "1".equals(rset.getString("indcancelacion"));
				    String formaPagamento = getValueOrEmpty(rset, "forma_pagamento");
				    String formaPagamentoOriginal = getValueOrEmpty(rset, "forma_pago_original");
				    Boolean isFormaPagamentoIguais = formaPagamento.equals(formaPagamentoOriginal);

				    Boolean isCajaIDRepetido = cajaID.equals(rset.getString("cajaID"));
				    cajaID = isCajaIDRepetido ? cajaID : rset.getString("cajaID");

				    BigDecimal tarifa = getBigDecimal(isCajaIDRepetido, rset, "tarifa");
				    BigDecimal pedagio = getBigDecimal(isCajaIDRepetido, rset, "PEDAGIO");
				    BigDecimal seguro = getBigDecimal(isCajaIDRepetido, rset, "SEGURO");
				    BigDecimal seguroOPC = getBigDecimal(isCajaIDRepetido, rset, "seg_opcional");
				    BigDecimal taxa = getBigDecimal(isCajaIDRepetido, rset, "taxa");
				    BigDecimal valor = rset.getBigDecimal("valor");

				    popularData(dataResult, rset, bpe, indStatus, motivoCancelamento);
				    
				    boolean isReplicado = processarTransacao(dataResult, isCancelamento, tarifa, pedagio, seguro, seguroOPC, taxa, valor, formaPagamento, formaPagamentoOriginal, isFormaPagamentoIguais);

				    if (!isReplicado) {
				        this.dados.add(dataResult);
				    }
				}

				this.resultSet = rset;
				
				
			}
			
			private String getValueOrEmpty(ResultSet rset, String columnName) throws SQLException {
			    return StringUtils.defaultString(rset.getString(columnName), StringUtils.EMPTY);
			}

			private BigDecimal getBigDecimal(Boolean isCajaIDRepetido, ResultSet rset, String columnName) throws SQLException {
			    return isCajaIDRepetido ? BigDecimal.ZERO : rset.getBigDecimal(columnName);
			}

			private void popularData(Map<String, Object> dataResult, ResultSet rset, String bpe, String indStatus, String motivoCancelamento) throws SQLException {
			    dataResult.put("DATA", rset.getDate("data"));
			    dataResult.put("BILHETE", rset.getString("bilhete"));
			    dataResult.put("ORIGEM", rset.getString("ORIGEM"));
			    dataResult.put("DESTINO", rset.getString("DESTINO"));
			    dataResult.put("AGENCIA", rset.getString("agencia"));
			    dataResult.put("NUMERO_BPE", bpe);
			    dataResult.put("STATUS", indStatus);
			    dataResult.put("MOTIVO_CANCELAMENTO", motivoCancelamento);
			}

			private boolean processarTransacao(Map<String, Object> dataResult, Boolean isCancelamento, BigDecimal tarifa, BigDecimal pedagio, BigDecimal seguro, BigDecimal seguroOPC, BigDecimal taxa, BigDecimal valor, String formaPagamento, String formaPagamentoOriginal, Boolean isFormaPagamentoIguais) {
			    if (isCancelamento) {
			        transacaoNegativa(dataResult, tarifa, pedagio, seguro, seguroOPC, taxa, valor, formaPagamentoOriginal);
			        return false;
			    } else if (isFormaPagamentoIguais) {
			        transacaoNormal(dataResult, tarifa, pedagio, seguro, seguroOPC, taxa, valor, formaPagamento);
			        return false;
			    }
			    return true;
			}

			private void transacaoNegativa(Map<String, Object> dataResult, BigDecimal tarifa, BigDecimal pedagio, BigDecimal seguro, BigDecimal seguroOPC, BigDecimal taxa, BigDecimal valor, String formaPagamentoOriginal) {
			    dataResult.put("FORMA_PAGAMENTO", formaPagamentoOriginal);
			    dataResult.put("TARIFA", tarifa.negate());
			    dataResult.put("PEDAGIO", pedagio.negate());
			    dataResult.put("SEGURO", seguro.negate());
			    dataResult.put("SEG_OPCIONAL", seguroOPC.negate());
			    dataResult.put("TAXA", taxa.negate());
			    dataResult.put("VALOR", valor.negate());
			}

			private void transacaoNormal(Map<String, Object> dataResult, BigDecimal tarifa, BigDecimal pedagio, BigDecimal seguro, BigDecimal seguroOPC, BigDecimal taxa, BigDecimal valor, String formaPagamento) {
			    dataResult.put("FORMA_PAGAMENTO", formaPagamento);
			    dataResult.put("TARIFA", tarifa);
			    dataResult.put("PEDAGIO", pedagio);
			    dataResult.put("SEGURO", seguro);
			    dataResult.put("SEG_OPCIONAL", seguroOPC);
			    dataResult.put("TAXA", taxa);
			    dataResult.put("VALOR", valor);
			}
		});
		
		
	}
}