package com.rjconsultores.ventaboletos.relatorios.impl;

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

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

public class RelatorioSegundaViaBoleto extends Relatorio {

	private static Logger log = LogManager.getLogger(RelatorioSegundaVia.class);
	private SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
	private List<RelatorioSegundaViaBean> lsDadosRelatorio;

	public RelatorioSegundaViaBoleto(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();

				Date dataInicial = (Date) parametros.get("dataInicial");
				Date dataFinal = (Date) parametros.get("dataFinal");
				Integer empresaId = (Integer) parametros.get("empresaId");
				Integer puntoVentaId = (Integer) parametros.get("puntoVentaId");

				String sql = getSqlDados(dataInicial, dataFinal, empresaId, puntoVentaId);
				ResultSet rset = null;
				NamedParameterStatement stmt = null;
				Connection conexao = this.relatorio.getConexao();

				stmt = new NamedParameterStatement(conexao, sql);
				stmt.setTimestamp("dataInicial", getDataHoraInicial(dataInicial));
				stmt.setTimestamp("dataFinal", getDataHoraFinal(dataFinal));
				
				parametros.put("dataInicial", sdf.format(dataInicial));
				parametros.put("dataFinal", sdf.format(dataFinal));
				try {
					rset = stmt.executeQuery();

					lsDadosRelatorio = new ArrayList<RelatorioSegundaViaBean>();
					while (rset.next()) {
						lsDadosRelatorio.add(criarRelatorioSegundaViaBean(rset));
					}
					setCollectionDataSource(new JRBeanCollectionDataSource(lsDadosRelatorio));
				} catch (Exception e) {
					log.error(e.getMessage(), e);
				} finally {
					try {
						if (rset != null) {
							rset.close();
						}
						if (stmt != null) {
							stmt.close();
						}
					} catch (SQLException e) {
						log.error(e.getMessage(), e);
					}
				}
			}

			private RelatorioSegundaViaBean criarRelatorioSegundaViaBean(ResultSet rset) throws SQLException {
				RelatorioSegundaViaBean r = new RelatorioSegundaViaBean();
				r.setBilheteiro(rset.getString("bilheteiro"));
				r.setBilhete(rset.getString("bilhete"));
				r.setCoo(rset.getInt("coo") == 0 ? null : rset.getInt("coo"));
				r.setDataVenda(rset.getTimestamp("dataVenda"));
				r.setDataViagem(rset.getDate("dataViagem"));
				r.setDestino(rset.getString("destino"));
				r.setOrigem(rset.getString("origem"));
				r.setPedagio(rset.getBigDecimal("pedagio"));
				r.setPoltrona(rset.getString("poltrona"));
				r.setPreImpresso(rset.getString("preImpresso"));
				r.setPuntoVenta(rset.getInt("puntoVenta"));
				r.setSeguro(rset.getBigDecimal("seguro"));
				r.setSerieImpFiscal(rset.getString("serieImpFiscal"));
				r.setServico(rset.getString("servico"));
				r.setTaxa(rset.getBigDecimal("taxa"));
				r.setTarifa(rset.getBigDecimal("tarifa"));
				r.setNumBpe(rset.getString("numBpe"));
				return r;
			}
		});
	}

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

	private String getSqlDados(Date dataInicial, Date dataFinal, Integer empresaId, Integer puntoVentaId) {
		StringBuilder sql = new StringBuilder();
		sql.append("SELECT boleto.CORRIDA_ID AS servico, ");
		sql.append("boleto.FECHORVIAJE AS dataViagem, ");
		sql.append("ori.CVEPARADA AS origem, ");
		sql.append("des.CVEPARADA AS destino, ");
		sql.append("boleto.NUMASIENTO AS poltrona, ");
		sql.append("boleto.FECHORVENTA AS dataVenda, ");
		sql.append("boleto.NUMFOLIOSISTEMA AS bilhete, ");
		sql.append("usuario.NOMBUSUARIO AS bilheteiro, ");
		sql.append("boleto.PUNTOVENTA_ID AS puntoVenta, ");
		sql.append("boleto.PRECIOPAGADO AS tarifa, ");
		sql.append("boleto.IMPORTETAXAEMBARQUE AS taxa, ");
		sql.append("boleto.IMPORTESEGURO AS seguro, ");
		sql.append("boleto.IMPORTEPEDAGIO AS pedagio, ");
		sql.append("r4.COO AS coo, ");
		sql.append("boleto.NUMFOLIOPREIMPRESO AS preimpresso, ");
		sql.append("boleto.NUMSERIEPREIMPRESA AS seriePreImpresso, ");
		sql.append("boleto.SERIEIMPFISCAL AS serieImpFiscal, ");
		sql.append("boleto.NUM_BPE AS numBpe ");

		sql.append("FROM BOLETO boleto ");
		sql.append("INNER JOIN USUARIO usuario ON boleto.USUARIO_ID = usuario.USUARIO_ID ");
		sql.append("left join fiscal_impressora fi on fi.numserie = boleto.SERIEIMPFISCALORIGINAL  ");
		sql.append("left join fiscal_r4 r4 on r4.NUMSERIE20 = fi.NUMSERIE20 and r4.CONTADOR = boleto.CCF ");
		sql.append("inner join parada ori on ori.parada_id = boleto.origen_id ");
		sql.append("inner join parada des on des.parada_id = boleto.destino_id ");
		sql.append("WHERE boleto.INDSEGUNDAVIAIMPRESSA = 1 ");
		if (dataInicial != null && dataFinal != null) {
			sql.append(" AND boleto.FECSEGUNDAVIA BETWEEN :dataInicial AND :dataFinal");
		}
		if (empresaId != null && empresaId != -1) {
			sql.append(" AND boleto.EMPRESACORRIDA_ID = " + empresaId);
		}
		if (puntoVentaId != null && puntoVentaId != -1) {
			sql.append(" AND boleto.PUNTOVENTA_ID = " + puntoVentaId);
		}

		return sql.toString();
	}

	@Override
	protected void processaParametros() throws Exception {

	}

	private Timestamp getDataHoraInicial(Date dataInicial) {
		Calendar calendar = Calendar.getInstance();

		calendar.setTime(dataInicial);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);

		return new Timestamp(calendar.getTime().getTime());
	}

	private Timestamp getDataHoraFinal(Date dataFinal) {
		Calendar calendar = Calendar.getInstance();

		calendar.setTime(dataFinal);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);

		return new Timestamp(calendar.getTime().getTime());
	}

}
