/**
 * 
 */
package com.rjconsultores.ventaboletos.relatorios.impl;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zkoss.util.resource.Labels;
import org.zkoss.zul.Messagebox;

import com.rjconsultores.ventaboletos.dao.ConstanteDAO;
import com.rjconsultores.ventaboletos.entidad.Constante;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.ArrayDataSource;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

import bsh.StringUtil;

public class RelatorioDemandasDetalhadoNovoLayout extends RelatorioDemandas {
	public final String VENDA_EM_PE = "00";
	
	public RelatorioDemandasDetalhadoNovoLayout(Map<String, Object> parametros, Connection conexao, final Boolean filtrarCrianca, final Boolean filtrarEmPe, final ConstanteDAO constanteDao) 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();

				Calendar dataInicial = Calendar.getInstance();
				dataInicial.setTime((Date) parametros.get("DATA_INICIAL"));

				Calendar dataFinal = Calendar.getInstance();
				dataFinal.setTime((Date) parametros.get("DATA_FINAL"));

				Calendar horaInicial = Calendar.getInstance();
				if (parametros.get("HORA_INICIAL") != null)
					horaInicial.setTime((Date) parametros.get("HORA_INICIAL"));

				Calendar horaFinal = Calendar.getInstance();
				if (parametros.get("HORA_FINAL") != null)
					horaFinal.setTime((Date) parametros.get("HORA_FINAL"));

				SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

				StringBuilder sql = new StringBuilder();
				
				sql.append(" with vendidos as ( ");
				
				sql.append("select ");
				sql.append("  trunc(co.feccorrida) as data_corrida, ");
				sql.append("  trunc(co.fechorsalida) as data, ");
				sql.append("  r.descruta as linha, ");
				sql.append("  r.numruta as codlinha, ");
				sql.append("  co.corrida_id as servico, ");
				sql.append("  case when ((ori.indvisibleinternet is null or ori.indvisibleinternet = 1) ");
				sql.append("      and (des.indvisibleinternet is null or  des.indvisibleinternet = 1)) then 'SIM' else 'NÃO' end as internet, ");
				sql.append("   co.fechorsalida as horario, ");
				sql.append("  ori.descparada as origem, ");
				sql.append("  des.descparada as destino, ");
				sql.append("  cs.descclase as classe, ");
				sql.append("  da.cantasientos as capacidade, ");
				sql.append("  count(bo.boleto_id) as ocupacao, ");
				sql.append("  ts.descservicio as tipo_servico, ");
				sql.append("  nvl(ct.plataforma,'') AS plataforma, ");
				sql.append("  e.nombempresa as empresa, ");
				sql.append("  r.INDSENTIDOIDA     AS sentido ");

				sql.append("from boleto bo ");
				sql.append("  join corrida co on co.corrida_id = bo.corrida_id and co.feccorrida = bo.feccorrida ");
				sql.append("  join ruta r on co.ruta_id = r.ruta_id ");
				sql.append("  left join empresa e on  e.empresa_id = bo.empresacorrida_id ");
				sql.append("  join parada ori on ori.parada_id = co.origen_id ");
				sql.append("  join parada des on des.parada_id = co.destino_id ");
				sql.append("  join clase_servicio cs on cs.claseservicio_id = co.claseservicio_id ");
				sql.append("  join rol_operativo ro on ro.roloperativo_id = co.roloperativo_id ");
				sql.append("  join diagrama_autobus da on ro.diagramaautobus_id = da.diagramaautobus_id ");
				sql.append("  join tipo_servicio ts on ts.tiposervicio_id = co.tiposervicio_id ");
				sql.append("  left join corrida_tramo ct on ct.corrida_id = bo.corrida_id and ct.feccorrida = bo.feccorrida and ct.numsecuencia = 1 and ct.activo = 1  ");
				sql.append("  where bo.motivocancelacion_id is null and bo.numasiento is not null and bo.indstatusoperacion = 'F' ");
				if (parametros.get("HORA_INICIAL") == null && parametros.get("HORA_FINAL") == null) {
					sql.append("  and co.fechorsalida >= :DATA_INICIAL and co.fechorsalida <= :DATA_FINAL ");
				}
				
