package com.rjconsultores.ventaboletos.relatorios.impl;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.rjconsultores.ventaboletos.relatorios.utilitarios.ArrayDataSource;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.IndStatusBoleto;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

public class RelatorioVendaBilhetePorEmpresaAutorizadoraAnalitico extends Relatorio {

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

		this.setCustomDataSource(new ArrayDataSource(this) {
			@Override
			public void initDados() throws Exception {

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

				StringBuilder sql = new StringBuilder();

				getSQL(parametros, sql);
				
				NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql.toString());
				setarParmetrosObrigatorios(parametros, stmt);

				ResultSet rset = stmt.executeQuery();

				getResultSet(rset);

				this.resultSet = rset;
			}

			private void getResultSet(ResultSet rset) throws SQLException {
				while (rset.next()) {
					Map<String, Object> dataResult = new HashMap<String, Object>();
					carregarDataResult(rset, dataResult);
					this.dados.add(dataResult);
				}
			}

			private void carregarDataResult(ResultSet rset, Map<String, Object> dataResult) throws SQLException {
				dataResult.put("DATA_EVENTO", rset.getDate("DATA_EVENTO"));
				dataResult.put("CODIGO_AGENCIA", rset.getString("CODIGO_AGENCIA"));
				dataResult.put("NOME_AGENCIA", rset.getString("NOME_AGENCIA"));
				dataResult.put("CODIGO_BILHETEIRO", rset.getString("CODIGO_BILHETEIRO"));
				dataResult.put("NOME_BILHETEIRO", rset.getString("NOME_BILHETEIRO"));
				dataResult.put("NUMERO_PASSAGEM", rset.getBigDecimal("NUMERO_PASSAGEM"));
				dataResult.put("ORIGEM", rset.getString("ORIGEM"));
				dataResult.put("DESTINO", rset.getString("DESTINO"));
				dataResult.put("TIPO_BILHETE", rset.getString("TIPO_BILHETE"));
				dataResult.put("TX_EMBARQUE", rset.getBigDecimal("TX_EMBARQUE"));
				dataResult.put("PEDAGIO", rset.getBigDecimal("PEDAGIO"));
				dataResult.put("TARIFA", rset.getBigDecimal("TARIFA"));
				dataResult.put("TOTAL_BILHETE", rset.getBigDecimal("TOTAL_BILHETE"));
				dataResult.put("STATUS_PASSAGEM",
						IndStatusBoleto.valueOf(rset.getString("STATUS_PASSAGEM")).getValue());
				dataResult.put("SERVICO", rset.getBigDecimal("SERVICO"));
				dataResult.put("DATA_VIAGEM", rset.getDate("DATA_VIAGEM"));
				dataResult.put("CLASSE", rset.getString("CLASSE"));
				dataResult.put("EMPRESAAUTORIZADORA", rset.getString("EMPRESAAUTORIZADORA"));
				dataResult.put("EMPRESAAUTORIZADORA_ID", rset.getString("EMPRESAAUTORIZADORA_ID"));
				dataResult.put("NUMBPE", rset.getString("NUMBPE"));
				
				String formasPagamento = rset.getString("descpago");
				setarAsFormasDePagamento(dataResult, formasPagamento);					
				setarOsValoresDasFormasDePagamento(dataResult, formasPagamento);
			}

			private void setarOsValoresDasFormasDePagamento(Map<String, Object> dataResult, String formasPagamento) {
				if (!StringUtils.isBlank(formasPagamento)) {
					final String[] formaPagamento = formasPagamento.split("\\;");
					if (formaPagamento.length > 1) {
						int contador = 1;	
						int contadorFormaPagamento =0;
						while (contador <=formaPagamento.length) {
							String valorformapago = "VALORFORMAPAGO" + contador;
							dataResult.put(valorformapago, formatarValorFormaDePagamento(formaPagamento[contadorFormaPagamento]));						
							contador ++;
							contadorFormaPagamento++;
						}

					} else {
						dataResult.put("VALORFORMAPAGO1", formatarValorFormaDePagamento(formaPagamento[0]));
					}						
				}
			}

			private void setarAsFormasDePagamento(Map<String, Object> dataResult, String formasPagamento) {
				if (!StringUtils.isBlank(formasPagamento)) {
					final String[] formaPagamento = formasPagamento.split("\\;");
					if (formaPagamento.length > 1) {
						int contador = 1;
						int contadorFormaPagamento =0;
						while (contador <= formaPagamento.length) {
							String formaPago = "FORMAPAGO" + contador;
							dataResult.put(formaPago, formatarFormaDePagamento(formaPagamento[contadorFormaPagamento]));
							contador ++;
							contadorFormaPagamento ++;
						
						}

					} else {
						dataResult.put("FORMAPAGO1", formatarFormaDePagamento(formaPagamento[0]));
					}
					
					
				}
			}

			private void setarParmetrosObrigatorios(Map<String, Object> parametros, NamedParameterStatement stmt)
					throws SQLException {
				stmt.setInt("EMPRESA_ID", Integer.valueOf(parametros.get("EMPRESA_ID").toString()));
				stmt.setTimestamp("DATA_INICIAL",
						new Timestamp(DateUtil.inicioFecha((Date) parametros.get("DATA_INICIAL")).getTime()));
				stmt.setTimestamp("DATA_FINAL",
						new Timestamp(DateUtil.fimFecha((Date) parametros.get("DATA_FINAL")).getTime()));
			}

			private void getSQL(Map<String, Object> parametros, StringBuilder sql) {
				sql.append(" select c.feccreacion DATA_EVENTO, pv.NUMPUNTOVENTA CODIGO_AGENCIA, ");
				sql.append(" pv.NOMBPUNTOVENTA NOME_AGENCIA, ");
				sql.append(" u.CVEUSUARIO CODIGO_BILHETEIRO, ");
				sql.append(" u.NOMBUSUARIO NOME_BILHETEIRO, ");
				sql.append(" c.NUMFOLIOSISTEMA NUMERO_PASSAGEM, ");
				sql.append(" p_origen.DESCPARADA ORIGEM, ");
				sql.append(" p_destino.DESCPARADA DESTINO, ");
				sql.append(" ct.DESCCATEGORIA TIPO_BILHETE, ");
				sql.append(" case when (c.INDREIMPRESION = 1 and c.MOTIVOREIMPRESION_ID = 99) then ");
				sql.append("		'R' else c.INDSTATUSBOLETO end STATUS_PASSAGEM,");
				sql.append(" c.FECCORRIDA DATA_VIAGEM, ");
				sql.append(" c.CORRIDA_ID SERVICO, ");
				sql.append(" c.IMPORTEPEDAGIO PEDAGIO,");
				sql.append(" c.IMPORTETAXAEMBARQUE TX_EMBARQUE,");
				sql.append(" c.PRECIOPAGADO TARIFA,");
				sql.append(
						" (NVL(c.PRECIOPAGADO,0)+(NVL(c.IMPORTEPEDAGIO,0)+ NVL(c.IMPORTETAXAEMBARQUE,0)+ NVL(c.IMPORTESEGURO,0))) TOTAL_BILHETE, ");
				sql.append(" cs.DESCCLASE CLASSE, ");
				sql.append(
						" LISTAGG(cf.cajaformapago_id||' /'||  fp.cvepago||' /'||CAST(cf.IMPORTE AS VARCHAR(10)),';') WITHIN GROUP( ORDER BY 1 DESC ) AS descpago, ");
				sql.append(" e.empresa_id EMPRESAAUTORIZADORA_ID, e.nombempresa EMPRESAAUTORIZADORA, ");
				sql.append(" c.num_bpe NUMBPE ");

				sql.append(" from caja c ");
				sql.append(" join PUNTO_VENTA pv on c.PUNTOVENTA_ID = pv.PUNTOVENTA_ID ");
				sql.append(" join USUARIO u on u.USUARIO_ID = c.USUARIO_ID ");
				sql.append(" join PARADA p_origen on p_origen.PARADA_ID = c.ORIGEN_ID ");
				sql.append(" join PARADA p_destino on p_destino.PARADA_ID = c.DESTINO_ID ");
				sql.append(" join CATEGORIA ct on ct.CATEGORIA_ID = c.CATEGORIA_ID ");
				sql.append(" join CLASE_SERVICIO cs on cs.CLASESERVICIO_ID = c.CLASESERVICIO_ID ");
				sql.append(" join MARCA m on m.marca_id = c.marca_id ");
				sql.append(" join RUTA_EMPRESA re on re.ruta_id = c.ruta_id and re.activo = 1 ");
				sql.append(" join CAJA_FORMAPAGO cf on cf.caja_id=c.caja_id ");
				sql.append(" join FORMA_PAGO fp on fp.formapago_id=cf.formapago_id ");
				sql.append(" INNER JOIN empresa e on re.empresa_autorizadora_id=e.empresa_id ");
				sql.append(" where  ");
				sql.append(" m.EMPRESA_ID  = :EMPRESA_ID ");
				sql.append(" and re.empresa_autorizadora_id  in ( ");
				sql.append(parametros.get("EMPRESAAUTORIZADORA_ID"));
				sql.append(" ) ");
				sql.append(" and c.FECHORVENTA >= :DATA_INICIAL ");
				sql.append(" and c.FECHORVENTA <= :DATA_FINAL ");
				sql.append(" and ((c.indreimpresion = 1 ");
				sql.append(
						"               AND (c.motivoreimpresion_id = 99 )) or c.indreimpresion = 0) ");
				if (parametros.get("NUMPUNTOVENTA") != null && !possuiFiltroTodos("NUMPUNTOVENTA")) {
					sql.append(" and pv.PUNTOVENTA_ID IN (" + parametros.get("NUMPUNTOVENTA").toString() + ")");
				}
				if (parametros.get("BILHETEIRO") != null && !parametros.get("BILHETEIRO").equals("")) {
					sql.append(" and u.NOMBUSUARIO like '" + parametros.get("BILHETEIRO") + "%'");
				}
				sql.append(" GROUP BY ");
				sql.append(" c.feccreacion,  ");
				sql.append(" pv.numpuntoventa,  ");
				sql.append(" pv.nombpuntoventa,  ");
				sql.append(" u.cveusuario,  ");
				sql.append(" u.nombusuario,  ");
				sql.append(" c.numfoliosistema,  ");
				sql.append(" p_origen.descparada,  ");
				sql.append(" p_destino.descparada,  ");
				sql.append(" ct.desccategoria ,   ");
				sql.append("  CASE  ");
				sql.append("     WHEN ( c.indreimpresion = 1  ");
				sql.append("            AND c.motivoreimpresion_id = 99 ) THEN  ");
				sql.append("         'R'  ");
				sql.append("     ELSE  ");
				sql.append("         c.indstatusboleto  ");
				sql.append(" END,  ");
				sql.append(" c.feccorrida,  ");
				sql.append(" c.corrida_id,  ");
				sql.append(" c.importepedagio,  ");
				sql.append(" c.importetaxaembarque,  ");
				sql.append(" c.preciopagado,  ");
				sql.append(
						" (NVL(c.PRECIOPAGADO,0)+(NVL(c.IMPORTEPEDAGIO,0)+ NVL(c.IMPORTETAXAEMBARQUE,0)+ NVL(c.IMPORTESEGURO,0))), ");
				sql.append(" cs.descclase,  ");
				sql.append(" e.empresa_id, ");
				sql.append(" e.nombempresa, ");
				sql.append(" c.num_bpe ");
				sql.append(" ORDER BY e.empresa_id,u.CVEUSUARIO, ");
				sql.append(" u.NOMBUSUARIO, ");
				sql.append(" pv.NUMPUNTOVENTA, ");
				sql.append(" pv.NOMBPUNTOVENTA, ");
				sql.append(" c.feccreacion, ");				
				sql.append(" c.NUMFOLIOSISTEMA, ");
				sql.append(" p_origen.DESCPARADA, ");
				sql.append(" p_destino.DESCPARADA, ");
				sql.append(" ct.DESCCATEGORIA, ");
				sql.append(" c.FECCORRIDA, ");
				sql.append(" c.CORRIDA_ID ");
				
				

			}
		});
	}

	@Override
	protected void processaParametros() throws Exception {
		// TODO Auto-generated method stub

	}

	private String formatarFormaDePagamento(String formaDePagamento) {
		if (formaDePagamento != null) {
			final String[] formaPagamentoAuxilar = formaDePagamento.split("\\/");
			return formaPagamentoAuxilar[1];
		}
		return null;
	}
	
	private BigDecimal formatarValorFormaDePagamento(String formaDePagamento){
	    if(formaDePagamento!=null){
		final String[] formaPagamentoAuxilar = formaDePagamento.split("\\/") ;
	    return formaPagamentoAuxilar.length>2? new BigDecimal(formaPagamentoAuxilar[2].replace(",", ".").trim()):new BigDecimal("0.0");	
	    }
		return null;	
	}
}
