package com.rjconsultores.ventaboletos.relatorios.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.rjconsultores.ventaboletos.relatorios.utilitarios.ArrayDataSource;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;

public class RelatorioQuadroDemonstrativoMovimentoPassageiros extends Relatorio {

	public RelatorioQuadroDemonstrativoMovimentoPassageiros(Map<String, Object> parametros, Connection conexao) throws Exception {
		super(parametros, conexao);

		this.setCustomDataSource(new ArrayDataSource(this) {

			public void initDados() throws Exception {
				Connection conexao = this.relatorio.getConexao();
				Map<String, Object> parametros = this.relatorio.getParametros();
				
				String dataDe = (String) parametros.get("DATA_DE");
				
				String dataAte = (String) parametros.get("DATA_ATE");
				

				String linhasIds = (String) parametros.get("LINHAS");
				String empresaId = (String) parametros.get("EMPRESA_IDS");

				String sql = getSql(dataDe, dataAte, linhasIds, empresaId);

				PreparedStatement ps = conexao.prepareStatement(sql.toString());
				
				ResultSet rset = ps.executeQuery();

				while (rset.next()) {
					boolean agrupar = false;
					Map<String, Object> dataResult = new HashMap<String, Object>();

					dataResult.put("origem", rset.getString("origem"));
					dataResult.put("destino", rset.getString("destino"));
					dataResult.put("km", rset.getFloat("km"));
					dataResult.put("totalida", rset.getLong("totalida"));
					dataResult.put("totalvolta", rset.getLong("totalvolta"));

					for (Iterator iterator = dados.iterator(); iterator.hasNext();) {

						Map<String, Object> map = (Map<String, Object>) iterator.next();
						String origem = map.get("origem").toString();
						String destino = map.get("destino").toString();
						Long ida = (Long) map.get("totalida");
						Long volta = (Long) map.get("totalvolta");

						if (origem.equals(rset.getString("destino")) && destino.equals(rset.getString("origem"))) {
							agrupar = true;
							if (ida == 0) {
								map.put("totalida", rset.getLong("totalida"));
							}
							if (volta == 0) {
								map.put("totalvolta", rset.getLong("totalvolta"));
							}

						}

					}

					if (!agrupar) {
						this.dados.add(dataResult);
					}

				}
				
				this.ordenarTrechosSentidoIda(this.dados,linhasIds);
				
				this.resultSet = rset;
			}

			private void ordenarTrechosSentidoIda(List<Map<String, Object>> dados, String linhasIds) {
				
				List<String> listOrigemDestino = this.buscarSequenciaOrigemDestinoIda(linhasIds);
				
				if (listOrigemDestino.isEmpty()){
					return;
				}
					
				
				List<Map<String, Object>> dadosOrdenados = new ArrayList<Map<String,Object>>();

				
				for(Map<String, Object> dado : dados){
					
					Map<String, Object> dataResult = new HashMap<String, Object>();
					
					String origemAtual = dado.get("origem").toString();
					String destinoAtual = dado.get("destino").toString();
					
					String trecho = origemAtual.concat("|").concat(destinoAtual);
					
					if (!listOrigemDestino.contains(trecho) ){
						origemAtual = dado.get("destino").toString();
						destinoAtual = dado.get("origem").toString();
					}
					
					dataResult.put("origem", origemAtual);
					dataResult.put("destino", destinoAtual);
					dataResult.put("km", dado.get("km"));
					dataResult.put("totalida", dado.get("totalida"));
					dataResult.put("totalvolta", dado.get("totalvolta"));
					
					dadosOrdenados.add(dataResult);
				}

				dados.clear();
				dados.addAll(dadosOrdenados);
				
								
			}

			private List<String> buscarSequenciaOrigemDestinoIda(String linhasIds) {
				StringBuilder query = new StringBuilder();
				query.append("SELECT ");
				query.append("ori.DESCPARADA || '|' ||  des.DESCPARADA AS trecho ");
				query.append("FROM ");
				query.append("ruta r ");
				query.append("JOIN RUTA_COMBINACION rc ON rc.ruta_id = r.ruta_id ");
				query.append("INNER JOIN tramo tr ON tr.TRAMO_ID =rc.TRAMO_ID AND tr.ACTIVO = 1 ");
				query.append("JOIN parada ori ON\tori.parada_id = tr.origen_id ");
				query.append("JOIN parada des ON\tdes.parada_id = tr.destino_id ");
				query.append(" ");
				query.append("WHERE ");				
				query.append(" r.INDSENTIDOIDA =1 ");
				query.append("AND rc.ACTIVO =1 ");
				query.append("AND r.ACTIVO =1 ");
				if (!StringUtils.isBlank(linhasIds)) {
					query.append(" and  r.NUMRUTA = '").append(linhasIds).append("' ");
				}
				query.append("ORDER BY 1 ");

				List<String> listOrigemDestino = new ArrayList<String>();
				
				try {
					
					Connection conexao = this.relatorio.getConexao();
					PreparedStatement ps= conexao.prepareStatement(query.toString());
					
					ResultSet rset = ps.executeQuery();
										
					while (rset.next()) {
						listOrigemDestino.add(rset.getString("trecho"));
					}
					
					rset.close();
					ps.close();
					
				} catch (SQLException e) {
					throw new RuntimeException("Erro ao buscar sequencia da linha",e);
				}
				return listOrigemDestino;
			}
		});
	}

