package com.rjconsultores.ventaboletos.relatorios.impl;

import java.math.BigDecimal;
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 org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

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

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

public class RelatorioEmpresaCorrida extends Relatorio {
	protected static final String FIELD_FEC_FINAL = "fecFinal";
	protected static final String FILED_FEC_INICIO = "fecInicio";
	protected static final String FIELD_EMPRESA_ID = "empresa_id";
	protected static final String FIELD_KM_TOTAL = "kmTotal";
	protected static final String FIELD_KM_ONIBUS_PROPRIO = "kmOnibusProprio";
	protected static final String FIELD_KM_ONIBUS_ARRENDADOS = "kmOnibusArrendados";
	protected static final String FIELD_PASSAGEIROS_TRANSP = "passageirosTransp";
	protected static final String FIELD_LINEA = "linea";
	protected static final String FIELD_NOMB_EMPRESA = "nombempresa";
	protected static final String FIELD_BOLETOS = "boletos";
	protected static final String FIELD_ABONOS = "abonos";
	protected static final String FIELD_RUTA_ID = "ruta_id";
	protected static final String FIELD_DESTINO = "destino";
	protected static final String FIELD_ORIGEM = "origem";
	protected static final String FIELD_TURNO_ORIGEM = "turnoOrigem";
	protected static final String FIELD_DATA_CORRIDA = "dataCorrida";
	protected static final String FIELD_CORRIDA_ID = "corrida_id";
	protected Logger log = LogManager.getLogger(RelatorioEmpresaCorrida.class);

	public RelatorioEmpresaCorrida(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 fecInicio = parametros.get(FILED_FEC_INICIO).toString() + " 00:00:00";
				String fecFinal = parametros.get(FIELD_FEC_FINAL).toString() + " 23:59:59";
				String empresa = parametros.get("empresa") != null ? parametros.get("empresa").toString() : "";

				log.info("empresa:" + empresa + ";fecinicio:" + fecInicio + ";fecFinal:" + fecFinal);
				String sql = getSql(empresa);
				log.info(sql);

				NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql);
				ResultSet rset = null;

				stmt.setString(FILED_FEC_INICIO, fecInicio);
				stmt.setString(FIELD_FEC_FINAL, fecFinal);
				if (empresa != null && !empresa.equals("")) {
					stmt.setInt(FIELD_EMPRESA_ID, Integer.parseInt(empresa));
				}
				log.info("Antes  de enviar consulta para o banco:" + System.currentTimeMillis());
				rset = stmt.executeQuery();
				log.info("Depois de enviar consulta para o banco:" + System.currentTimeMillis());

				List<RelatorioEmpresaCorridaBean> lsDadosRelatorio = new ArrayList<RelatorioEmpresaCorridaBean>();

				log.info("Preenchendo bean:" + System.currentTimeMillis());
				setDadosRelatorio(rset, lsDadosRelatorio);
				log.info("Fim bean:" + System.currentTimeMillis());