				sql.append("  and co.activo = 1 and bo.activo = 1 and r.activo = 1 and e.activo = 1 and ori.activo = 1 and  ");
				sql.append("  des.activo = 1 and cs.activo = 1 and ro.activo = 1 and da.activo = 1 and ts.activo = 1  ");
				
				if (filtrarCrianca){
					Constante idGratuidadeCrianca = constanteDao.buscarPorNomeConstante("CRIANÇA GRATUIDADE");
					if (idGratuidadeCrianca != null && StringUtils.isNotBlank(idGratuidadeCrianca.getValorconstante())){
						sql.append(" and bo.categoria_id != "+ idGratuidadeCrianca.getValorconstante() +" ");
					} else {
						Messagebox.show(
								Labels.getLabel("relatorioDemandasController.ConstanteGratuidadeError"),
								Labels.getLabel("relatorioDemandasController.window.title"),
								Messagebox.OK, Messagebox.ERROR);
					}
				}
				
				if (filtrarEmPe){
					sql.append(" and bo.numasiento != '"+VENDA_EM_PE+"' ");
				}
				
				sql.append((parametros.get("RUTA_ID") != null) ? " and r.ruta_id  = :RUTA_ID  " : "");
				sql.append((parametros.get("EMPRESA_ID") != null) ? " and e.empresa_id = :EMPRESA_ID " : "");
				sql.append((parametros.get("PARADA_ID") != null) ? " and bo.origen_id = :PARADA_ID " : "");
				sql.append((parametros.get("PARADA_ID") != null) ? " and ori.parada_id =:PARADA_ID " : "");
				sql.append((parametros.get("TIPO_SERVICO") != null) ? " and ts.tiposervicio_id = :TIPO_SERVICO " : "");

				if (parametros.get("HORA_INICIAL") != null && parametros.get("HORA_FINAL") != null) {
					sql.append(" AND ");
					sql.append(" ( ");
					do {
						mesclarDataHora(dataInicial, horaInicial);
						sql.append(" bo.fechorviaje between to_date('" + format.format(dataInicial.getTime()) + "', 'dd/MM/yyyy HH24:MI:ss') ");
						mesclarDataHora(dataInicial, horaFinal);
						sql.append(" and to_date('" + format.format(dataInicial.getTime()) + "', 'dd/MM/yyyy HH24:MI:ss')");
						dataInicial.add(Calendar.DAY_OF_MONTH, 1);
						if (!dataInicial.after(dataFinal)) {
							sql.append(" or ");
						}

					} while (!dataInicial.after(dataFinal));
					sql.append("   ) ");
				}
				
				sql.append("group by co.feccorrida, co.fechorsalida, r.descruta, r.numruta, co.corrida_id,  ");
				sql.append("  case when ((ori.indvisibleinternet is null or ori.indvisibleinternet = 1) ");
				sql.append("    and (des.indvisibleinternet is null or  des.indvisibleinternet = 1)) then 'SIM' else 'NÃO' end, ");
				sql.append("   ori.descparada, des.descparada, cs.descclase, ");
				sql.append("  da.cantasientos, ts.descservicio, ct.plataforma, e.nombempresa, r.INDSENTIDOIDA  ");
				sql.append("order by data, horario, servico, linha,  origem, destino , plataforma");
				
