package com.rjconsultores.ventaboletos.relatorios.impl;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
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.RelatorioDepositoBean;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

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

public class RelatorioDepositos extends Relatorio {

	private static Logger log = LogManager.getLogger(RelatorioDepositos.class);

	private List<RelatorioDepositoBean> lsDadosRelatorio;

	public RelatorioDepositos(Map<String, Object> parametros, Connection conexao, final String... nomeSubReporte) {
		super(parametros, conexao);

		try {
			this.setCustomDataSource(new DataSource(this) {
				@Override
				public void initDados() throws Exception {

					Connection conexao = this.relatorio.getConexao();

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

					Integer puntoventaId = parametros.get(PUNTOVENTA_ID) != null ? Integer.parseInt(parametros.get(PUNTOVENTA_ID).toString()) : null;
					Integer empresaId = parametros.get(EMPRESA_ID) != null ? Integer.parseInt(parametros.get(EMPRESA_ID).toString()) : null;
					boolean filtrarPendentes = parametros.get("filtrarPendentes") != null ? Boolean.parseBoolean(parametros.get("filtrarPendentes").toString()) : false;
					String fecInicio = parametros.get(FEC_INICIO).toString() + " 00:00:00";
					String fecFinal = parametros.get(FEC_FINAL).toString() + " 23:59:59";

					String sql = getSQL(puntoventaId, empresaId, filtrarPendentes);

					NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql);

					stmt.setTimestamp(FEC_INICIO, DateUtil.getTimestampFromString(fecInicio, DateUtil.ddMMaaHH24mmss));
					stmt.setTimestamp(FEC_FINAL, DateUtil.getTimestampFromString(fecFinal, DateUtil.ddMMaaHH24mmss));
					
					if(puntoventaId != null && puntoventaId != -1) {
						stmt.setInt(PUNTOVENTA_ID, puntoventaId);
					}
					
					if(empresaId != null) {
						stmt.setInt(EMPRESA_ID, empresaId);
					}
					
					ResultSet rs = stmt.executeQuery();
					rs.setFetchSize(500);

					lsDadosRelatorio = new ArrayList<>();
					
					Integer puntoventaIdAux = null;
					Integer empresaIdAux = null;
					BigDecimal pendente = BigDecimal.ZERO;
					BigDecimal totalFechamento = BigDecimal.ZERO;
					Date dtMotivo = null;
					Long fechamentocntcorrenteId = null;
					boolean isBoletoQuitado = false;

					while (rs.next()) {
						RelatorioDepositoBean deposito = new RelatorioDepositoBean();
						deposito.setNombempresa(rs.getString("nombempresa"));
						deposito.setNombpuntoventa(rs.getString("nombpuntoventa"));
						deposito.setNumpuntoventa(rs.getString("numpuntoventa"));
						deposito.setDtmotivo(rs.getDate("dtmotivo"));
						deposito.setVrfechamento(rs.getBigDecimal("vrfechamento"));
						deposito.setSaldo(rs.getBigDecimal("saldo").multiply(BigDecimal.valueOf(-1)));
						deposito.setEmpresaId(rs.getInt(EMPRESA_ID));
						deposito.setPuntoventaId(rs.getInt(PUNTOVENTA_ID));
						isBoletoQuitado = "1".equals(rs.getString("indboletoquitado")) ? true : false;
						
						if (isBoletoQuitado) {
							deposito.setVrdeposito(rs.getBigDecimal("valordocumento"));	
						} else {
							deposito.setVrdeposito(rs.getBigDecimal("vlrBoletoDeposito"));	
						}
						
						if (! filtrarPendentes){
							deposito.setNumdeposito(rs.getString("numdeposito"));
						}
												
						boolean isPontoVendaEmpresaDiferente = (puntoventaIdAux == null || !puntoventaIdAux.equals(deposito.getPuntoventaId())) ||
								   							   (empresaIdAux == null || !empresaIdAux.equals(deposito.getEmpresaId()));
						
						if(fechamentocntcorrenteId == null) {
							fechamentocntcorrenteId = rs.getLong(FECHAMENTOCNTCORRENTE_ID);
						} if(!isPontoVendaEmpresaDiferente && dtMotivo != null && DateUtil.compareOnlyDate(dtMotivo, deposito.getDtmotivo()) == 0 && !fechamentocntcorrenteId.equals(rs.getLong(FECHAMENTOCNTCORRENTE_ID))) {
							pendente = deposito.getVrfechamento();
							totalFechamento = totalFechamento.add(deposito.getVrfechamento());
							fechamentocntcorrenteId = rs.getLong(FECHAMENTOCNTCORRENTE_ID);
						}
						
						if(isPontoVendaEmpresaDiferente || (dtMotivo == null || DateUtil.compareOnlyDate(dtMotivo, deposito.getDtmotivo()) != 0)) {
							
							if(isPontoVendaEmpresaDiferente) {
								puntoventaIdAux = deposito.getPuntoventaId();
								empresaIdAux = deposito.getEmpresaId();
								pendente = deposito.getVrfechamento();
								dtMotivo = deposito.getDtmotivo();
								totalFechamento = totalFechamento.add(deposito.getVrfechamento());
								fechamentocntcorrenteId = rs.getLong(FECHAMENTOCNTCORRENTE_ID);
							}

							if(dtMotivo == null || DateUtil.compareOnlyDate(dtMotivo, deposito.getDtmotivo()) != 0) {
								pendente = deposito.getVrfechamento();
								totalFechamento = totalFechamento.add(deposito.getVrfechamento());
								fechamentocntcorrenteId = rs.getLong(FECHAMENTOCNTCORRENTE_ID);
							}
							dtMotivo = deposito.getDtmotivo();
						}
						
						pendente = pendente.subtract(deposito.getVrdeposito());
						deposito.setVrpendente(pendente);
						deposito.setDataDepositoFechamento(rs.getDate("fecha_deposito"));
						
						lsDadosRelatorio.add(deposito);
					}

					if (!lsDadosRelatorio.isEmpty()) {
						setLsDadosRelatorio(lsDadosRelatorio);
					}
					parametros.put("totalFechamento", totalFechamento);
					setNomeSubReporte(nomeSubReporte);
				}

			});
		} catch (Exception e) {
			log.error("", e);
		}
	}

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

	@Override
	protected void processaParametros() throws Exception {
	}

	private String getSQL(Integer puntoVentaId, Integer empresaId, boolean filtrarPendentes) {

		StringBuilder sql = new StringBuilder();
		
		sql.append(" SELECT DISTINCT tmp.nombempresa, ");
		sql.append("   tmp.nombpuntoventa, ");
		sql.append("   tmp.numpuntoventa, ");
		sql.append("   tmp.dtmotivo, ");
		sql.append("   tmp.saldo, ");
		sql.append("   tmp.vrfechamento, ");
		sql.append("   tmp.valordocumento, ");
		sql.append("   tmp.indboletoquitado, ");
		sql.append("   tmp.fechamentocntcorrenteId, ");
		
		if (! filtrarPendentes){
			sql.append("   tmp.numdeposito, ");
		} 

		sql.append("   tmp.vlrBoletoDeposito, ");	
		sql.append("   tmp.puntoventaId, ");
		sql.append("   tmp.empresaId, ");
		sql.append("   tmp.fecha_deposito ");
		sql.append(" FROM ");
		sql.append("   ( SELECT DISTINCT e.nombempresa, ");
		sql.append("     p.nombpuntoventa, ");
		sql.append("     p.numpuntoventa, ");
		sql.append("     p.puntoventa_id as puntoventaId, ");
		sql.append("     e.empresa_id as empresaId, ");
		sql.append("     f.fecfechamento as dtmotivo, ");
		sql.append("     ( SUM(COALESCE(fd.valor_pago,0)) - f.total ) AS saldo, ");
		sql.append("     SUM(COALESCE(fd.valor_pago,0))    AS vlrBoletoDeposito, ");
		sql.append("     f.total as vrfechamento, ");
		sql.append("	 fb.indboletoquitado,  ");
		sql.append("     fb.valordocumento,  ");
		
		if (! filtrarPendentes){
			sql.append("     fdp.NUMDEPOSITO as numdeposito, ");
		}
		sql.append("     fdp.fecha_deposito, ");
		sql.append("     f.FECHAMENTOCNTCORRENTE_ID as fechamentocntcorrenteId ");
		sql.append("   FROM fechamento_cntcorrente f ");
		sql.append("   INNER JOIN punto_venta p ");
		sql.append("      ON p.puntoventa_id = f.puntoventa_id ");
		sql.append("      AND p.activo = 1 ");
		sql.append("   INNER JOIN empresa e ");
		sql.append("      ON e.empresa_id = f.empresa_id ");
		sql.append("      AND e.activo = 1 ");
		sql.append("   LEFT JOIN fechamento_cct_deposito fd ");
		sql.append("      ON fd.fechamentocntcorrente_id = f.fechamentocntcorrente_id ");
		sql.append("      AND fd.activo = 1 ");
		sql.append("   LEFT JOIN FECHAMENTO_DEPOSITO fdp ");
		sql.append("      ON fdp.FECHAMENTODEPOSITO_ID = fd.FECHAMENTODEPOSITO_ID ");
		sql.append("      AND fdp.activo = 1 ");		
		sql.append("   INNER JOIN fechamento_boleto fb ");
		sql.append("      ON f.fechamentocntcorrente_id = fb.fechamentocntcorrente_id ");
		sql.append("   WHERE f.fecfechamento BETWEEN :fecInicio AND :fecFinal ");
		sql.append("     AND f.activo = 1 ");
		sql.append("     AND fb.tipo_pagamento = 'D' ");
		
		if(puntoVentaId != null && puntoVentaId != -1) {
			sql.append("   AND f.puntoventa_id = :puntoventaId ");
		}
		
		if(empresaId != null) {
			sql.append("   AND e.empresa_id = :empresaId ");
		}
		sql.append(" GROUP BY e.nombempresa,  ");
		sql.append("   p.nombpuntoventa,  ");
		sql.append("   p.numpuntoventa,  ");
		sql.append("   p.puntoventa_id, ");
		sql.append("   e.empresa_id, ");
		sql.append("   f.fecfechamento,  ");
		sql.append("   f.FECHAMENTOCNTCORRENTE_ID,  ");
		sql.append("   fdp.fecha_deposito, ");
		if (!filtrarPendentes){
			sql.append("   fdp.NUMDEPOSITO, ");
		}
		sql.append("	fb.indboletoquitado, ");
		sql.append("	fb.valordocumento, ");
		sql.append("	f.total ) tmp ");
		
		if (filtrarPendentes){
			sql.append(" where ");
			sql.append(" tmp.saldo < tmp.vlrBoletoDeposito and tmp.saldo <> 0");
		}
		sql.append(" ORDER BY tmp.nombempresa,  ");
		sql.append("   tmp.nombpuntoventa,  ");
		sql.append("   tmp.dtmotivo, ");
		sql.append("   tmp.vlrBoletoDeposito,  ");
		sql.append("   tmp.puntoventaId, ");
		sql.append("   tmp.empresaId ");		
		return sql.toString();
	}
}