				if (lsDadosRelatorio.size() > 0) {
					setLsDadosRelatorio(lsDadosRelatorio);
				}
			}

		});
	}
	
	protected void setDadosRelatorio(ResultSet rset, List<RelatorioEmpresaCorridaBean> lsDadosRelatorio) throws SQLException {
		RelatorioEmpresaCorridaBean bean = new RelatorioEmpresaCorridaBean();
		while (rset.next()) {
			if (possuiRutaNoBean(rset.getInt(FIELD_RUTA_ID), lsDadosRelatorio)) {
				setValoresAgrupados(rset, bean);
				continue;
			} else {
				bean = new RelatorioEmpresaCorridaBean();
				setDadosBean(rset, bean);
			}
			lsDadosRelatorio.add(bean);
		}
	}
	
	private boolean possuiRutaNoBean(int ruta_id, List<RelatorioEmpresaCorridaBean> lsDadosRelatorio) {
		for (RelatorioEmpresaCorridaBean relatorioBean : lsDadosRelatorio) {
			if (ruta_id == relatorioBean.getRutaId()) {
				return true;
			}
		}
		return false;
	}

	protected void setDadosBean(ResultSet rset, RelatorioEmpresaCorridaBean bean) throws SQLException {
		bean.setRutaId(rset.getInt(FIELD_RUTA_ID));
		bean.setEmpresa(rset.getString(FIELD_NOMB_EMPRESA));
		bean.setLinea(rset.getString(FIELD_LINEA));
		bean.setAbonos(rset.getBigDecimal(FIELD_ABONOS));
		bean.setBoletos(rset.getBigDecimal(FIELD_BOLETOS));
		bean.setPasajerosTransportados(rset.getInt(FIELD_PASSAGEIROS_TRANSP));
		bean.setKmOnibusArrendados(rset.getBigDecimal(FIELD_KM_ONIBUS_ARRENDADOS));
		bean.setKmOnibusProprio(rset.getBigDecimal(FIELD_KM_ONIBUS_PROPRIO));
		bean.setKmTotal(rset.getBigDecimal(FIELD_KM_TOTAL));
	}

	private void setValoresAgrupados(ResultSet rset, RelatorioEmpresaCorridaBean bean) throws SQLException {
		bean.setAbonos(rset.getBigDecimal(FIELD_ABONOS).add(getValorBigDecimal(bean.getAbonos())));
		bean.setBoletos(rset.getBigDecimal(FIELD_BOLETOS).add(getValorBigDecimal(bean.getBoletos())));
		bean.setPasajerosTransportados(rset.getInt(FIELD_PASSAGEIROS_TRANSP) + (bean.getPasajerosTransportados() == null ? 0 : bean.getPasajerosTransportados()));
		bean.setKmOnibusArrendados(rset.getBigDecimal(FIELD_KM_ONIBUS_ARRENDADOS).add(getValorBigDecimal(bean.getKmOnibusArrendados())));
		bean.setKmOnibusProprio(rset.getBigDecimal(FIELD_KM_ONIBUS_PROPRIO).add(getValorBigDecimal(bean.getKmOnibusProprio())));
		bean.setKmTotal(rset.getBigDecimal(FIELD_KM_TOTAL).add(getValorBigDecimal(bean.getKmTotal())));
	}

	private BigDecimal getValorBigDecimal(BigDecimal valor) {
		return valor == null ? BigDecimal.ZERO : valor;
	}

	public void setLsDadosRelatorio(List<RelatorioEmpresaCorridaBean> lsDadosRelatorio) {
		this.setCollectionDataSource(new JRBeanCollectionDataSource(lsDadosRelatorio));
	}

	@Override
	protected void processaParametros() throws Exception {
	}

	protected String getSql(String empresa) {
		StringBuilder sql = new StringBuilder();
		
		sql.append("SELECT ");
		sql.append("	EMPRESA_ID, ");
		sql.append("	NOMBEMPRESA, ");
		sql.append("	RUTA_ID, ");
		sql.append("	LINEA, ");
		sql.append("	BOLETOS, ");
		sql.append("	ABONOS, ");
		sql.append("	PASSAGEIROSTRANSP, ");
		sql.append("	DATACORRIDA, ");
		sql.append("	TURNOORIGEM, ");
		sql.append("	ORIGEM, ");
		sql.append("	DESTINO, ");
		sql.append("	CORRIDA_ID, ");
		sql.append("	COALESCE(SUM(CANTKMREAL),0) KMTOTAL,  ");
		sql.append("	COALESCE(SUM(  ");
		sql.append("			CASE   ");
		sql.append("			WHEN EMPRESA_ID_AUTOBUS = EMPRESACORRIDA_ID THEN CANTKMREAL   ");
		sql.append("			ELSE 0   ");
		sql.append("			END   ");
		sql.append("			),0) KMONIBUSPROPRIO,   ");
		sql.append("	COALESCE(SUM(  ");
		sql.append("			CASE   ");
		sql.append("				WHEN EMPRESA_ID_AUTOBUS <> EMPRESACORRIDA_ID THEN CANTKMREAL   ");
		sql.append("				ELSE 0   ");
		sql.append("			END  ");
		sql.append("			),0) KMONIBUSARRENDADOS  ");
		sql.append("FROM ( ");
		sql.append("		SELECT  ");
		sql.append("		E.EMPRESA_ID,  ");
		sql.append("		E.NOMBEMPRESA,  ");
		sql.append("		R.RUTA_ID,  ");
		sql.append("		R.DESCRUTA AS LINEA,  ");
		sql.append("		(SELECT COALESCE(SUM(  ");
		sql.append("			CASE WHEN(CAT.GRUPOCATEGORIA_ID IS NULL OR CAT.GRUPOCATEGORIA_ID <> 4) THEN  ");
		sql.append("					B.PRECIOPAGADO   ");
		sql.append("				ELSE 0   ");
		sql.append("			END  ");
		sql.append("		),0) FROM BOLETO B ");
		sql.append("		LEFT JOIN CATEGORIA CAT ON CAT.CATEGORIA_ID = B.CATEGORIA_ID ");
		sql.append("		WHERE B.CORRIDA_ID = C.CORRIDA_ID   ");
		sql.append("		AND B.FECCORRIDA = C.FECCORRIDA   ");
		sql.append("		AND B.MOTIVOCANCELACION_ID IS NULL) BOLETOS,   ");
		sql.append("		(SELECT COALESCE(SUM(  ");
		sql.append("			CASE WHEN CAT.GRUPOCATEGORIA_ID = 4 THEN B.PRECIOPAGADO   ");
		sql.append("				ELSE 0   ");
		sql.append("			END  ");
		sql.append("		),0) FROM BOLETO B ");
		sql.append("		LEFT JOIN CATEGORIA CAT ON CAT.CATEGORIA_ID = B.CATEGORIA_ID ");
		sql.append("		WHERE B.CORRIDA_ID = C.CORRIDA_ID   ");
		sql.append("		AND B.FECCORRIDA = C.FECCORRIDA   ");
		sql.append("		AND B.MOTIVOCANCELACION_ID IS NULL) ABONOS,   ");
		sql.append("		(SELECT COUNT(B.BOLETO_ID) FROM BOLETO B  ");
		sql.append("		WHERE B.CORRIDA_ID = C.CORRIDA_ID   ");
		sql.append("		AND B.FECCORRIDA = C.FECCORRIDA   ");
		sql.append("		AND B.MOTIVOCANCELACION_ID IS NULL ");
		sql.append("		) PASSAGEIROSTRANSP, ");
		sql.append("		TO_CHAR(C.FECCORRIDA, 'DD/MM/YYYY') DATACORRIDA,  ");
		sql.append("		TO_CHAR(C.FECHORSALIDA, 'HH24:MI') TURNOORIGEM,  ");
		sql.append("		PO.DESCPARADA ORIGEM,  ");
		sql.append("		PD.DESCPARADA DESTINO,  ");
		sql.append("		C.CORRIDA_ID,  ");
		sql.append("		T.CANTKMREAL, ");
		sql.append("		C.EMPRESACORRIDA_ID, ");
		sql.append("		A.EMPRESA_ID EMPRESA_ID_AUTOBUS ");
		sql.append("		FROM CORRIDA C  ");
		sql.append("		INNER JOIN RUTA R ON C.RUTA_ID = R.RUTA_ID  ");
		sql.append("		INNER JOIN CORRIDA_TRAMO CT ON CT.CORRIDA_ID = C.CORRIDA_ID   ");
		sql.append("									AND C.FECCORRIDA = CT.FECCORRIDA  ");
		sql.append("		INNER JOIN TRAMO T ON T.TRAMO_ID = CT.TRAMO_ID  ");
		sql.append("		INNER JOIN AUTOBUS A ON A.AUTOBUS_ID = CT.AUTOBUS_ID  ");
		sql.append("		INNER JOIN MARCA M ON  M.MARCA_ID = C.MARCA_ID  ");
		sql.append("		INNER JOIN EMPRESA E ON  E.EMPRESA_ID = M.EMPRESA_ID  ");
		sql.append("		LEFT JOIN PARADA PO ON PO.PARADA_ID = C.ORIGEN_ID  ");
		sql.append("		LEFT JOIN PARADA PD ON PD.PARADA_ID = C.DESTINO_ID  ");
		sql.append("		WHERE C.ACTIVO <> 0  ");
		sql.append("		AND R.ACTIVO = 1  ");
		sql.append("		AND CT.ACTIVO = 1  ");
		sql.append(StringUtils.isBlank(empresa) ? "" : "AND E.EMPRESA_ID  = :empresa_id  ");
		sql.append("		AND C.FECCORRIDA BETWEEN TO_DATE(:fecInicio, 'DD/MM/YYYY HH24:MI:SS') AND TO_DATE(:fecFinal, 'DD/MM/YYYY HH24:MI:SS') ");
		sql.append(") TMP ");
		sql.append("GROUP BY  ");
		sql.append("EMPRESA_ID,  ");
		sql.append("NOMBEMPRESA,  ");
		sql.append("RUTA_ID, ");
		sql.append("LINEA, ");
		sql.append("BOLETOS, ");
		sql.append("ABONOS, ");
		sql.append("PASSAGEIROSTRANSP, ");
		sql.append("DATACORRIDA, ");
		sql.append("TURNOORIGEM, ");
		sql.append("ORIGEM, ");
		sql.append("DESTINO, ");
		sql.append("CORRIDA_ID ");
		sql.append("ORDER BY  ");
		sql.append("RUTA_ID ");
		
		return sql.toString();
	}

}