package com.rjconsultores.ventaboletos.relatorios.impl;

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

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

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.rjconsultores.ventaboletos.constantes.Constantes;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.DataSource;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.RelatorioVendasComissaoBean;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

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

	private SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
	
	private List<RelatorioVendasComissaoBean> lsDadosRelatorio;
	
	private Timestamp fecInicio;
	private Timestamp fecFinal;
	private Integer marcaId;
	
	public RelatorioVendasComissao(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 = (Timestamp) parametros.get("dataFiltroInicial");
				fecFinal = (Timestamp) parametros.get("dataFiltroFinal");
				if(parametros.get("MARCA_ID")!=null){
					marcaId =  Integer.valueOf(parametros.get("MARCA_ID").toString());
				}
				
				Connection conexao = this.relatorio.getConexao();
				processarVendasComissao(conexao);
				setLsDadosRelatorio(lsDadosRelatorio);
			}

		});
	}
	
	private void processarVendasComissao(Connection conexao) {
		ResultSet rset = null;
		NamedParameterStatement stmt = null;
		
		try {
			if(lsDadosRelatorio == null) {
				lsDadosRelatorio = new ArrayList<RelatorioVendasComissaoBean>();
			}

			/* Processando vendas normais */
			stmt = carregarNamedParameterStatement(conexao);
			rset = stmt.executeQuery();
			processarResultado(rset);
			fecharConexaoBanco(stmt, rset);

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

	private void processarResultado(ResultSet rset) throws SQLException {
		while (rset.next()) {
			RelatorioVendasComissaoBean relatorioVendasPacotesBoletosBean = new RelatorioVendasComissaoBean();
			relatorioVendasPacotesBoletosBean.setNumPuntoVenta(rset.getString("NUMPUNTOVENTA"));
			relatorioVendasPacotesBoletosBean.setNombPuntoVenta(rset.getString("NOMBPUNTOVENTA"));
			String indstatusboleto = rset.getString("INDSTATUSBOLETO");
			Long motivocancelacionId = rset.getLong("MOTIVOCANCELACION_ID");
			if(isDevolucaoOrCancelamentoCaja(indstatusboleto, motivocancelacionId) && StringUtils.isNotBlank(rset.getString("NUMPTOVTAVENTA"))) {
				relatorioVendasPacotesBoletosBean.setNumPuntoVenta(rset.getString("NUMPTOVTAVENTA"));
				relatorioVendasPacotesBoletosBean.setNombPuntoVenta(rset.getString("NOMBPTOVTAVENTA"));
			} 
			
			boolean contain = lsDadosRelatorio.contains(relatorioVendasPacotesBoletosBean);
			if(contain) {
				relatorioVendasPacotesBoletosBean = lsDadosRelatorio.get(lsDadosRelatorio.indexOf(relatorioVendasPacotesBoletosBean));
			}

			if(isVenda(indstatusboleto)) {
				relatorioVendasPacotesBoletosBean.setTotalVendas(relatorioVendasPacotesBoletosBean.getTotalVendas().add(rset.getBigDecimal("TOTAL") != null ? rset.getBigDecimal("TOTAL") : new BigDecimal(0)));
				relatorioVendasPacotesBoletosBean.setTotalTaxasVendas(relatorioVendasPacotesBoletosBean.getTotalTaxasVendas().add(rset.getBigDecimal("TOTAL_TAXAS") != null ? rset.getBigDecimal("TOTAL_TAXAS") : new BigDecimal(0)));
			} else if(isCancelamentoCaja(indstatusboleto, motivocancelacionId)) {
				relatorioVendasPacotesBoletosBean.setTotalVendasCanceladas(relatorioVendasPacotesBoletosBean.getTotalVendasCanceladas().add(rset.getBigDecimal("TOTAL") != null ? rset.getBigDecimal("TOTAL") : new BigDecimal(0)));
				relatorioVendasPacotesBoletosBean.setTotalTaxasVendasCanceladas(relatorioVendasPacotesBoletosBean.getTotalTaxasVendasCanceladas().add(rset.getBigDecimal("TOTAL_TAXAS") != null ? rset.getBigDecimal("TOTAL_TAXAS") : new BigDecimal(0)));
			} else if(isDevolucaoCaja(indstatusboleto, motivocancelacionId)) {
				relatorioVendasPacotesBoletosBean.setTotalVendasDevolucao(relatorioVendasPacotesBoletosBean.getTotalVendasDevolucao().add(rset.getBigDecimal("TOTAL") != null ? rset.getBigDecimal("TOTAL") : new BigDecimal(0)));
				relatorioVendasPacotesBoletosBean.setTotalTaxasVendasDevolucao(relatorioVendasPacotesBoletosBean.getTotalTaxasVendasDevolucao().add(rset.getBigDecimal("TOTAL_TAXAS") != null ? rset.getBigDecimal("TOTAL_TAXAS") : new BigDecimal(0)));
			}
			
			if(!contain) {
				lsDadosRelatorio.add(relatorioVendasPacotesBoletosBean);
			}
		}
		
	}
	
	private boolean isCancelamento(String indstatusboleto) {
		return "C".equals(indstatusboleto);
	}

	private boolean isVenda(String indstatusboleto) {
		return "V".equals(indstatusboleto);
	}

	private boolean isCancelamentoCaja(String indstatusboleto, Long motivocancelacionId) {
		return isCancelamento(indstatusboleto) && Constantes.MVO_CANCEL_CANCELACION.equals(motivocancelacionId);
	}
	
	private boolean isDevolucaoCaja(String indstatusboleto, Long motivocancelacionId) {
		return "C".equals(indstatusboleto) && Constantes.MVO_CANCEL_DEVOLUCAO.equals(motivocancelacionId);
	}
	
	private boolean isDevolucaoOrCancelamentoCaja(String indstatusboleto, Long motivocancelacionId) {
		return isCancelamentoCaja(indstatusboleto, motivocancelacionId) || isDevolucaoCaja(indstatusboleto, motivocancelacionId);
	}

	private NamedParameterStatement carregarNamedParameterStatement(Connection conexao) throws SQLException {
		String sql = getSqlPacotes();
		log.info(sql);
		
		NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql);
		
		if(fecInicio != null) {
			stmt.setTimestamp("fecInicio", fecInicio);
		}
		if(fecFinal != null) {
			stmt.setTimestamp("fecFinal", fecFinal);
		}
		if(marcaId != null){
			stmt.setInt("MARCA_ID", marcaId);
		}
		
		return stmt;
	}

	protected String getSqlPacotes() {
		StringBuilder sQuery = new StringBuilder();
		
		sQuery.append("SELECT PV.PUNTOVENTA_ID, PV.NUMPUNTOVENTA, PV.NOMBPUNTOVENTA, C.PTOVTAVENTA_ID, PV1.NUMPUNTOVENTA as NUMPTOVTAVENTA, PV1.NOMBPUNTOVENTA AS NOMBPTOVTAVENTA, C.INDSTATUSBOLETO, C.MOTIVOCANCELACION_ID, ")
			  .append("SUM(C.PRECIOPAGADO + C.IMPORTETAXAEMBARQUE + C.IMPORTESEGURO + C.IMPORTEPEDAGIO + C.IMPORTEOUTROS) AS TOTAL, ")
			  .append("SUM(C.IMPORTETAXAEMBARQUE + C.IMPORTESEGURO + C.IMPORTEPEDAGIO + C.IMPORTEOUTROS) AS TOTAL_TAXAS ")
			  .append("FROM CAJA C ")
			  .append("JOIN PUNTO_VENTA PV ON PV.PUNTOVENTA_ID = C.PUNTOVENTA_ID ")
			  .append("LEFT JOIN PUNTO_VENTA PV1 ON PV1.PUNTOVENTA_ID = C.PTOVTAVENTA_ID ")
			  .append("WHERE (C.INDSTATUSBOLETO = 'V' OR (C.INDCANCELACION = 1 AND C.INDSTATUSBOLETO = 'C')) ")
			  .append("AND C.FECHORVENTA BETWEEN :fecInicio AND :fecFinal ");
			  if(parametros.get("MARCA_ID")!= null){
				  sQuery.append("AND C.MARCA_ID =:MARCA_ID ");
			  }
			  sQuery.append("GROUP BY PV.PUNTOVENTA_ID, PV.NUMPUNTOVENTA, PV.NOMBPUNTOVENTA, C.PTOVTAVENTA_ID, PV1.NUMPUNTOVENTA, PV1.NOMBPUNTOVENTA, C.INDSTATUSBOLETO, C.MOTIVOCANCELACION_ID ")
			  .append("ORDER BY PV.NUMPUNTOVENTA, PV1.NUMPUNTOVENTA, C.INDSTATUSBOLETO");
		
		return sQuery.toString();
	}
	
	@Override
	protected void processaParametros() throws Exception {
	}
	
	public List<RelatorioVendasComissaoBean> getLsDadosRelatorio() {
		return lsDadosRelatorio;
	}

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

}