				sql.append(" ), nao_vendidos as ( ");
				
				
				sql.append(" SELECT distinct TRUNC(co.FECHORSALIDA) AS data_corrida, ");
				sql.append("   TRUNC(co.FECHORSALIDA)  AS data, ");
				sql.append("   r.descruta                AS linha, ");
				sql.append("   r.numruta                 AS codlinha, ");
				sql.append("   co.corrida_id             AS servico, ");
				sql.append("   CASE ");
				sql.append("     WHEN ((ori.indvisibleinternet IS NULL ");
				sql.append("    OR ori.indvisibleinternet      = 1) ");
				sql.append("AND (des.indvisibleinternet   IS NULL ");
				sql.append("OR des.indvisibleinternet      = 1)) ");
				sql.append("THEN 'SIM' ");
				sql.append("ELSE 'NÃO' ");
				sql.append("END                 AS internet, ");
				sql.append("co.FECHORSALIDA      AS horario, ");
				sql.append("ori.descparada      AS origem, ");
				sql.append("  des.descparada      AS destino, ");
				sql.append(" cs.descclase        AS classe, ");
				sql.append(" da.cantasientos     AS capacidade, ");
				sql.append(" 0 AS ocupacao, ");
				sql.append(" ts.descservicio     AS tipo_servico, ");
				sql.append("  nvl(ct.plataforma,'') AS plataforma, ");
				sql.append(" e.nombempresa       AS empresa, ");
				sql.append(" r.INDSENTIDOIDA     AS sentido ");	
				sql.append(" FROM corrida co "); 
				sql.append(" JOIN ruta r ");
				sql.append(" ON co.ruta_id = r.ruta_id ");
				sql.append(" LEFT JOIN empresa e ");
				sql.append(" ON e.empresa_id = co.empresacorrida_id ");
				sql.append(" JOIN parada ori ");
				sql.append(" ON ori.parada_id = co.origen_id ");
				sql.append(" JOIN parada des ");
				sql.append(" ON des.parada_id = co.destino_id ");
				sql.append(" JOIN clase_servicio cs ");
				sql.append(" ON cs.claseservicio_id = co.claseservicio_id ");
				sql.append(" JOIN rol_operativo ro ");
				sql.append(" ON ro.roloperativo_id = co.roloperativo_id ");
				sql.append(" JOIN diagrama_autobus da ");
				sql.append(" ON ro.diagramaautobus_id = da.diagramaautobus_id ");
				sql.append(" JOIN tipo_servicio ts ");
				sql.append(" ON ts.tiposervicio_id        = co.tiposervicio_id ");
				sql.append(" left join corrida_tramo ct on ct.corrida_id = co.corrida_id and ct.feccorrida = co.feccorrida and ct.numsecuencia = 1 and ct.activo = 1 ");
				sql.append(" WHERE co.activo              = 1 ");
				if (parametros.get("HORA_INICIAL") == null && parametros.get("HORA_FINAL") == null) {
					sql.append("  and co.FECHORSALIDA           >= :DATA_INICIAL and co.FECHORSALIDA          <= :DATA_FINAL ");
				}
				
				sql.append((parametros.get("EMPRESA_ID") != null) ? " and e.empresa_id = :EMPRESA_ID " : "");
				sql.append((parametros.get("RUTA_ID") != null) ? " and r.ruta_id  = :RUTA_ID  " : "");
				sql.append((parametros.get("PARADA_ID") != null) ? " and co.origen_id = :PARADA_ID " : "");
				sql.append((parametros.get("PARADA_ID") != null) ? " and ori.parada_id =:PARADA_ID " : "");
				sql.append((parametros.get("TIPO_SERVICO") != null) ? " and ts.tiposervicio_id = :TIPO_SERVICO " : "");
				
				sql.append("  and (co.CORRIDA_ID, co.feccorrida) not in (select servico, data_corrida from vendidos ) ");
				
				sql.append("  and co.activo = 1 and r.activo = 1 and e.activo = 1 and ori.activo = 1 and des.activo = 1 and  ");
				sql.append("  cs.activo = 1 and ro.activo = 1 and da.activo = 1 and ts.activo = 1  ");
				