	@Override
	protected void processaParametros() throws Exception {
	}

	private String getSql(String dataDe, String dataAte, String linhasIds,
			String empresaId) {
		StringBuilder sql = new StringBuilder();

		sql.append(" SELECT DISTINCT ");					
		sql.append(" r.cantasientos, ");
		sql.append(" e.nombempresa empresa, ");
		sql.append(" r.descruta linha, ");
		sql.append(" ori.descparada AS origem, ");
		sql.append(" des.descparada AS destino, ");
		sql.append(" MAX(tr.CANTKMREAL) as km, ");
		sql.append(" COUNT( DISTINCT ");
		sql.append(" CASE ");
		sql.append(" WHEN(r.indsentidoida = 1) THEN b.boleto_id ");
		sql.append(" ELSE NULL ");
		sql.append(" END ");
		sql.append(" ) AS totalida, ");
		sql.append(" COUNT( DISTINCT ");
		sql.append(" CASE ");
		sql.append(" WHEN(r.indsentidoida = 0) THEN b.boleto_id ");
		sql.append(" ELSE NULL ");
		sql.append(" END ");
		sql.append(" ) AS totalvolta ");
		sql.append(" FROM ");
		sql.append(" boleto b ");
		sql.append(" JOIN empresa e ON e.empresa_id = b.empresacorrida_id ");
		sql.append(" JOIN categoria ca ON b.categoria_id = ca.categoria_id ");
		sql.append(" JOIN parada ori ON ori.parada_id = b.origen_id ");
		sql.append(" JOIN parada des ON des.parada_id = b.destino_id ");
		sql.append(" JOIN ruta r ON r.ruta_id = b.ruta_id ");
		sql.append(" JOIN RUTA_COMBINACION rc ON rc.ruta_id = r.ruta_id ");
		sql.append(" INNER JOIN tramo tr ON tr.TRAMO_ID =rc.TRAMO_ID AND tr.ORIGEN_ID = ori.PARADA_ID	AND tr.DESTINO_ID = des.PARADA_ID	AND tr.ACTIVO = 1 ");
		sql.append(" WHERE b.empresacorrida_id IN (").append(empresaId).append(") ");		             
		                                                                                           
		sql.append(" AND b.motivocancelacion_id is null ");
		
		if (!StringUtils.isBlank(linhasIds)) {
			sql.append(" AND r.NUMRUTA = '").append(linhasIds).append("' ");
		}
		
		sql.append(" AND b.feccorrida BETWEEN To_date('").append(dataDe).append("', 'dd/mm/yyyy') ");
		sql.append("                      AND To_date('").append(dataAte).append("', 'dd/mm/yyyy') ");
		
		sql.append(" GROUP BY ");
		sql.append(" r.cantasientos, ");
		sql.append(" e.nombempresa, ");
		sql.append(" r.numruta, ");
		sql.append(" r.descruta, ");
		sql.append(" ori.descparada, ");
		sql.append(" des.descparada ");
		sql.append(" ORDER BY ");
		sql.append(" r.descruta, ");
		sql.append(" origem, ");
		sql.append(" destino ");
		
		return sql.toString();
	}
}
