package com.rjconsultores.ventaboletos.relatorios.impl;

import java.sql.Connection;
import java.sql.ResultSet;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

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

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

public class RelatorioEmpresaOnibus extends Relatorio {

	private List<RelatorioEmpresaOnibusBean> lsDadosRelatorio;

	public RelatorioEmpresaOnibus(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() : "";
				String autobus = parametros.get("autobus") != null ? parametros.get("autobus").toString() : "";

				String sql = getSql(empresa, autobus);

				SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
				NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql);
				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));
				}
				if (autobus != null && !autobus.equals("")) {
					stmt.setInt("autobus_id", Integer.parseInt(autobus));
				}

				ResultSet rset = null;

				rset = stmt.executeQuery();

				// Soma os kms dos tramos.
				// HashMap utilizado para identificar os tramos de uma corrida
				Map<String, RelatorioEmpresaOnibusBean> mDadosRelatorio = new LinkedHashMap<String, RelatorioEmpresaOnibusBean>();
				lsDadosRelatorio = new ArrayList<RelatorioEmpresaOnibusBean>();

				sdf.applyPattern("dd/MM/yyyy");
				while (rset.next()) {
					RelatorioEmpresaOnibusBean empresaOnibusBean = new RelatorioEmpresaOnibusBean();
					empresaOnibusBean.setCorridaId(rset.getInt("corridaId"));
					empresaOnibusBean.setEmpresa(rset.getString("empresa"));
					empresaOnibusBean.setCoche(Integer.parseInt(rset.getString("coche")));
					empresaOnibusBean.setDestino(rset.getString("destino"));
					empresaOnibusBean.setDia(rset.getDate("dia"));
					empresaOnibusBean.setHora(rset.getString("hora"));
					empresaOnibusBean.setKmts(rset.getInt("kmts"));
					empresaOnibusBean.setOrigem(rset.getString("origem"));
					empresaOnibusBean.setNumsecuencia(rset.getInt("numsecuencia"));

					String key = empresaOnibusBean.getCorridaId() + "-" + empresaOnibusBean.getCoche() + "-" + empresaOnibusBean.getHora() + "-" +
							sdf.format(empresaOnibusBean.getDia()) + "-" + empresaOnibusBean.getEmpresa();

					if (mDadosRelatorio.containsKey(key)) {
						RelatorioEmpresaOnibusBean auxEmpresaOnibusBean = mDadosRelatorio.get(key);
						empresaOnibusBean.setOrigem(auxEmpresaOnibusBean.getOrigem());

						empresaOnibusBean.setKmts(empresaOnibusBean.getKmts() + auxEmpresaOnibusBean.getKmts());
						if (empresaOnibusBean.getNumsecuencia() < auxEmpresaOnibusBean.getNumsecuencia()) {
							empresaOnibusBean.setDestino(auxEmpresaOnibusBean.getDestino());
						}
					}

					mDadosRelatorio.put(key, empresaOnibusBean);
				}

				for (Entry<String, RelatorioEmpresaOnibusBean> empresaOnibusBean : mDadosRelatorio.entrySet()) {
					lsDadosRelatorio.add(empresaOnibusBean.getValue());
				}

				if (lsDadosRelatorio.size() > 0) {
					Collections.sort(lsDadosRelatorio, new Comparator<RelatorioEmpresaOnibusBean>() {
						@Override
						public int compare(RelatorioEmpresaOnibusBean o1, RelatorioEmpresaOnibusBean o2) {
							int result = o1.getEmpresa().compareToIgnoreCase(o2.getEmpresa());
							if (result != 0) {
								return result;
							}

							result = o1.getCoche().compareTo(o2.getCoche());
							if (result != 0) {
								return result;
							}

							result = o1.getDia().compareTo(o2.getDia());
							if (result != 0) {
								return result;
							}

							try {
								SimpleDateFormat formatter = new SimpleDateFormat("HH:mm");
								Date h1 = formatter.parse(o1.getHora());
								Date h2 = formatter.parse(o2.getHora());
								result = h1.compareTo(h2);
							} catch (ParseException e) {
							}
							return result;
						}
					});
					setLsDadosRelatorio(lsDadosRelatorio);
				}

			}
		});
	}

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

	@Override
	protected void processaParametros() throws Exception {

	}

	private String getSql(String empresa, String autobus) {
		StringBuffer sql = new StringBuffer();

		sql.append(" select c.corrida_Id corridaId, e.nombempresa empresa, c.feccorrida dia, a.numautobus coche, ");
		sql.append("       o.cveparada origem, d.cveparada destino,  ");
		sql.append("       to_char(c.fechorsalida, 'HH24:MI') Hora, t.cantkmreal KMTS, ct.numsecuencia ");
		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 parada o on o.parada_id = ct.origen_id ");
		sql.append("       inner join parada d on d.parada_id = ct.destino_id  ");
		sql.append("       inner join autobus a on a.autobus_id = ct.autobus_id ");
		sql.append("       inner join empresa e on e.empresa_id = a.empresa_id ");
		sql.append("       where c.activo = 1  ");
		if (!empresa.isEmpty()) {
			sql.append("       and e.empresa_id = :empresa_id  ");
		}
		if (!autobus.isEmpty()) {
			sql.append("       and a.autobus_id = :autobus_id  ");
		}
		sql.append("       and ct.activo = 1 and c.feccorrida between :fecInicio and :fecFinal ");
		sql.append("       and ct.feccorrida between :fecInicio and :fecFinal ");
		sql.append("       order by e.nombempresa, a.numautobus, c.feccorrida, ct.numsecuencia ");

		return sql.toString();
	}
}
