package com.rjconsultores.ventaboletos.relatorios.impl;

import java.sql.Connection;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

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

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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;

public class RelatorioEmpresaCorrida extends Relatorio {
	private Logger log = LoggerFactory.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("fecInicio").toString() + " 00:00:00";
				String fecFinal = parametros.get("fecFinal").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;

				SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
				stmt.setTimestamp("fecInicio", new java.sql.Timestamp(sdf.parse(fecInicio).getTime()));
				stmt.setTimestamp("fecFinal", new java.sql.Timestamp(sdf.parse(fecFinal).getTime()));
				if (empresa != null && !empresa.equals("")) {
					stmt.setInt("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());
				while (rset.next()) {
					RelatorioEmpresaCorridaBean rec = new RelatorioEmpresaCorridaBean();
					rec.setRutaId(rset.getInt("ruta_id"));
					rec.setAbonos(rset.getBigDecimal("abonos"));
					rec.setBoletos(rset.getBigDecimal("boletos"));
					rec.setEmpresa(rset.getString("nombempresa"));
					rec.setLinea(rset.getString("linea"));
					rec.setPasajerosTransportados(rset.getInt("passageirosTransp"));

					lsDadosRelatorio.add(rec);
				}
				log.info("Fim bean:" + System.currentTimeMillis());

				log.info("empresa:" + empresa + ";fecinicio:" + fecInicio + ";fecFinal:" + fecFinal);
				String sqlKm = getSqlKm(empresa);
				log.info(sqlKm);

				stmt = new NamedParameterStatement(conexao, sqlKm);
				rset = null;

				stmt.setTimestamp("fecInicio", new java.sql.Timestamp(sdf.parse(fecInicio).getTime()));
				stmt.setTimestamp("fecFinal", new java.sql.Timestamp(sdf.parse(fecFinal).getTime()));
				if (empresa != null && !empresa.equals("")) {
					stmt.setInt("empresa_id", Integer.parseInt(empresa));
				}

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

				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());
				while (rset.next()) {

					Integer rutaId = rset.getInt("ruta_id");

					RelatorioEmpresaCorridaBean rec = buscarRelatorioEmpresaCorrida(lsDadosRelatorio, rutaId);
					if (rec != null) {
						rec.setKmOnibusArrendados(rset.getInt("kmOnibusArrendados"));
						rec.setKmOnibusProprio(rset.getInt("kmOnibusProprio"));
						rec.setKmTotal(rset.getInt("kmTotal"));

						lsAux.add(rec);
					}
				}

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

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

	@Override
	protected void processaParametros() throws Exception {
	}

	private RelatorioEmpresaCorridaBean buscarRelatorioEmpresaCorrida(List<RelatorioEmpresaCorridaBean> lsDadosRelatorio, Integer rutaId) {
		for (RelatorioEmpresaCorridaBean rec : lsDadosRelatorio) {
			if (rec.getRutaId().equals(rutaId)) {
				return rec;
			}
		}
		return null;
	}

	private String getSql(String empresa) {

		StringBuilder sql = new StringBuilder();
		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("    COALESCE(SUM(CASE WHEN (cat.grupocategoria_id IS NULL OR cat.grupocategoria_id <> 4) THEN b.preciopagado ELSE 0 END), 0) boletos, ");
		sql.append("    COALESCE(SUM(CASE WHEN cat.grupocategoria_id = 4 THEN b.preciopagado ELSE 0 END), 0) abonos, ");
		sql.append("    COUNT(b.boleto_id) passageirosTransp ");
		sql.append("FROM ruta r ");
		sql.append("LEFT JOIN corrida c ON c.ruta_id = r.ruta_id ");
		sql.append("INNER JOIN empresa e ON  c.marca_id = e.empresa_id ");
		sql.append("LEFT JOIN boleto b ON b.corrida_id = c.corrida_id AND b.feccorrida = c.feccorrida AND b.motivocancelacion_id IS NULL ");
		sql.append("LEFT JOIN categoria cat ON cat.categoria_id = b.categoria_id ");
		sql.append("WHERE c.activo <> 0 ");
		sql.append("AND r.activo = 1 ");
		sql.append(StringUtils.isBlank(empresa) ? "" : "AND c.marca_id  = :empresa_id  ");
		sql.append("AND c.FECCORRIDA BETWEEN :fecInicio AND :fecFinal ");
		sql.append("GROUP BY ");
		sql.append("    e.empresa_id, ");
		sql.append("    e.nombempresa, ");
		sql.append("    r.ruta_id, ");
		sql.append("    r.descruta ");
		sql.append("ORDER BY r.ruta_id ");

		return sql.toString();
	}

	private String getSqlKm(String empresa) {

		StringBuilder sql = new StringBuilder();
		sql.append("SELECT ");
		sql.append("c.ruta_id                      ruta_id, ");
		sql.append("COALESCE(SUM(t.cantkmreal), 0) kmtotal, ");
		sql.append("COALESCE(SUM(CASE WHEN a.empresa_id = c.empresacorrida_id THEN t.cantkmreal ELSE 0 END), 0) kmOnibusProprio, ");
		sql.append("COALESCE(SUM(CASE WHEN a.empresa_id <> c.empresacorrida_id THEN t.cantkmreal ELSE 0 END), 0) kmOnibusArrendados ");
		sql.append("FROM corrida c ");
		sql.append("INNER JOIN corrida_tramo ct ON ct.corrida_id = c.corrida_id 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("WHERE c.activo <> 0 ");
		sql.append("AND ct.activo = 1 ");
		sql.append(StringUtils.isBlank(empresa) ? "" : "AND c.marca_id = :empresa_id  ");
		sql.append("AND c.FECCORRIDA BETWEEN :fecInicio AND :fecFinal ");
		sql.append("GROUP BY c.ruta_id ");
		sql.append("ORDER BY c.ruta_id ");

		return sql.toString();
	}

}