package com.rjconsultores.ventaboletos.relatorios.impl;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

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

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.rjconsultores.ventaboletos.constantes.Constantes;
import com.rjconsultores.ventaboletos.enums.LocalEnderecoApanhe;
import com.rjconsultores.ventaboletos.enums.SituacaoVendaPacote;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.DataSource;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.pacote.PacoteItemAdicionalVoucher;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.pacote.PacoteTarifaVoucher;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.pacote.PacoteVoucher;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

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

	private List<PacoteVoucher> lsPacoteVoucher;
	
	private Long vendapacoteId;
	
	public RelatorioVendaPacoteVoucher(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();
				vendapacoteId = parametros.get("vendapacoteId") != null && !parametros.get("vendapacoteId").equals("null") ? Long.valueOf(parametros.get("vendapacoteId").toString()) : null;
				
				Connection conexao = this.relatorio.getConexao();
				processarVendaPacoteVoucher(conexao);
				
				setNomeSubReporte(nomeSubReporte);
				setLsDadosRelatorio(lsPacoteVoucher);
			}
		});
	}
	
	private void processarVendaPacoteVoucher(Connection conexao) {
		PacoteVoucher pacoteVoucher = carregarDadosPacoteVoucher(conexao);
		
		lsPacoteVoucher = new ArrayList<PacoteVoucher>();
		lsPacoteVoucher.add(pacoteVoucher);
	}
	
	private PacoteVoucher carregarDadosPacoteVoucher(Connection conexao) {
		ResultSet rset = null;
		NamedParameterStatement stmt = null;
		try {
			StringBuilder sQuery = new StringBuilder("SELECT VP.DATAPACOTE,VP.DATAVENDA,VP.SUBTOTAL,VP.TOTAL,VP.DESCONTO,VP.NUMOPERACION,P.NOMPACOTE,P.DESCPACOTE,E.NOMBEMPRESA,VP.SITUACAO ");
			sQuery.append("FROM VENDA_PACOTE VP ")
				  .append("JOIN PACOTE P ON P.PACOTE_ID = VP.PACOTE_ID ")
				  .append("JOIN EMPRESA E ON E.EMPRESA_ID = P.EMPRESA_ID ")
				  .append("WHERE VP.VENDAPACOTE_ID = :vendapacoteId ")
				  .append("AND VP.MOTIVOCANCELVENDAPACOTE_ID IS NULL ");
			log.info(sQuery);
			stmt = new NamedParameterStatement(conexao, sQuery.toString());
			stmt.setLong("vendapacoteId", vendapacoteId);
			rset = stmt.executeQuery();
		
			while (rset.next()) {
				PacoteVoucher pacoteVoucher = new PacoteVoucher();
				pacoteVoucher.setDatapacote(rset.getDate("datapacote"));
				pacoteVoucher.setDatavenda(rset.getDate("datavenda"));
				pacoteVoucher.setSubTotal(rset.getBigDecimal("subtotal"));
				pacoteVoucher.setTotal(rset.getBigDecimal("total"));
				pacoteVoucher.setDesconto(rset.getBigDecimal("desconto"));
				pacoteVoucher.setNumoperacion(rset.getString("numoperacion"));
				pacoteVoucher.setNomePacote(rset.getString("nompacote"));
				pacoteVoucher.setDescPacote(rset.getString("descpacote"));
				pacoteVoucher.setNombempresa(rset.getString("nombempresa"));
				pacoteVoucher.setSituacaoVendaPacote(SituacaoVendaPacote.getSituacaoVendaPacote(rset.getInt("situacao")));
				
				carregarPacoteItem(conexao, pacoteVoucher);
				carregarEnderecoApanhe(conexao, pacoteVoucher);
				carregarClientePacote(conexao, pacoteVoucher);
				carregarTarifaVendaPacote(conexao, pacoteVoucher);
				carregarFormaPago(conexao, pacoteVoucher);
				
				return pacoteVoucher;
			}
			
		} 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);
			}
		}
		return null;
	}

	private void carregarPacoteItem(Connection conexao, PacoteVoucher pacoteVoucher) {
		ResultSet rset = null;
		NamedParameterStatement stmt = null;
		try {
			StringBuilder sQuery = new StringBuilder();
			sQuery.append("SELECT IA.DESCITEMADICIONAL ")
				  .append("FROM ITEM_ADICIONAL IA ")
				  .append("JOIN PACOTE_ITEM PI ON PI.ITEMADICIONAL_ID = IA.ITEMADICIONAL_ID ")
				  .append("JOIN PACOTE P ON P.PACOTE_ID = PI.PACOTE_ID ")
				  .append("JOIN VENDA_PACOTE VP ON VP.PACOTE_ID = P.PACOTE_ID ")
				  .append("WHERE VP.VENDAPACOTE_ID = :vendapacoteId ")
				  .append("AND IA.ACTIVO = 1");
			log.info(sQuery);
			stmt = new NamedParameterStatement(conexao, sQuery.toString());
			stmt.setLong("vendapacoteId", vendapacoteId);
			rset = stmt.executeQuery();
		
			List<PacoteItemAdicionalVoucher> lsPacoteItemAdicionalVoucher = new ArrayList<PacoteItemAdicionalVoucher>();
			while (rset.next()) {
				PacoteItemAdicionalVoucher pacoteTarifaVoucher = new PacoteItemAdicionalVoucher();
				pacoteTarifaVoucher.setDescitemadicional(rset.getString("descitemadicional"));
				lsPacoteItemAdicionalVoucher.add(pacoteTarifaVoucher);
			}
			pacoteVoucher.setItemAdicionalVouchers(lsPacoteItemAdicionalVoucher);
		} 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 void carregarEnderecoApanhe(Connection conexao, PacoteVoucher pacoteVoucher) {
		ResultSet rset = null;
		NamedParameterStatement stmt = null;
		try {
			StringBuilder sQuery = new StringBuilder("SELECT EA.LOCAL,EA.DESCHOTEL,EA.BAIRRO,EA.CEP,EA.CIDADE,EA.COMPLEMENTO,EA.ENDERECO,EA.NUMERO,EA.REFERENCIA ");
			sQuery.append("FROM ENDERECO_APANHE EA ")
				  .append("JOIN VENDA_PACOTE VP ON VP.VENDAPACOTE_ID = EA.VENDAPACOTE_ID ")
				  .append("WHERE VP.VENDAPACOTE_ID = :vendapacoteId ")
				  .append("AND EA.ACTIVO = 1 ")
				  .append("ORDER BY EA.ENDERECOAPANHE_ID DESC ");
			log.info(sQuery);
			stmt = new NamedParameterStatement(conexao, sQuery.toString());
			stmt.setLong("vendapacoteId", vendapacoteId);
			rset = stmt.executeQuery();
		
			while (rset.next()) {
				LocalEnderecoApanhe localEnderecoApanhe = LocalEnderecoApanhe.getLocalEnderecoApanhe(rset.getInt("local")); 
				if(LocalEnderecoApanhe.APANHE_EM_CASA.equals(localEnderecoApanhe)) {
					pacoteVoucher.setDescLocalEnderecoApanhe(LocalEnderecoApanhe.APANHE_EM_CASA.toString());
				} else if(LocalEnderecoApanhe.HOTEL.equals(localEnderecoApanhe)) {
					if(StringUtils.isNotBlank(rset.getString("deschotel"))) {
						pacoteVoucher.setDescLocalEnderecoApanhe(rset.getString("deschotel"));
					} else {
						pacoteVoucher.setDescLocalEnderecoApanhe(LocalEnderecoApanhe.HOTEL.toString());
					}
				} else if(LocalEnderecoApanhe.REGIAO_METROPOLITANA.equals(localEnderecoApanhe)) {
					pacoteVoucher.setDescLocalEnderecoApanhe(LocalEnderecoApanhe.REGIAO_METROPOLITANA.toString());
				}
				
				pacoteVoucher.setBairroEnderecoApanhe(rset.getString("bairro"));
				pacoteVoucher.setCepEnderecoApanhe(rset.getString("cep"));
				pacoteVoucher.setCidadeEnderecoApanhe(rset.getString("cidade"));
				pacoteVoucher.setComplementoEnderecoApanhe(rset.getString("complemento"));
				pacoteVoucher.setEnderecoEnderecoApanhe(rset.getString("endereco"));
				pacoteVoucher.setNumeroEnderecoApanhe(rset.getString("numero"));
				pacoteVoucher.setReferenciaEnderecoApanhe(rset.getString("referencia"));
				break;
			}
		} 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 void carregarClientePacote(Connection conexao, PacoteVoucher pacoteVoucher) {
		ResultSet rset = null;
		NamedParameterStatement stmt = null;
		try {
			StringBuilder sQuery = new StringBuilder("SELECT CP.RAZAO_SOCIAL,CP.CPF_CNPJ,CP.DESCEMAIL,CP.DESCTELEFONE,CP.DESCFAX,CP.CEP,CP.ENDERECO,CP.NUMERO,CP.COMPLEMENTO,CP.PAIS,CP.ESTADO,CP.CIDADE,CP.BAIRRO ");
			sQuery.append("FROM CLIENTE_PACOTE CP ")
				  .append("JOIN VENDA_PACOTE VP ON VP.CLIENTEPACOTE_ID = CP.CLIENTEPACOTE_ID ")
				  .append("WHERE VP.VENDAPACOTE_ID = :vendapacoteId ");
			log.info(sQuery);
			stmt = new NamedParameterStatement(conexao, sQuery.toString());
			stmt.setLong("vendapacoteId", vendapacoteId);
			rset = stmt.executeQuery();
		
			while (rset.next()) {
				pacoteVoucher.setRazaoSocialClientePacote(rset.getString("razao_social")); 
				pacoteVoucher.setCpfCnpjClientePacote(rset.getString("cpf_cnpj"));
				pacoteVoucher.setDescemailClientePacote(rset.getString("descemail"));
				pacoteVoucher.setDesctelefoneClientePacote(rset.getString("desctelefone"));
				pacoteVoucher.setDescfaxClientePacote(rset.getString("descfax"));  
				pacoteVoucher.setCepClientePacote(rset.getString("cep"));
				pacoteVoucher.setEnderecoClientePacote(rset.getString("endereco"));
				pacoteVoucher.setNumeroClientePacote(rset.getString("numero"));
				pacoteVoucher.setComplementoClientePacote(rset.getString("complemento"));
				pacoteVoucher.setPaisClientePacote(rset.getString("pais"));
				pacoteVoucher.setEstadoClientePacote(rset.getString("estado"));
				pacoteVoucher.setCidadeClientePacote(rset.getString("cidade"));
				pacoteVoucher.setBairroClientePacote(rset.getString("bairro"));
			}
		} 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 void carregarTarifaVendaPacote(Connection conexao, PacoteVoucher pacoteVoucher) {
		ResultSet rset = null;
		NamedParameterStatement stmt = null;
		try {
			StringBuilder sQuery = new StringBuilder();
			sQuery.append("SELECT B.NUMASIENTO, CONCAT(DEST.CVEPARADA,CONCAT(' - ',DEST.DESCPARADA)) AS DESTINO, CONCAT(ORI.CVEPARADA,CONCAT(' - ',ORI.DESCPARADA)) AS ORIGEM, ")
				  .append("TVP.DESCEMAIL,TTP.DESCTIPOTARIFA,TO_CHAR(B.FECHORVIAJE,'DD/MM/YYYY HH24:MI') AS FECHORVIAJE,TVP.IDIOMA,PC.NOMCONVENIO,TVP.NOMEPASSAGEIRO, ")
				  .append("TVP.TIPODOC,TVP.DOCUMENTO,TVP.DESCTELEFONE,CT.DESCCATEGORIA,C.CORRIDA_ID,C.MARCA_ID ")
				  .append("FROM TARIFA_VENDA_PACOTE TVP ")
				  .append("JOIN PACOTE_TARIFA PT ON PT.PACOTETARIFA_ID = TVP.PACOTETARIFA_ID ")
				  .append("JOIN TIPO_TARIFA_PACOTE TTP ON TTP.TIPOTARIFAPACOTE_ID = PT.TIPOTARIFAPACOTE_ID ")
				  .append("LEFT JOIN BOLETO B ON B.BOLETO_ID = TVP.BOLETO_ID ")
				  .append("LEFT JOIN PARADA DEST ON DEST.PARADA_ID = B.DESTINO_ID ")
				  .append("LEFT JOIN PARADA ORI ON ORI.PARADA_ID = B.ORIGEN_ID ")
				  .append("LEFT JOIN CORRIDA C ON C.CORRIDA_ID = B.CORRIDA_ID AND C.FECCORRIDA = B.FECCORRIDA ")
				  .append("LEFT JOIN CATEGORIA CT ON CT.CATEGORIA_ID = B.CATEGORIA_ID ")
				  .append("LEFT JOIN PACOTE_CONVENIO PC ON PC.PACOTECONVENIO_ID = TVP.PACOTECONVENIO_ID ")
				  .append("WHERE TVP.VENDAPACOTE_ID = :vendapacoteId ");
			log.info(sQuery);
			stmt = new NamedParameterStatement(conexao, sQuery.toString());
			stmt.setLong("vendapacoteId", vendapacoteId);
			rset = stmt.executeQuery();
		
			List<PacoteTarifaVoucher> lsPacoteTarifasVouchers = new ArrayList<PacoteTarifaVoucher>();
			while (rset.next()) {
				PacoteTarifaVoucher pacoteTarifaVoucher = new PacoteTarifaVoucher();
				pacoteTarifaVoucher.setAsiento(rset.getString("numasiento"));
				pacoteTarifaVoucher.setDescDestino(rset.getString("destino"));
				pacoteTarifaVoucher.setDescOrigen(rset.getString("origem"));
				pacoteTarifaVoucher.setDescEmail(rset.getString("descemail"));
				pacoteTarifaVoucher.setDesctipotarifa(rset.getString("desctipotarifa"));
				pacoteTarifaVoucher.setFecHorViaje(rset.getString("fechorviaje"));
				pacoteTarifaVoucher.setIdioma(rset.getString("idioma"));
				pacoteTarifaVoucher.setNomconvenio(rset.getString("nomconvenio"));
				pacoteTarifaVoucher.setNomPasajero(rset.getString("nomepassageiro"));
				pacoteTarifaVoucher.setNumDoc(rset.getString("documento"));
				pacoteTarifaVoucher.setTipoDoc(rset.getString("tipodoc"));
				pacoteTarifaVoucher.setNumTelefone(rset.getString("desctelefone"));
				pacoteTarifaVoucher.setDesccategoria(rset.getString("desccategoria"));
				
				if(rset.getInt("corrida_id") > 0) {
					pacoteTarifaVoucher.setCorridaId(rset.getInt("corrida_id"));
				}
				
				carregarLogo(conexao, rset.getInt("marca_id"));
				
				lsPacoteTarifasVouchers.add(pacoteTarifaVoucher);
			}
			pacoteVoucher.setPacoteTarifasVouchers(lsPacoteTarifasVouchers);
		} 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 void carregarLogo(Connection conexao, int marcaId) {
		if(getParametros().containsKey("logo")) {
			return;
		}
		
		ResultSet rset = null;
		NamedParameterStatement stmt = null;
		try {
			StringBuilder sQuery = new StringBuilder();
			sQuery.append("SELECT LOGOTIPOMARCA ")
			  	  .append("FROM MARCA ")
			  	  .append("WHERE MARCA_ID = :marcaId ")
			  	  .append("AND ACTIVO = 1 ");

			log.info(sQuery);
			stmt = new NamedParameterStatement(conexao, sQuery.toString());
			stmt.setLong("marcaId", marcaId);
			rset = stmt.executeQuery();
		
			while (rset.next()) {
				InputStream io = new ByteArrayInputStream(rset.getBytes("logotipomarca"));
				getParametros().put("logo", io);
			}
		} 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 void carregarFormaPago(Connection conexao, PacoteVoucher pacoteVoucher) {
		ResultSet rset = null;
		NamedParameterStatement stmt = null;
		try {
			StringBuilder sQuery = new StringBuilder();
			sQuery.append("SELECT FP.FORMAPAGO_ID, FP.DESCPAGO, PFP.VALOR ")
			  	  .append("FROM PACOTE_FORMAPAGO PFP ")
			  	  .append("JOIN FORMA_PAGO FP ON FP.FORMAPAGO_ID = PFP.FORMAPAGO_ID ")
			  	  .append("WHERE PFP.VENDAPACOTE_ID = :vendapacoteId ");

			if(SituacaoVendaPacote.RESERVA.equals(pacoteVoucher.getSituacaoVendaPacote())) {
				sQuery.append("AND FP.FORMAPAGO_ID = :formapagoId ");
			} else {
				sQuery.append("AND FP.FORMAPAGO_ID != :formapagoId ");
			}

			log.info(sQuery);
			stmt = new NamedParameterStatement(conexao, sQuery.toString());
			stmt.setLong("vendapacoteId", vendapacoteId);
			stmt.setInt("formapagoId", Constantes.FORMA_PAGO_RESERVA.intValue());
			rset = stmt.executeQuery();
		
			int indice = 0;
			while (rset.next()) {
				++indice;
				if(indice == 1) {
					pacoteVoucher.setDescFormapago1(rset.getString("descpago"));
					pacoteVoucher.setValorFormapago1(rset.getBigDecimal("valor"));
				} else if(indice == 2) {
					pacoteVoucher.setDescFormapago2(rset.getString("descpago"));
					pacoteVoucher.setValorFormapago2(rset.getBigDecimal("valor"));
				} else if(indice == 3) {
					pacoteVoucher.setDescFormapago3(rset.getString("descpago"));
					pacoteVoucher.setValorFormapago3(rset.getBigDecimal("valor"));
				}
			}
		} 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);
			}
		}
	}

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

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

}
