package com.rjconsultores.ventaboletos.relatorios.impl;

import java.sql.Connection;
import java.sql.ResultSet;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.rjconsultores.ventaboletos.constantes.Constantes;
import com.rjconsultores.ventaboletos.entidad.Constante;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.ArrayDataSource;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.service.ConstanteService;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;
import com.rjconsultores.ventaboletos.web.utilerias.spring.AppContext;

public class RelatorioBPe extends Relatorio {

	public RelatorioBPe(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 sql = getSql(parametros);
				
				Date dtInicio = (Date) parametros.get("DATA_INICIO");
				Date dtFim = (Date) parametros.get("DATA_FIM");
				String chBpe = (String) parametros.get("CHBPE");
				String numBpe = (String) parametros.get("NUMBPE");				

				NamedParameterStatement ps = new NamedParameterStatement(conexao, sql.toString());
				if(dtInicio != null && dtFim != null) {
					ps.setString("dataInicio", DateUtil.getStringDate(dtInicio, "dd/MM/yyyy") + " 00:00:00");
					ps.setString("dataFinal", DateUtil.getStringDate(dtFim, "dd/MM/yyyy") + " 23:59:59");
				}

				if(StringUtils.isNotBlank(chBpe)) {
					ps.setString("chbpe", chBpe);
				}
				
				if(StringUtils.isNotBlank(numBpe)) {
					ps.setString("numbpe",numBpe);
				}
				
				ResultSet rset = ps.executeQuery();

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

					dataResult.put("dtvenda", rset.getString("dtvenda"));
					dataResult.put("hrvenda", rset.getString("hrvenda"));
					dataResult.put("locpuntoventa", rset.getString("locpuntoventa"));
					dataResult.put("numPuntoVenta", rset.getString("numPuntoVenta"));
					dataResult.put("origem", rset.getString("origem"));
					dataResult.put("destino", rset.getString("destino"));
					dataResult.put("dtviagem", rset.getString("dtviagem"));
					dataResult.put("vlbpe", rset.getBigDecimal("vlbpe"));
					dataResult.put("chbpe", rset.getString("chbpe"));
					dataResult.put("protocolo", rset.getString("protocolo"));
					dataResult.put("num_bpe", rset.getString("num_bpe"));
					dataResult.put("numserie_bpe", rset.getString("numserie_bpe"));
					dataResult.put("status", rset.getString("status"));
					dataResult.put("obs", rset.getString("obs"));
					dataResult.put("qrcode", rset.getString("qrcode"));
					dataResult.put("valortarifa", rset.getBigDecimal("valortarifa"));
					dataResult.put("valortaxa", rset.getBigDecimal("valortaxa"));
					dataResult.put("valorpedagio", rset.getBigDecimal("valorpedagio"));
					dataResult.put("valorseguro", rset.getBigDecimal("valorseguro"));
					dataResult.put("valoroutros", rset.getBigDecimal("valoroutros"));
					dataResult.put("errocontingencia", rset.getString("errocontingencia"));
					dataResult.put("evento", rset.getString("evento"));
					
					this.dados.add(dataResult);
				}

