package com.rjconsultores.ventaboletos.relatorios.impl;

import java.sql.Connection;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
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.log4j.Logger;

import com.rjconsultores.ventaboletos.relatorios.utilitarios.DataSource;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.RelatorioVendasPacotesBoletosBean;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.RelatorioVendasPacotesBoletosBean.RelatorioVendasPacotesBoletosItemBean;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

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

	private SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
	
	private List<RelatorioVendasPacotesBoletosBean> lsDadosRelatorio;
	
	private Date fecInicio;
	private Date fecFinal;
	private Integer empresaId;
	private Integer origenId;
	private Integer destinoId;
	private Integer usuarioId;
	private Integer tipoTarifaPacoteId;
	
	public RelatorioVendasPacotesBoletos(Map<String, Object> parametros, Connection conexao, final String... nomeSubReporte) throws Exception {
		super(parametros, conexao);
		
		this.setCustomDataSource(new DataSource(this) {


			@Override
			public void initDados() throws Exception {
				Map<String, Object> parametros = this.relatorio.getParametros();
				fecInicio = new java.sql.Date(sdf.parse(parametros.get("fecInicio").toString()).getTime());
				fecFinal = new java.sql.Date(sdf.parse(parametros.get("fecFinal").toString()).getTime());
				empresaId = parametros.get("empresaId") != null && !parametros.get("empresaId").equals("null") ? Integer.valueOf(parametros.get("empresaId").toString()) : null;
				origenId = parametros.get("origenId") != null && !parametros.get("origenId").equals("null") ? Integer.valueOf(parametros.get("origenId").toString()) : null;
				destinoId = parametros.get("destinoId") != null && !parametros.get("destinoId").equals("null") ? Integer.valueOf(parametros.get("destinoId").toString()) : null;
				usuarioId = parametros.get("usuarioId") != null && !parametros.get("usuarioId").equals("null") ? Integer.valueOf(parametros.get("usuarioId").toString()) : null;
				tipoTarifaPacoteId = parametros.get("tipoTarifaPacoteId") != null && !parametros.get("tipoTarifaPacoteId").equals("null") ? Integer.valueOf(parametros.get("tipoTarifaPacoteId").toString()) : null;
				
				Connection conexao = this.relatorio.getConexao();
				processarVendasPacote(conexao);
				processarVendasPacoteCancelados(conexao);
				processarVendasPacoteTotais();
				
				setNomeSubReporte(nomeSubReporte);
				setLsDadosRelatorio(lsDadosRelatorio);
			}

		});
	}
	
	private void processarVendasPacote(Connection conexao) {
		ResultSet rset = null;
		NamedParameterStatement stmt = null;
		
		try {
			stmt = carregarNamedParameterStatement(conexao, false);
			rset = stmt.executeQuery();
	
			if(lsDadosRelatorio == null) {
				lsDadosRelatorio = new ArrayList<RelatorioVendasPacotesBoletosBean>();
			}
			
			while (rset.next()) {
				RelatorioVendasPacotesBoletosBean relatorioVendasBoletosBean = carregarRelatorioVendasBoletosBean(rset);
				Integer idx = carregarIndice(relatorioVendasBoletosBean);
				
				if(idx != null) {
					relatorioVendasBoletosBean = lsDadosRelatorio.get(idx); 
				}
				
				relatorioVendasBoletosBean.setRelatorioVendasPacotesBoletosItemBeans(carregarItens(rset, relatorioVendasBoletosBean, relatorioVendasBoletosBean.getRelatorioVendasPacotesBoletosItemBeans()));
				
				if(idx != null) {
					lsDadosRelatorio.set(idx, relatorioVendasBoletosBean);
				} else {
					lsDadosRelatorio.add(relatorioVendasBoletosBean);
				}
			}
			
		} 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 List<RelatorioVendasPacotesBoletosBean.RelatorioVendasPacotesBoletosItemBean> carregarItens(ResultSet rset, RelatorioVendasPacotesBoletosBean relatorioVendasPacotesBoletosBean, List<RelatorioVendasPacotesBoletosBean.RelatorioVendasPacotesBoletosItemBean> itens) throws SQLException {
		RelatorioVendasPacotesBoletosBean.RelatorioVendasPacotesBoletosItemBean relatorioVendasPacotesBoletosItemBean = relatorioVendasPacotesBoletosBean.new RelatorioVendasPacotesBoletosItemBean();
		relatorioVendasPacotesBoletosItemBean.setNomconvenio(rset.getString("nomconvenio"));
		relatorioVendasPacotesBoletosItemBean.setDesctipotarifa(rset.getString("desctipotarifa"));
		relatorioVendasPacotesBoletosItemBean.setQtde(rset.getLong("qtde"));
		relatorioVendasPacotesBoletosItemBean.setSimportetaxaembarque(rset.getBigDecimal("simportetaxaembarque"));
		relatorioVendasPacotesBoletosItemBean.setSimportepedagio(rset.getBigDecimal("simportepedagio"));
		relatorioVendasPacotesBoletosItemBean.setSimporteoutros(rset.getBigDecimal("simporteoutros"));
		relatorioVendasPacotesBoletosItemBean.setSimporteseguro(rset.getBigDecimal("simporteseguro"));
		relatorioVendasPacotesBoletosItemBean.setSpreciobase(rset.getBigDecimal("spreciobase"));
		relatorioVendasPacotesBoletosItemBean.setDesconto(rset.getBigDecimal("desconto"));
		
		if(itens == null) {
			itens = new ArrayList<RelatorioVendasPacotesBoletosBean.RelatorioVendasPacotesBoletosItemBean>();
		}
		itens.add(relatorioVendasPacotesBoletosItemBean);
		
		return itens;
	}

	private Integer carregarIndice(RelatorioVendasPacotesBoletosBean relatorioVendasBoletosBean) {
		Integer idx = null;
		if(lsDadosRelatorio.contains(relatorioVendasBoletosBean)) {
			idx = lsDadosRelatorio.indexOf(relatorioVendasBoletosBean);
			relatorioVendasBoletosBean = lsDadosRelatorio.get(idx);
		}
		return idx;
	}

	private RelatorioVendasPacotesBoletosBean carregarRelatorioVendasBoletosBean(ResultSet rset) throws SQLException {
		RelatorioVendasPacotesBoletosBean relatorioVendasPacotesBoletosBean = new RelatorioVendasPacotesBoletosBean();
		relatorioVendasPacotesBoletosBean.setDescdestino(rset.getString("destino"));
		relatorioVendasPacotesBoletosBean.setDescorigen(rset.getString("origem"));
		relatorioVendasPacotesBoletosBean.setCvedestino(rset.getString("cvedestino"));
		relatorioVendasPacotesBoletosBean.setCveorigen(rset.getString("cveorigem"));
		/*relatorioVendasPacotesBoletosBean.setTotais(new ArrayList<RelatorioVendasPacotesBoletosBean.RelatorioVendasPacotesBoletosItemTotaisBean>());
		relatorioVendasPacotesBoletosBean.getTotais().add(relatorioVendasPacotesBoletosBean.new RelatorioVendasPacotesBoletosItemTotaisBean("CWB-MOR","ADULTO",2));
		relatorioVendasPacotesBoletosBean.getTotais().add(relatorioVendasPacotesBoletosBean.new RelatorioVendasPacotesBoletosItemTotaisBean("CWB-MOR","CHD",2));
		relatorioVendasPacotesBoletosBean.getTotais().add(relatorioVendasPacotesBoletosBean.new RelatorioVendasPacotesBoletosItemTotaisBean("MOR-CWB","SEGURO",2));*/
		
		return relatorioVendasPacotesBoletosBean;
	}

	private void processarVendasPacoteCancelados(Connection conexao) {
		ResultSet rset = null;
		NamedParameterStatement stmt = null;
		
		try {
			stmt = carregarNamedParameterStatement(conexao, true);
			rset = stmt.executeQuery();
	
			if(lsDadosRelatorio == null) {
				lsDadosRelatorio = new ArrayList<RelatorioVendasPacotesBoletosBean>();
			}
			
			while (rset.next()) {
				RelatorioVendasPacotesBoletosBean relatorioVendasBoletosBean = carregarRelatorioVendasBoletosBean(rset);
				Integer idx = carregarIndice(relatorioVendasBoletosBean);
				
				if(idx != null) {
					relatorioVendasBoletosBean = lsDadosRelatorio.get(idx); 
				}
				
				relatorioVendasBoletosBean.setRelatorioVendasPacotesBoletosItemBeansCancelados(carregarItens(rset, relatorioVendasBoletosBean, relatorioVendasBoletosBean.getRelatorioVendasPacotesBoletosItemBeansCancelados()));
				
				if(idx != null) {
					lsDadosRelatorio.set(idx, relatorioVendasBoletosBean);
				} else {
					lsDadosRelatorio.add(relatorioVendasBoletosBean);
				}
			}
			
		} 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 NamedParameterStatement carregarNamedParameterStatement(Connection conexao, boolean cancelados) throws SQLException {
		String sql = getSqlPacotes(cancelados);
		log.info(sql);
		
		NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql);
		
		if(fecInicio != null) {
			stmt.setDate("fecInicio", fecInicio);
		}
		if(fecFinal != null) {
			stmt.setDate("fecFinal", fecFinal);
		}
		if (empresaId != null){
			stmt.setInt("empresaId", empresaId);
		}
		if(origenId != null) {
			stmt.setInt("origenId", origenId);
		}
		if(destinoId != null) {
			stmt.setInt("destinoId", destinoId);
		}
		if(usuarioId != null) {
			stmt.setInt("usuarioId", usuarioId);
		}
		if(tipoTarifaPacoteId != null && tipoTarifaPacoteId > 0) {
			stmt.setInt("tipoTarifaPacoteId", tipoTarifaPacoteId);
		}
		
		return stmt;
	}

	protected String getSqlPacotes(boolean cancelado) {
		StringBuilder sQuery = new StringBuilder();
		
		sQuery.append("SELECT DES.CVEPARADA AS CVEDESTINO, ORI.CVEPARADA AS CVEORIGEM, ORI.DESCPARADA AS ORIGEM, DES.DESCPARADA AS DESTINO, TVP.NOMCONVENIO, TTP.DESCTIPOTARIFA, ")
			  .append("COUNT(TVP.TARIFAVENDAPACOTE_ID) AS QTDE, SUM(B.IMPORTETAXAEMBARQUE) AS SIMPORTETAXAEMBARQUE, SUM(B.IMPORTEPEDAGIO) AS SIMPORTEPEDAGIO, ")
			  .append("SUM(B.IMPORTEOUTROS) AS SIMPORTEOUTROS, SUM(B.IMPORTESEGURO) AS SIMPORTESEGURO, SUM(B.PRECIOBASE) AS SPRECIOBASE, SUM(B.PRECIOBASE - B.PRECIOPAGADO) AS DESCONTO ")
			  .append("FROM VENDA_PACOTE VP ")
			  .append("LEFT JOIN PACOTE P ON P.PACOTE_ID = VP.PACOTE_ID ")
			  .append("LEFT JOIN TARIFA_VENDA_PACOTE TVP ON TVP.VENDAPACOTE_ID = VP.VENDAPACOTE_ID ")
			  .append("LEFT JOIN BOLETO B ON B.BOLETO_ID = TVP.BOLETO_ID ")
			  .append("LEFT JOIN PACOTE_TARIFA PT ON PT.PACOTETARIFA_ID = TVP.PACOTETARIFA_ID ")
			  .append("LEFT JOIN TIPO_TARIFA_PACOTE TTP ON TTP.TIPOTARIFAPACOTE_ID = PT.TIPOTARIFAPACOTE_ID ")
			  .append("LEFT JOIN PARADA ORI ON ORI.PARADA_ID = B.ORIGEN_ID ")
			  .append("LEFT JOIN PARADA DES ON DES.PARADA_ID = B.DESTINO_ID ")
			  .append("WHERE P.ACTIVO = 1 ")
			  .append("AND B.ACTIVO = 1 ");
		
		if(!cancelado) {
			sQuery.append("AND B.INDSTATUSBOLETO = 'V' ")
			  	  .append("AND B.MOTIVOCANCELACION_ID IS NULL ");
		} else {
			sQuery.append("AND B.MOTIVOCANCELACION_ID IS NOT NULL ");
		}
		
		if(empresaId != null) {
			sQuery.append("AND P.EMPRESA_ID = :empresaId ");
		}

		if(origenId != null) {
			sQuery.append("AND B.ORIGEN_ID = :origenId ");
		}
		
		if(destinoId != null) {
			sQuery.append("AND B.DESTINO_ID = :destinoId ");
		}

		if(usuarioId != null) {
			sQuery.append("AND VP.USUARIO_ID = :usuarioId ");
		}

		if(tipoTarifaPacoteId != null && tipoTarifaPacoteId > 0) {
			sQuery.append("AND TTP.TIPOTARIFAPACOTE_ID = :tipoTarifaPacoteId ");
		}

		if(fecInicio != null) {
			sQuery.append("AND VP.DATAVENDA >= :fecInicio ");
		}
		
		if(fecFinal != null) {
			sQuery.append("AND VP.DATAVENDA <= :fecFinal ");
		}
		
		sQuery.append("GROUP BY DES.CVEPARADA,ORI.CVEPARADA,ORI.DESCPARADA,DES.DESCPARADA,TVP.NOMCONVENIO,TTP.DESCTIPOTARIFA ")
			  .append("ORDER BY DES.CVEPARADA,ORI.CVEPARADA,ORI.DESCPARADA,DES.DESCPARADA,TVP.NOMCONVENIO,TTP.DESCTIPOTARIFA ");
		
		return sQuery.toString();
	}
	
	private void processarVendasPacoteTotais() {
		List<RelatorioVendasPacotesBoletosBean.RelatorioVendasPacotesBoletosItemTotaisBean> totais = new ArrayList<RelatorioVendasPacotesBoletosBean.RelatorioVendasPacotesBoletosItemTotaisBean>();
		for (RelatorioVendasPacotesBoletosBean relatorioVendasPacotesBoletosBean : lsDadosRelatorio) {
			for (RelatorioVendasPacotesBoletosItemBean item : relatorioVendasPacotesBoletosBean.getRelatorioVendasPacotesBoletosItemBeans()) {
				RelatorioVendasPacotesBoletosBean.RelatorioVendasPacotesBoletosItemTotaisBean total = relatorioVendasPacotesBoletosBean.new RelatorioVendasPacotesBoletosItemTotaisBean();
				total.setTrecho(relatorioVendasPacotesBoletosBean.getCveorigen()+"-"+relatorioVendasPacotesBoletosBean.getCvedestino());
				total.setCategoria(item.getDesctipotarifa());
				total.setQtde(0l);
				Integer idx = null;
				if(totais.contains(total)) {
					idx = totais.indexOf(total);
					total = totais.get(idx);
				}
				total.setQtde(total.getQtde() + item.getQtde());
				
				if(idx == null) {
					totais.add(total);
				} else {
					totais.set(idx, total);
				}
			}
		}
		this.parametros.put("totais", totais);
	}

	@Override
	protected void processaParametros() throws Exception {
	}
	
	public List<RelatorioVendasPacotesBoletosBean> getLsDadosRelatorio() {
		return lsDadosRelatorio;
	}

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

}
