package com.rjconsultores.ventaboletos.web.gui.controladores.relatorios.sgti;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;

import javax.activation.MimetypesFileTypeMap;

import org.zkoss.zul.Filedownload;

import com.rjconsultores.ventaboletos.entidad.Ruta;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.web.gui.controladores.relatorios.EspecializaLista;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

public class ExecutarExportacaoSGTI {

	private RelatorioExportacaoSGTIController controller;
	private Connection connection;
	
	public ExecutarExportacaoSGTI(RelatorioExportacaoSGTIController controller, Connection connection) {
		this.controller = controller;
		this.connection = connection;
	}

	public void executa() throws IOException {
		GerarXMLExportacaoSGTI geradorXML = new GerarXMLExportacaoSGTI(controller, this);
		File arquivoXml = geradorXML.gerar();
		downloadArquivo(arquivoXml);
	}

	private void downloadArquivo(File file) throws IOException {
		if (file.exists()) {
			FileInputStream inputStream = new FileInputStream(file);
			Filedownload.save(inputStream, new MimetypesFileTypeMap().getContentType(file), "Exportacao_SGTI.xml");
		}
	}
	
	protected ResultSet getDadosTrecho() throws SQLException {
		return obtemInstrucaoSqlParametrizada(getQueryTrechosPorLinha()).executeQuery();
	}

	protected ResultSet getDadosReceita() throws SQLException {
		return obtemInstrucaoSqlParametrizada(getQueryReceitasPorLinha()).executeQuery();
	}

	protected ResultSet getDadosViagemExtra() throws SQLException {
		return obtemInstrucaoSqlParametrizada(getQueryViagensExtrasPorLinha()).executeQuery();
	}

	private NamedParameterStatement obtemInstrucaoSqlParametrizada(String instrucaoSQL) throws SQLException {
		NamedParameterStatement stmt = new NamedParameterStatement(connection, instrucaoSQL, ResultSet.TYPE_SCROLL_INSENSITIVE);
		stmt.setTimestamp("data_inicio", new Timestamp(DateUtil.inicioFecha(controller.getDataInicial().getValue()).getTime()));
		stmt.setTimestamp("data_fim", new Timestamp(DateUtil.inicioFecha(controller.getDataFinal().getValue()).getTime()));
		return stmt;
	}

	private String getQueryTrechosPorLinha() {
		StringBuilder query = new StringBuilder();
		query.append("select sum(coalesce(bo.qtde, 0)) as qtde, ");
		query.append("r.indsentidoida, ");
		query.append("pco.codigo cod_origem, pcd.codigo cod_destino, ");
		query.append("r.ruta_id, ct.numsecuencia ");
		query.append("from corrida_tramo ct ");
		query.append("inner join corrida c on ct.corrida_id = c.corrida_id ");
		query.append("                    and ct.feccorrida  = c.feccorrida ");
		query.append("inner join ruta_combinacion rc on ct.tramo_id = rc.tramo_id ");
		query.append("inner join ruta r on rc.ruta_id = r.ruta_id ");
		query.append("left join parada_cod_orgaoconcedente pco on ct.origen_id = pco.parada_id ");
		query.append("left join parada_cod_orgaoconcedente pcd on ct.destino_id = pcd.parada_id ");
		query.append("left join ( ");
		query.append("			select count(*) qtde, corrida_id, ");
		query.append("			feccorrida, origen_id, ruta_id ");
		query.append("			from boleto b ");
		query.append("			where b.indstatusboleto = 'V'  ");
		query.append("			and b.motivocancelacion_id is null ");
		query.append("			group by corrida_id, feccorrida, ");
		query.append("			origen_id, ruta_id) bo on ct.corrida_id = bo.corrida_id ");
		query.append("			                        and ct.feccorrida = bo.feccorrida ");
		query.append("			                        and ct.origen_id = bo.origen_id ");
		query.append("			                        and r.ruta_id = bo.ruta_id ");
		query.append("where r.ruta_id in("+getIdsRuta()+") ");
		query.append("and ct.feccorrida between :data_inicio and :data_fim ");
		query.append("group by r.indsentidoida, ");
		query.append("pco.codigo, pcd.codigo, ");
		query.append("r.ruta_id, ct.numsecuencia ");
		query.append("order by r.ruta_id, ct.numsecuencia ");
		return query.toString();
	}
	
	private String getQueryReceitasPorLinha() {
		StringBuilder query = new StringBuilder();
		query.append("select sum(b.preciopagado) receita, b.ruta_id ");
		query.append("from boleto b ");
		query.append("where b.indstatusboleto = 'V'   ");
		query.append("and b.motivocancelacion_id is null ");
		query.append("and b.ruta_id in("+getIdsRuta()+") ");
		query.append("and b.feccorrida between :data_inicio and :data_fim ");
		query.append("group by b.ruta_id ");
		return query.toString();
	}
	
	private String getQueryViagensExtrasPorLinha() {
		StringBuilder query = new StringBuilder();
		query.append("select r.ruta_id, r.indsentidoida, ");
		query.append("extract(day from c.fechorsalida) dia, ");
		query.append("to_char(c.fechorsalida, 'hh24:mi') horario ");
		query.append("from corrida c ");
		query.append("inner join ruta r on c.ruta_id = r.ruta_id ");
		query.append("where c.feccorrida between :data_inicio and :data_fim ");
		query.append("and c.tiposervicio_id = 2 ");
		query.append("and r.ruta_id in("+getIdsRuta()+") ");
		return query.toString();
	}

	private String getIdsRuta() {
		EspecializaLista<Ruta> especializaLista = new EspecializaLista<Ruta>(Ruta.class, controller.getLinhaSelList(), "getRutaId");
		return especializaLista.obtemIds();
	}

}
