package com.rjconsultores.ventaboletos.relatorios.impl;

import java.sql.Connection;
import java.sql.ResultSet;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import com.rjconsultores.ventaboletos.relatorios.utilitarios.DataSource;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.RelatorioPassagensAGRBean;
import com.rjconsultores.ventaboletos.web.utilerias.CurrencyUtil;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

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

public class RelatorioPassagensAGR extends Relatorio {

	private List<RelatorioPassagensAGRBean> lsDadosRelatorio;
	
	public RelatorioPassagensAGR(Map<String, Object> parametros, Connection conexao)  throws Exception {
		super(parametros, conexao);
		
		this.setCustomDataSource(new DataSource(this) {
			
			@Override
			public void initDados() throws Exception {

				Connection conexao = this.relatorio.getConexao();

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

				String fecInicioVenda = null;
				if (parametros.get("fecInicioVenda") != null) {
					fecInicioVenda = parametros.get("fecInicioVenda") + " 00:00:00";
				}
				String fecFinalVenda = null;
				if (parametros.get("fecFinalVenda") != null) {
					fecFinalVenda = parametros.get("fecFinalVenda")+ " 23:59:59";
				}
				
				String fecInicioViagem = null;
				if (parametros.get("fecInicioViagem") != null) {
					fecInicioViagem = parametros.get("fecInicioViagem") + " 00:00:00";
				}
				String fecFinalViagem = null;
				if (parametros.get("fecFinalViagem") != null) {
					fecFinalViagem = parametros.get("fecFinalViagem") + " 23:59:59";
				}
				Locale locale = new Locale("pt", "BR");
				String tipGratuIds = parametros.get("tipGratuIds").toString();
				String clienteIds = parametros.get("clienteIds").toString();
				String linhaIds = parametros.get("linhaIds").toString();
				String empresa = parametros.get("empresa") != null ? parametros.get("empresa").toString() : "";
				String categoriaIds = parametros.get("tipGratuIds") != null ? parametros.get("tipGratuIds").toString() : "";
						
				String sql = getSql(fecInicioVenda, fecFinalVenda, linhaIds, tipGratuIds, clienteIds, empresa, fecInicioViagem, fecFinalViagem, categoriaIds);
		
				SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
				NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql);

				if (fecInicioVenda != null) {
					stmt.setTimestamp("fecInicioVenda", new java.sql.Timestamp(sdf.parse(fecInicioVenda).getTime()));
				}
				
				if (fecFinalVenda != null) {
					stmt.setTimestamp("fecFinalVenda", new java.sql.Timestamp(sdf.parse(fecFinalVenda).getTime()));
				}
				
				if (fecInicioViagem != null) {
					stmt.setTimestamp("fecInicioViagem", new java.sql.Timestamp(sdf.parse(fecInicioViagem).getTime()));
				}
				
				if (fecFinalViagem != null) {
					stmt.setTimestamp("fecFinalViagem", new java.sql.Timestamp(sdf.parse(fecFinalViagem).getTime()));
				}
				
				if(empresa != null && !empresa.equals("")){
					stmt.setInt("empresa_id", Integer.parseInt(empresa));
				}
				
				ResultSet rset = null;
		
				rset = stmt.executeQuery();
		
				lsDadosRelatorio = new ArrayList<RelatorioPassagensAGRBean>();
				
				while (rset.next()) {
					RelatorioPassagensAGRBean PassagensBean = new RelatorioPassagensAGRBean();
					
					PassagensBean.setNumeroBilhete(rset.getString("numero_bilhete"));
					PassagensBean.setRazaoSocial(capitalizeWords(rset.getString("razao_social")));
					PassagensBean.setCnpj(mascaraDOC(rset.getString("cnpj")));
					PassagensBean.setNumeroPassaporte(rset.getString("numero_passaporte"));
					PassagensBean.setTipoDescontoBeneficio(capitalizeWords(removerEstado(rset.getString("tipo_desconto_beneficio"))));
					PassagensBean.setNomePassageiro(capitalizeWords(rset.getString("nome_passageiro")));
					PassagensBean.setNumeroIdentidade((rset.getString("numero_identidade"))); 
					PassagensBean.setOrgaoExpedidor(rset.getString("orgao_expedidor"));
					PassagensBean.setCpfPassageiro(mascaraDOC(rset.getString("cpf_passageiro"))); 
					PassagensBean.setNumeroPoltrona(rset.getString("numero_poltrona")); 
					PassagensBean.setDataViagem(getDataCompleta(rset.getString("data_viagem")));
					PassagensBean.setMesViagem(getMesAno(rset.getString("data_viagem")));
					PassagensBean.setHoraViagem(getHora(rset.getString("data_viagem")));
					PassagensBean.setNumeroLinha(formatarNumero(rset.getString("numero_linha"))); 
					PassagensBean.setDenominacaoLinha(capitalizeWords(rset.getString("denominacao_linha")));
					PassagensBean.setLocalOrigem(capitalizeWords(removerEstado(rset.getString("local_origem"))));
					PassagensBean.setLocalDestino(capitalizeWords(removerEstado(rset.getString("local_destino"))));
					PassagensBean.setValorPassagem(CurrencyUtil.getCurrencyStrFromStr(rset.getString("valor_passagem"),locale)); 
					PassagensBean.setChaveAcessoBPE(rset.getString("chave_acesso_bpe"));
					PassagensBean.setImagemBPE(rset.getString("imagem_bpe")); 
					PassagensBean.setNaturezaServico(capitalizeWords(rset.getString("natureza_servico")));
					
					
					lsDadosRelatorio.add(PassagensBean);
				}

				if (lsDadosRelatorio.size() > 0) {
					setLsDadosRelatorio(lsDadosRelatorio);
				}
			}
		});
	}
	
	public static String formatarNumero(String numero) {
        if (numero == null || numero.isEmpty()) {
            return "";
        }
        
        StringBuilder builder = new StringBuilder(numero);
        if (numero.length() >= 6) {
        	builder.insert(2, ".");
            builder.insert(6, "-");
            return builder.toString();
        } else {
        	builder.insert(2, ".");
        	return builder.toString();
        }
    }
	
	public void setLsDadosRelatorio(List<RelatorioPassagensAGRBean> lsDadosRelatorio) {
		this.setCollectionDataSource(new JRBeanCollectionDataSource(lsDadosRelatorio));
		this.lsDadosRelatorio = lsDadosRelatorio;
	}
	
	public String getMesAno(String data) {
		if(!data.isEmpty()) {
			data = getData(data);
			DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
			Date dateFormatada = null;
			try {
				dateFormatada = format.parse(data);
			} catch (ParseException e) {
				e.printStackTrace();
			}
			DateFormat outputFormat = new SimpleDateFormat("dd/MM");
			String dataDiaMes = outputFormat.format(dateFormatada);
			return dataDiaMes;
		}

	return "";	
	}
		
	public static String mascaraDOC(String document) {
		if (document == null || document.isEmpty()) {
			return "";
		}
		String numericOnly = document.replaceAll("[^0-9]", "");
		if (numericOnly.length() == 11) {
			return numericOnly.replaceFirst("(\\d{3})(\\d{3})(\\d{3})(\\d{2})", "$1.$2.$3-$4");
		} else if (numericOnly.length() == 14) {
			return numericOnly.replaceFirst("(\\d{2})(\\d{3})(\\d{3})(\\d{4})(\\d{2})", "$1.$2.$3/$4-$5");
		}

		return document;
	}
	 
	public static String removerDigitosEspeciais(String input) {
		String semDigitosEspeciais = input.replaceAll("[^\\p{L}\\s.]", "");
		String semEspacosEmExcesso = semDigitosEspeciais.replaceAll("\\s+", " ");
		String resultadoFinal = semEspacosEmExcesso.trim();

		return resultadoFinal;
	}
	
	public static String capitalizeWords(String input) {
		StringBuilder output = new StringBuilder();
		String palavraCorrigida = "";
		boolean newWord = input == null || input.isEmpty() ? false : true;
		if (newWord) {
			for (int i = 0; i < input.length(); i++) {
				char c = input.charAt(i);

				if (Character.isLetter(c)) {
					if (newWord) {
						output.append(Character.toUpperCase(c));
						newWord = false;
					} else {
						output.append(Character.toLowerCase(c));
					}
				} else {
					output.append(c);
					newWord = true;
				}
			}
		}
		try {
			palavraCorrigida = removerDigitosEspeciais(output.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}

		return palavraCorrigida;
	}
	
	public static String removerEstado(String lugar) {
	    // Criando um array com as siglas dos estados
	    String[] estados = {"AC", "AL", "AP", "AM", "BA", "CE", "DF", "ES", "GO", "MA", "MT", "MS", 
	    						"MG", "PA", "PB", "PR", "PE", "PI", "RJ", "RN", "RS", "RO", "RR", "SC", "SP", "SE", "TO"};
	    boolean isEstado = lugar == null || lugar.isEmpty() ? false : true;
	    if(isEstado) {
	    	 // Percorrendo o array de estados
		    for (String estado : estados) {
		        // Verificando se a string contém a sigla do estado
		        if (lugar.contains(" - " + estado)) {
		            // Retornando a string sem a sigla do estado
		           return lugar.replace(" - " + estado, "");
				}
		        if (lugar.endsWith(" " + estado)) {
		            // Retornando a string sem a sigla do estado
		           	return lugar.replace(" " + estado, "");
		        }
		    }
	    }
	    // Se não encontrar nenhuma sigla de estado, retorna a string original
	    return lugar;
	}

	private String getData(String data) {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		LocalDateTime dateTime = LocalDateTime.parse(data, formatter);
		String formattedDate = dateTime.format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"));
		return formattedDate;
	}
	
	private String getDataCompleta(String data) {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		LocalDateTime dateTime = LocalDateTime.parse(data, formatter);
		String formattedDate = dateTime.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
		return formattedDate;
	}
	
	public String getHora(String data) {
		if(!data.isEmpty()) {
			data = getData(data);
			DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
			Date dateFormatada = null;
			try {
				dateFormatada = format.parse(data);
			} catch (ParseException e) {
				e.printStackTrace();
			}
			DateFormat outputFormat = new SimpleDateFormat("HH:mm");
			String dataDiaMes = outputFormat.format(dateFormatada);
			return dataDiaMes;
		}
	return "";	
	}

	@Override
	protected void processaParametros() throws Exception {
	}
	
	private String getSql(String fecInicioVenda, String fecFinalVenda, String linha, String tipoGratu, String cliente, 
							String empresa, String fecInicioViagem, String fecFinalViagem, String categoriaIds ) {
	
		StringBuilder sql = new StringBuilder(3400);
		
		 sql.append(" SELECT ");
		 sql.append("   b.numfoliosistema AS numero_bilhete,                                                                   	");
		 sql.append("   e.nombempresa AS razao_social,                                                                         	");
		 sql.append("   COALESCE(ie.cnpj, e.cnpj)   AS cnpj,                                                                  	");
		 sql.append("   CASE                                                                                                   	");
		 sql.append("      WHEN ((b.DESCNUMDOC IS NOT NULL OR c.NUMIDENTIFICAUNO IS NOT NULL) AND c.TIPOIDENTIFICAUNO_ID = 13) 	");
		 sql.append("      THEN  nvl(b.descnumdoc, c.numidentificauno)                                                         	");
		 sql.append("      WHEN ((b.descnumdoc2 IS NOT NULL OR c.NUMIDENTIFICADOS IS NOT NULL) AND c.TIPOIDENTIFICADOS_ID = 13)	");
		 sql.append("      THEN  nvl(b.descnumdoc2, c.numidentificados)                                                        	");
		 sql.append("      ELSE ''                                                                                             	");
		 sql.append("   END AS numero_passaporte,                                                                              	");
		 sql.append("  ct.desccategoria    AS tipo_desconto_beneficio, 															");
		 sql.append("  b.nombpasajero AS nome_passageiro,                                                                      	");
		 sql.append("  CASE                                                                                                    	");
		 sql.append("      WHEN (b.desctipodoc like 'RG') THEN b.descnumdoc													  	");
		 sql.append("      WHEN (b.desctipodoc2 like 'RG') THEN  b.descnumdoc2                                                 	");
		 sql.append("      WHEN (c.NUMIDENTIFICAUNO IS NOT NULL AND c.TIPOIDENTIFICAUNO_ID = 1) THEN c.numidentificauno			");
		 sql.append("      WHEN (c.NUMIDENTIFICADOS IS NOT NULL AND c.TIPOIDENTIFICADOS_ID = 1) THEN c.numidentificados			");
		 sql.append("      ELSE ''                                                                                             	");
		 sql.append("  END AS numero_identidade,                                                                               	");
		 sql.append("  ''  AS orgao_expedidor,                                                                                 	");
		 sql.append("  CASE                                                                                                    	");
		 sql.append("      WHEN (b.desctipodoc like 'CPF') THEN b.descnumdoc												  	");
		 sql.append("      WHEN (b.desctipodoc2 like 'CPF') THEN  b.descnumdoc2    	                                        	");
		 sql.append("      WHEN (c.NUMIDENTIFICAUNO IS NOT NULL AND c.TIPOIDENTIFICAUNO_ID = 2) THEN c.numidentificauno			");
		 sql.append("      WHEN (c.NUMIDENTIFICADOS IS NOT NULL AND c.TIPOIDENTIFICADOS_ID = 2) THEN c.numidentificados			");
		 sql.append("      ELSE ''																								");
		 sql.append("  END AS cpf_passageiro,                                                                                  	");
		 sql.append("  b.numasiento AS numero_poltrona,                                                                        	");
		 sql.append("  nvl(b.fechorviaje, '')  AS data_viagem,			                                                    	");
		 sql.append("  r.prefixo AS numero_linha,                                                                             	");
		 sql.append("  r.descruta AS denominacao_linha,                                                                       	");
		 sql.append("  ori.descparada AS local_origem,                                                                        	");
		 sql.append("  des.descparada AS local_destino,                                                                        	");
		 sql.append("  b.preciobase AS valor_passagem,                                                                         	");
		 sql.append("  bpe.chbpe AS chave_acesso_bpe,                                                                         	");
		 sql.append("  bpe.qrcode AS imagem_bpe,                                                                        	 	");
		 sql.append("  cs.descclase AS natureza_servico                                                                       	");
		 sql.append("FROM	                                                                                                	");
		 sql.append("	boleto  b 					                                                                           	");
		 sql.append("		LEFT JOIN BPE                bpe ON (bpe.boleto_id = b.boleto_id AND bpe.activo = 1)            	");
		 sql.append("		LEFT JOIN MARCA 			 m 	 ON (m.marca_id = b.marca_id)      									");
		 sql.append("		LEFT JOIN empresa            e   ON (e.empresa_id = m.empresa_id)                      				");
		 sql.append("		LEFT JOIN parada             ori ON (ori.parada_id = b.origen_id)                               	");
		 sql.append("		LEFT JOIN parada             des ON (des.parada_id = b.destino_id)                              	");
		 sql.append("		LEFT JOIN ruta               r   ON (r.ruta_id = b.ruta_id)                                     	");
		 sql.append("		LEFT JOIN clase_servicio    cs   ON (r.claseservicio_id = cs.claseservicio_id and cs.activo = 1)	");
		 sql.append("		LEFT JOIN cliente            c   ON (c.cliente_id = b.cliente_id	                               	");
		 sql.append("											AND c.activo = 1)                           	               	");
		 sql.append("		LEFT JOIN categoria 		 ct	 ON (b.categoria_id = ct.categoria_id 								");
		 sql.append("											AND ct.activo =1 and ct.categoria_id not in (1))				");
		 sql.append("  		LEFT JOIN punto_venta pv ON (b.puntoventa_id = pv.puntoventa_id and pv.activo =1)					");
		 sql.append("    	LEFT JOIN parada    pr ON  (pv.parada_id = pr.parada_id and pr.activo =1)							");
		 sql.append("   	LEFT JOIN ciudad    ci ON  (pr.ciudad_id = ci.ciudad_id and ci.activo =1)							");
		 sql.append("   	LEFT JOIN inscricao_estadual ie ON (e.empresa_id = ie.empresa_id 									");
		 sql.append(" 		 										and ci.estado_id = ie.estado_id and ie.activo =1)			");
		sql.append("WHERE		                                                                                               	");
		sql.append("     	( b.motivocancelacion_id NOT IN ( 4 ) 							");
		sql.append("           OR b.motivocancelacion_id IS NULL ) 							");
		sql.append("	 	AND r.orgaoconcedente_id = 16 									");
		
		if( fecInicioVenda != null && fecFinalVenda !=null ){
			sql.append("    AND b.fechorventa BETWEEN :fecInicioVenda AND :fecFinalVenda 	");
		}
			
		if (!categoriaIds.isEmpty() && !categoriaIds.equals("Todas") ) {
			sql.append("	AND b.categoria_id in ( "+categoriaIds+" ) 						");	
		}

		if( fecInicioViagem != null && fecFinalViagem !=null ){			
			sql.append("    AND b.fechorviaje BETWEEN :fecInicioViagem AND :fecFinalViagem ");
		}

		if (!empresa.isEmpty()){
			sql.append("	AND e.empresa_id =:empresa_id  							");
		}
		
		if (linha != null && !linha.equals("Todas")) {
			sql.append(" 	AND b.ruta_id in (").append(linha).append(") 					");
		}

		sql.append(" ORDER BY ");
		sql.append("     b.fechorviaje, 													");
		sql.append("     ori.descparada,													");
		sql.append("     des.descparada, 													");
		sql.append("     b.nombpasajero 													");
		
		return sql.toString();
	}
	
}