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.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

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

public class RelatorioSegundaVia extends Relatorio {

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

	public RelatorioSegundaVia(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("numfoliosistema"));
				r.setDataVenda(rset.getTimestamp("dataVenda"));
				r.setDataViagem(rset.getDate("dataViagem"));
				r.setDataServico(rset.getDate("dataServico"));
				r.setDataSegundaVia(rset.getDate("dataSegundaVia"));
				r.setHoraServico(DateUtil.getStringDate(rset.getDate("dataViagem"), "HH:mm"));
				r.setDestino(rset.getString("destino"));
				r.setOrigem(rset.getString("origem"));
				r.setDescDestino(rset.getString("descDestino"));
				r.setDescOrigem(rset.getString("descOrigem"));
				r.setPedagio(rset.getBigDecimal("pedagio"));
				r.setPoltrona(rset.getString("poltrona"));
				r.setSeguro(rset.getBigDecimal("seguro"));
				r.setSerieImpFiscalSegundaVia(rset.getString("serieImpFiscalSegundaVia")); 
				r.setSerieImpFiscal(rset.getString("serieImpFiscal"));
				r.setServico(rset.getString("servico"));
				r.setTaxa(rset.getBigDecimal("taxa"));
				r.setTarifa(rset.getBigDecimal("tarifa"));
				r.setNomeEmpresa(rset.getString("nomeEmpresa"));
				r.setNomeAgencia(rset.getString("nomeAgencia"));
				r.setLinha(rset.getString("linha")); 
				r.setCcf(rset.getString("ccf"));
				r.setTpp(rset.getBigDecimal("tpp"));
				r.setSiglaTipoPassagem(rset.getString("siglaTipoPassagem"));
				r.setTipoPassagem(rset.getString("tipoPassagem")); 
				r.setValorTotal(rset.getBigDecimal("valortotal"));
				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 distinct c.caja_id, ");
		sql.append("e.nombempresa as nomeEmpresa, ");
		sql.append("pt.nombpuntoventa as nomeAgencia, ");
		sql.append("usuario.nombusuario as bilheteiro, ");
		sql.append("case when c.motivoreimpresion_id = 99 then b.fecsegundavia else null end as dataSegundaVia,");
		sql.append("c.fechorventa as dataVenda, ");
		sql.append("c.feccorrida as  dataServico,");
		sql.append("c.fechorviaje as dataViagem, ");
		sql.append("c.corrida_id as servico, ");
		sql.append("r.descruta as linha, ");
		sql.append("po.cveparada as origem, ");
		sql.append("pd.cveparada as destino,");
		sql.append("po.descparada as descOrigem, ");
		sql.append("pd.descparada as descDestino, ");
		sql.append("c.numasiento as poltrona, ");
		sql.append("(select cc.serieimpfiscal from caja cc where cc.transacao_id = b.boleto_id  and cc.motivoreimpresion_id is null ) as serieImpFiscal,");
		sql.append("c.serieimpfiscal as serieImpFiscalSegundaVia, ");
		sql.append("c.numfoliosistema, ");
		sql.append("(select cc.ccf from caja cc where cc.transacao_id = b.boleto_id  and cc.motivoreimpresion_id is null ) as ccf, ");
		sql.append("ca.cvecategoria as siglaTipoPassagem,");
		sql.append("ca.desccategoria as tipoPassagem,");
		sql.append("(select sum(cfpv.importe) from caja_formapago cfpv where cfpv.caja_id = c.caja_id and cfpv.activo = 1) as valortotal,");
		sql.append("c.preciopagado as tarifa, ");
		sql.append("c.importeseguro as seguro, ");
		sql.append("c.importepedagio as pedagio, ");
		sql.append("c.importetaxaembarque as taxa, ");
		sql.append("c.importetpp as tpp, ");
		sql.append("c.num_bpe as numBpe ");
		sql.append("from caja c ");
		sql.append("inner join boleto b on (c.transacao_id = b.boleto_id)");
		sql.append("inner join usuario usuario on c.usuario_id = usuario.usuario_id ");
		sql.append("left join fiscal_impressora fi on fi.numserie = c.serieimpfiscaloriginal  ");
		sql.append("left join fiscal_r4 r4 on r4.numserie20 = fi.numserie20 and r4.contador = c.ccf ");
		sql.append("inner join empresa e on e.empresa_id = c.empresacorrida_id ");
		sql.append("inner join categoria ca on c.categoria_id = ca.categoria_id ");
		sql.append("inner join ruta r on r.ruta_id = c.ruta_id ");
		sql.append("inner join parada po on po.parada_id = c.origen_id ");
		sql.append("inner join parada pd on pd.parada_id = c.destino_id ");
		sql.append("inner join punto_venta pt on pt.puntoventa_id = c.puntoventa_id ");
		
		
		sql.append("where b.indsegundaviaimpressa = 1 and c.motivoreimpresion_id = 99  ");
		if (dataInicial != null && dataFinal != null) {
			sql.append(" and b.fecsegundavia between :dataInicial and :dataFinal");
		}
		if (empresaId != null && empresaId != -1) {
			sql.append(" and c.empresacorrida_id = " + empresaId);
		}
		if (puntoVentaId != null && puntoVentaId != -1) {
			sql.append(" and c.puntoventa_id = " + puntoVentaId);
		}
		sql.append(" order by c.numfoliosistema, c.caja_id " );
		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());
	}

}
