package com.rjconsultores.ventaboletos.relatorios.impl;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
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.RelatorioVendasConexaoBean;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

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

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

	private List<RelatorioVendasConexaoBean> lsDadosRelatorio;
	
	private Timestamp fecInicio;
	private Timestamp fecFinal;
	private Integer empresaId;
	private Integer puntoventaId;
	
	public RelatorioVendasConexao(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("EMPRESA_ID")!=null){
					empresaId =  Integer.valueOf(parametros.get("EMPRESA_ID").toString());
				}
				if(parametros.get("PUNTOVENTA_ID")!=null){
					puntoventaId =  Integer.valueOf(parametros.get("PUNTOVENTA_ID").toString());
				}

				Connection conexao = this.relatorio.getConexao();
				processarVendasConexao(conexao);
				
				setCollectionDataSource(new JRBeanCollectionDataSource(lsDadosRelatorio));
			}

		});
	}
	
	private void processarVendasConexao(Connection conexao) {
		ResultSet rset = null;
		NamedParameterStatement stmt = null;
		
		try {
			
			stmt = carregarNamedParameterStatement(conexao);
			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<RelatorioVendasConexaoBean>();
		}
		
		while (rset.next()) {
			RelatorioVendasConexaoBean bean = new RelatorioVendasConexaoBean();
			bean.setNombpuntoventa(rset.getString("NOMBPUNTOVENTA"));
			bean.setNombempresa(rset.getString("NOMBEMPRESA"));
			bean.setEmpresaId(rset.getInt("EMPRESA_ID"));
			bean.setDescpago(rset.getString("DESCPAGO"));
			bean.setImporte(rset.getBigDecimal("IMPORTE"));
			bean.setNegate(!bean.getEmpresaId().equals(empresaId));
			
			lsDadosRelatorio.add(bean);
		}
		
	}
	
	private NamedParameterStatement carregarNamedParameterStatement(Connection conexao) throws SQLException {
		String sql = getSql();
		log.info(sql);
		
		NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql);
		
		if(fecInicio != null) {
			stmt.setTimestamp("fecInicio", fecInicio);
		}
		if(fecFinal != null) {
			stmt.setTimestamp("fecFinal", fecFinal);
		}
		if(empresaId != null) {
			stmt.setInt("EMPRESA_ID", empresaId);
		}
		if(puntoventaId != null && puntoventaId > -1) {
			stmt.setInt("PUNTOVENTA_ID", puntoventaId);
		}
		
		return stmt;
	}

	protected String getSql() {

		StringBuilder sQuery = new StringBuilder();
		sQuery.append("SELECT PV.NOMBPUNTOVENTA, E.NOMBEMPRESA, E.EMPRESA_ID, NVL(CT.NUMTARJETA,FP.DESCPAGO) AS DESCPAGO, CFP.FORMAPAGO_ID, SUM(CFP.IMPORTE) AS IMPORTE ")
			  .append("FROM CAJA C ")
			  .append("JOIN CAJA_FORMAPAGO CFP ON CFP.CAJA_ID = C.CAJA_ID ")
			  .append("LEFT JOIN CAJA_DET_PAGO CDP ON CDP.CAJAFORMAPAGO_ID = CFP.CAJAFORMAPAGO_ID ")
			  .append("LEFT JOIN CAJA_TARJETA CT ON CT.CAJADETPAGO_ID = CDP.CAJADETPAGO_ID ")
			  .append("JOIN FORMA_PAGO FP ON FP.FORMAPAGO_ID = CFP.FORMAPAGO_ID ")
			  .append("JOIN MARCA M ON C.MARCA_ID = M.MARCA_ID ")
			  .append("JOIN EMPRESA E ON E.EMPRESA_ID = M.EMPRESA_ID ")
			  .append("JOIN PUNTO_VENTA PV ON PV.PUNTOVENTA_ID = C.PUNTOVENTA_ID ")
			  .append("WHERE C.INDCONEXION = 1 ")
			  .append("AND C.INDREIMPRESION = 0 ")
			  .append("AND C.TIPOVENTA_ID <> 6 ")
			  .append("AND C.NUMOPERACION IN ( ")
			  .append("  SELECT C.NUMOPERACION ")
			  .append("  FROM CAJA C ")
			  .append("  JOIN MARCA M ON C.MARCA_ID = M.MARCA_ID ")
			  .append("  JOIN EMPRESA E ON E.EMPRESA_ID = M.EMPRESA_ID ")
			  .append("  JOIN PUNTO_VENTA PV ON PV.PUNTOVENTA_ID = C.PUNTOVENTA_ID ")
			  .append("  WHERE C.INDCONEXION = 1 ")
			  .append("  AND C.INDREIMPRESION = 0 ")
			  .append("  AND C.TIPOVENTA_ID <> 6 ");
		
		if(fecInicio != null) {
			sQuery.append("AND NVL(C.FECHORVENTA_H,C.FECHORVENTA) >= :fecInicio ");
		}
		if(fecFinal != null) {
			sQuery.append("AND NVL(C.FECHORVENTA_H,C.FECHORVENTA) <= :fecFinal ");
		}
		if(empresaId != null) {
			sQuery.append("AND E.EMPRESA_ID = :EMPRESA_ID ");
		}
		if(puntoventaId != null && puntoventaId > -1) {
			sQuery.append("AND C.PUNTOVENTA_ID = :PUNTOVENTA_ID ");
		}
		
		sQuery.append(") ")
			  .append("GROUP BY PV.NOMBPUNTOVENTA, E.NOMBEMPRESA, E.EMPRESA_ID, NVL(CT.NUMTARJETA,FP.DESCPAGO), CFP.FORMAPAGO_ID ")
			  .append("ORDER BY PV.NOMBPUNTOVENTA, NVL(CT.NUMTARJETA,FP.DESCPAGO)");
		
		return sQuery.toString();
		
	}
	
	@Override
	protected void processaParametros() throws Exception {
	}
	
	public List<RelatorioVendasConexaoBean> getLsDadosRelatorio() {
		return lsDadosRelatorio;
	}
	
	@Override
	public String getNome() {
		return super.getNome();
	}

}