				if (parametros.get("HORA_INICIAL") != null && parametros.get("HORA_FINAL") != null) {
					sql.append(" AND ");
					sql.append(" ( ");
					do {
						mesclarDataHora(dataInicial, horaInicial);
						sql.append(" co.FECCORRIDA between to_date('" + format.format(dataInicial.getTime()) + "', 'dd/MM/yyyy HH24:MI:ss') ");
						mesclarDataHora(dataInicial, horaFinal);
						sql.append(" and to_date('" + format.format(dataInicial.getTime()) + "', 'dd/MM/yyyy HH24:MI:ss')");
						dataInicial.add(Calendar.DAY_OF_MONTH, 1);
						if (!dataInicial.after(dataFinal)) {
							sql.append(" or ");
						}

					} while (!dataInicial.after(dataFinal));
					sql.append("   ) ");
				}
				
				sql.append(" )select ");
				sql.append(" DATA_CORRIDA, DATA, LINHA, CODLINHA, SERVICO, INTERNET, HORARIO, ORIGEM, DESTINO, CLASSE, CAPACIDADE, SUM(OCUPACAO) OCUPACAO, TIPO_SERVICO, EMPRESA, SENTIDO, PLATAFORMA ");
				sql.append("  from ( ");
				sql.append(" select * from vendidos v union select  * from  nao_vendidos )  ");
				sql.append(" GROUP BY DATA_CORRIDA, DATA, LINHA, CODLINHA, SERVICO, INTERNET, HORARIO, ORIGEM, DESTINO, CLASSE, CAPACIDADE,  TIPO_SERVICO, EMPRESA, SENTIDO, PLATAFORMA ");
				sql.append(" order by data, horario, servico, linha,  origem, destino, plataforma  ");
				

				NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql.toString());
				if (parametros.get("EMPRESA_ID") != null)
					stmt.setInt("EMPRESA_ID", Integer.valueOf(parametros.get("EMPRESA_ID").toString()));

				if (parametros.get("PARADA_ID") != null)
					stmt.setInt("PARADA_ID", Integer.valueOf(parametros.get("PARADA_ID").toString()));

				if (parametros.get("RUTA_ID") != null)
					stmt.setInt("RUTA_ID", Integer.valueOf(parametros.get("RUTA_ID").toString()));

				if (parametros.get("TIPO_SERVICO") != null)
					stmt.setInt("TIPO_SERVICO", Integer.valueOf(parametros.get("TIPO_SERVICO").toString()));

				if (parametros.get("HORA_INICIAL") == null && parametros.get("HORA_FINAL") == null) {
					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()));
				}

				ResultSet rset = stmt.executeQuery();
				while (rset.next()) {
					Map<String, Object> dataResult = new HashMap<String, Object>();
					dataResult.put("DATA", rset.getDate("DATA"));
					dataResult.put("LINHA", rset.getString("LINHA"));
					dataResult.put("SERVICO", rset.getBigDecimal("SERVICO"));
					dataResult.put("INTERNET", rset.getString("INTERNET"));
					dataResult.put("HORARIO", rset.getTimestamp("HORARIO"));
					dataResult.put("ORIGEM", rset.getString("ORIGEM"));
					dataResult.put("DESTINO", rset.getString("DESTINO"));
					dataResult.put("CLASSE", rset.getString("CLASSE"));
					dataResult.put("CAPACIDADE", rset.getInt("CAPACIDADE"));
					dataResult.put("TIPO_SERVICO", rset.getString("TIPO_SERVICO"));
					dataResult.put("PLATAFORMA", rset.getString("PLATAFORMA"));
					dataResult.put("OCUPACAO", rset.getInt("OCUPACAO"));
					dataResult.put("EMPRESA", rset.getString("EMPRESA"));
					dataResult.put("CODLINHA", rset.getString("CODLINHA"));
					dataResult.put("SENTIDO", rset.getString("SENTIDO"));
					this.dados.add(dataResult);
				}
				this.resultSet = rset;

			}
		});
	}
}