				this.resultSet = rset;
			}
		});
	}

	@Override
	protected void processaParametros() throws Exception {
	}

	private String getSql(Map<String, Object> parametros) {

		StringBuilder sql = new StringBuilder();
		ConstanteService constanteService = (ConstanteService) AppContext.getApplicationContext().getBean("constanteService");

		String estados = (String) parametros.get("ESTADOS_ID");
		String empresaId = (String) parametros.get("EMPRESA_ID");
		String status = (String) parametros.get("STATUS");
		String chBpe = (String) parametros.get("CHBPE");
		String numBpe = (String) parametros.get("NUMBPE");
		Date dtInicio = (Date) parametros.get("DATA_INICIO");
		Date dtFim = (Date) parametros.get("DATA_FIM");
		String alias = (String) parametros.get("ALIAS");
		
		sql.append(" SELECT ");
		sql.append(" 	dtvenda, hrvenda, locpuntoventa,numPuntoVenta,  origem, destino, dtviagem, vlbpe, valortarifa, valortaxa, valorpedagio,  ");
		sql.append(" 	valorseguro, valoroutros, chbpe, protocolo, num_bpe, numserie_bpe, status, obs, qrcode, errocontingencia, evento ");
		sql.append(" FROM ( ");

		getSelectFrom(sql, alias);

		getWhere(sql, constanteService, estados, empresaId, status, chBpe, numBpe, dtInicio, dtFim);
		
		//So busca os dados da empresa operadora quando escolhido uma empresa
		if(empresaId != null) {
			sql.append(" UNION ");
			
			getSelectFrom(sql, alias);
			
			sql.append(" , ruta_empresa ");
			//Envia sem o empresa_id para usar na busca da empresa autorizadora
			getWhere(sql, constanteService, estados, null, status, chBpe, numBpe, dtInicio, dtFim);
			
			sql.append(" AND RUTA_EMPRESA.EMPRESA_AUTORIZADORA_ID = " + empresaId);
			sql.append(" AND bol.ruta_id = ruta_empresa.ruta_Id ");
		}
		
		
		sql.append(" ) ORDER BY NUM_BPE, COALESCE(NUMSERIE_BPE, '1')  ASC ");

		return sql.toString();
	}

	private void getWhere(StringBuilder sql, ConstanteService constanteService, String estados, String empresaId, String status, String chBpe, String numBpe, Date dtInicio, Date dtFim) {
		sql.append(" WHERE e.ACTIVO = 1 ");

		if (empresaId != null) {
			sql.append(" AND ep.EMPRESA_ID IN ( " + empresaId + " ) ");
		}
		if (estados != null) {
			sql.append(" AND e.ESTADO_ID IN ( " + estados + " )");
		}

		// Mantis 18156
		if (status != null && status.equals("A")) { //Autorizados ou ALIAS Origem/Destino dos bilhetes
			sql.append(" AND  bpe.CODSTAT = '100' AND bol.ACTIVO = 1 ");
		} else if (status != null && status.equals("C")) {//Cancelados
			sql.append(" AND  bpe.CODSTAT = '135' AND bpe.TIPOEVENTO = '110111' AND bol.ACTIVO = 1 ");
		} else if (status != null && status.equals("S")) {//Substituidos
			sql.append(" AND bpe.CODSTAT IN ('100', '102') AND bpeSub.BPE_ID IS NOT NULL AND bol.ACTIVO = 1 ");
		} else if (status != null && status.equals("SB")) {//Substituicao
			sql.append(" AND  ((bpe.CODSTAT IN ('100', '102', '150') AND bpe.TIPOSUBSTITUICAO IS NOT NULL AND bol.ACTIVO = 1 and  bpeSub.CODSTAT IN ('100', '102', '150')) or (bpe.CODSTAT IN ('100', '102', '150') AND bpe.TIPOSUBSTITUICAO IS NOT NULL AND bol.ACTIVO = 1 ))  ");
		} else if (status != null && status.equals("NE")) {//Nao Embarcado
			sql.append(" AND bpe.CODSTAT = '135' AND bpe.TIPOEVENTO = '110115' AND bol.ACTIVO = 1 ");
		} else if (status != null && status.equals("R")) {//Rejeitado
			sql.append(" AND bpe.CODSTAT NOT IN ('100','135','102','150','-1','-2') ");
		}else if (status != null && status.equals("AA")) {//Autorizado Contingencia
			sql.append(" AND bpe.CODSTAT IN ('100', '150') AND bpe.INDCONTINGENCIA = 1 AND bol.ACTIVO = 1 ");
		}else if (status != null && status.equals("RC")) {//Rejeitado Envio Contingencia
			sql.append(" AND  bpe.CODSTAT IN ('-10','-20') AND bol.ACTIVO = 1 ");
		} else if (status != null && status.equals("PE")) {//Pendente Envio
			sql.append(" AND bpe.CODSTAT IN ('-1','-2') ");
		}
		else if (status != null && status.equals("T")) {//Opcao Todas
			sql.append(opcaoTodas());
		}
		
		if(dtInicio != null && dtFim != null) {
			Constante constanteBPeOtimizado = constanteService.buscarPorNomeConstante(Constantes.RELATORIO_BPE_OTIMIZADO);
			if(constanteBPeOtimizado != null && StringUtils.isNotBlank(constanteBPeOtimizado.getValorconstante()) && Boolean.parseBoolean(constanteBPeOtimizado.getValorconstante())) {
				sql.append("  AND coalesce(bol.FECHORVENTA_H, bol.FECHORVENTA) >= TO_DATE(:dataInicio,'DD/MM/YYYY HH24:MI:SS') ");
				sql.append("  AND coalesce(bol.FECHORVENTA_H, bol.FECHORVENTA) <= TO_DATE(:dataFinal,'DD/MM/YYYY HH24:MI:SS') ");
			}else {
				//Mantis 17952
				sql.append(" AND (bpe.dt_venda >= TO_DATE(:dataInicio,  'DD/MM/YYYY HH24:MI:SS'  ) OR (bpe.dt_venda is null and bol.fechorventa   >= TO_DATE(:dataInicio,  'DD/MM/YYYY HH24:MI:SS'))) ");
				sql.append(" AND (bpe.dt_venda <= TO_DATE(:dataFinal,   'DD/MM/YYYY HH24:MI:SS'  ) OR (bpe.dt_venda is null and bol.fechorventa   <= TO_DATE(:dataFinal,  'DD/MM/YYYY HH24:MI:SS'  )))");
			}
		}

		if(StringUtils.isNotBlank(chBpe)) {
			sql.append(" AND bpe.CHBPE = :chbpe ");
		}
		
		if(StringUtils.isNotBlank(numBpe)) {
			sql.append(" AND bol.NUM_BPE = :numbpe ");
		}
	}

	private String opcaoTodas() {
		
		StringBuilder sql = new StringBuilder();

		sql.append(" AND ((bpe.CODSTAT = '100' AND bol.ACTIVO = 1) OR (bpe.CODSTAT = '135' AND bpe.TIPOEVENTO = '110111' AND bol.ACTIVO = 1 ) ");
		sql.append(" OR (bpe.CODSTAT IN ('100', '102') AND bpeSub.BPE_ID IS NOT NULL AND bol.ACTIVO = 1) ");
		sql.append(" OR ((bpe.CODSTAT IN ('100', '102', '150') AND bpe.TIPOSUBSTITUICAO IS NOT NULL AND bol.ACTIVO = 1 and  bpeSub.CODSTAT IN ('100', '102', '150')) or (bpe.CODSTAT IN ('100', '102', '150') AND bpe.TIPOSUBSTITUICAO IS NOT NULL AND bol.ACTIVO = 1 )) ");
		sql.append(" OR (bpe.CODSTAT = '135' AND bpe.TIPOEVENTO = '110115' AND bol.ACTIVO = 1) ");
		sql.append(" OR (bpe.CODSTAT NOT IN ('100','135','102','150','-1','-2')) ");
		sql.append(" OR (bpe.CODSTAT IN ('100', '150') AND bpe.INDCONTINGENCIA = 1 AND bol.ACTIVO = 1) ");
		sql.append(" OR (bpe.CODSTAT IN ('-10','-20') AND bol.ACTIVO = 1) ");
		sql.append(" OR (bpe.CODSTAT IN ('-1','-2'))) ");

		return sql.toString();
	}

	private void getSelectFrom(StringBuilder sql, String alias) {
		sql.append("SELECT");
		sql.append("  TO_CHAR(COALESCE(bpe.DT_VENDA,bol.FECHORVENTA),'dd/mm/yyyy') as dtvenda, ");
		sql.append("  TO_CHAR(COALESCE(bpe.DT_VENDA,bol.FECHORVENTA),'HH24:MI') as hrvenda, ");
		
		// Mantis 18156
		if(alias != null && alias.equals("S")) {// ALIAS Origem/Destino dos bilhetes
			sql.append("  COALESCE(oriA.DESCPARADA, ori.DESCPARADA) as origem,  ");
			sql.append("  COALESCE(destA.DESCPARADA, dest.DESCPARADA) as destino,");
		}else {
			sql.append("  ori.DESCPARADA as origem,  ");
			sql.append("  dest.DESCPARADA as destino,");
		}
		sql.append("  locpv.DESCPARADA as locpuntoventa, ");
		sql.append("  pv.NUMPUNTOVENTA as numPuntoVenta, ");
		
		sql.append("  TO_CHAR(bol.FECHORVIAJE,'dd/mm/yyyy HH24:MI') as dtviagem, ");
		sql.append("  COALESCE(bol.PRECIOPAGADO,0) + coalesce(bol.IMPORTETAXAEMBARQUE,0) + coalesce(bol.IMPORTESEGURO,0) + coalesce(bol.IMPORTEPEDAGIO,0) + coalesce(bol.IMPORTEOUTROS,0)  as vlbpe, ");
		sql.append("  COALESCE(bol.PRECIOPAGADO,0) as valortarifa, ");
		sql.append("  COALESCE(bol.IMPORTETAXAEMBARQUE,0) as valortaxa, ");
		sql.append("  COALESCE(bol.IMPORTEPEDAGIO,0) as valorpedagio, ");
		sql.append("  COALESCE(bol.IMPORTESEGURO,0) as valorseguro, ");
		sql.append("  COALESCE(bol.IMPORTEOUTROS,0) as valoroutros, ");
		
		sql.append("  bpe.CHBPE,  ");
		sql.append("  bpe.nprot as protocolo,  ");
		sql.append("  bol.NUM_BPE as num_bpe, ");
		sql.append("  COALESCE(bol.NUMSERIE_BPE, '1') as numserie_bpe, ");
		
		sql.append("  CASE bpe.tipoevento WHEN '110111' THEN 'Cancelado' ");
		sql.append("  	WHEN '110116' THEN 'Alteração de Poltrona' ");
		sql.append("  	WHEN '110115' THEN 'Não embarcado' ELSE '' END as evento, ");

		sql.append("  case bpe.codstat when '100' then ( ");
		sql.append("                  case ");
		sql.append("                    when bpe.tiposubstituicao is null and bpeSub.bpe_id is null and bpe.indcontingencia = 0 then 'Autorizado' ");
		sql.append("                    when bpe.tiposubstituicao is null and bpeSub.bpe_id is null and bpe.indcontingencia = 1 then 'Aut.Conting.' ");
		sql.append("                    when bpe.tiposubstituicao is not null then 'Autorizado/Substituição' ");
		sql.append("                    when bpeSub.bpe_id is not null then 'Autorizado/Substituído' ");
		sql.append("                    else 'Autorizado' ");
		sql.append("                  end ");
		sql.append("                  ) ");
		
		sql.append("  when '102' then ( ");
		sql.append("                case ");
		sql.append("                    when bpe.tiposubstituicao is not null then 'Substituição' ");
		sql.append("                    when bpeSub.bpe_id is not null then 'Substituído' ");
		sql.append("                end ");
		sql.append("                ) ");
		
		sql.append("  when '135' then ( ");
		sql.append("                case bpe.tipoevento ");
		sql.append("                    when '110111' then 'Cancelado' ");
		sql.append("                    when '110115' then 'Não embarcado' ");
		sql.append("                    else '' ");
		sql.append("                end ");
		sql.append("                ) ");
		
		sql.append("  when '150' then 'Aut.Conting.' ");
		sql.append("  when '-1' then 'Pendente Envio' ");
		sql.append("  when '-2' then 'Pendente Envio' ");
		sql.append("  when '-10' then 'Rejeitado Envio Contingência' ");
		sql.append("  when '-20' then 'Rejeitado Envio Contingência' ");
		
		sql.append("  else 'Rejeitado' ");
		sql.append("  end as status, ");
		
		sql.append("  CASE WHEN bpe.CODSTAT not in ('100','135') THEN bpe.motivo  ELSE NULL END as obs, ");
		sql.append("  bpe.QRCODE, bpe.errocontingencia ");

		sql.append(" FROM BPE bpe ");
		sql.append(" LEFT JOIN BPE bpeSub on (bpeSub.bpesubstituicao_id = bpe.bpe_id and bpeSub.activo = 1) ");
		sql.append(" LEFT JOIN BOLETO bol ON bol.BOLETO_ID = bpe.BOLETO_ID and bpe.activo = 1  ");
		sql.append(" LEFT JOIN estado e ON e.CODIBGE = bpe.UF  ");
		sql.append(" LEFT JOIN marca ma ON bol.MARCA_ID = ma.MARCA_ID  ");
		sql.append(" LEFT JOIN empresa ep on ma.EMPRESA_ID = ep.EMPRESA_ID ");
		
		// Mantis 18156
		if(alias != null && alias.equals("S")) {// ALIAS Origem/Destino dos bilhetes
			sql.append(" LEFT JOIN PARADA oriA on bol.ORIGENA_ID = oriA.PARADA_ID ");
			sql.append(" LEFT JOIN PARADA destA on bol.DESTINOA_ID = destA.PARADA_ID ");
		}
		
		sql.append(" LEFT JOIN PARADA ori on bol.ORIGEN_ID = ori.PARADA_ID ");
		sql.append(" LEFT JOIN PARADA dest on bol.DESTINO_ID = dest.PARADA_ID ");
		
		sql.append(" LEFT JOIN PUNTO_VENTA pv ");
		sql.append(" ON bol.PUNTOVENTA_ID = pv.PUNTOVENTA_ID ");
		sql.append(" LEFT JOIN PARADA locpv ");
		sql.append(" ON pv.PARADA_ID = locpv.PARADA_ID AND locpv.activo = 1");
	}
}