package com.rjconsultores.ventaboletos.relatorios.impl;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.rjconsultores.ventaboletos.entidad.Estado;
import com.rjconsultores.ventaboletos.entidad.PuntoVenta;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.DataSource;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.DevolucaoBilhetes;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

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

public class RelatorioDevolucaoBilhetesAnalitico extends Relatorio {
	
	private static Logger log = LogManager.getLogger(RelatorioDevolucaoBilhetesAnalitico.class);

	public RelatorioDevolucaoBilhetesAnalitico(Map<String, Object> parametros, Connection conexao) throws Exception {
		super(parametros, conexao);

		this.setCustomDataSource(new DataSource(this) {
			@SuppressWarnings("unchecked")
			@Override
			public void initDados() throws Exception {

				Connection conexao = this.relatorio.getConexao();
				Map<String, Object> parametros = this.relatorio.getParametros();

				List<PuntoVenta> lsPuntoVenta = parametros.get("PUNTOVENTAS") == null ? new ArrayList<PuntoVenta>() : (ArrayList<PuntoVenta>) parametros.get("PUNTOVENTAS");
				List<Estado> lsEstado = parametros.get("ESTADOS") == null ? new ArrayList<Estado>() : (ArrayList<Estado>) parametros.get("ESTADOS");
				Integer empresaId = parametros.get("EMPRESA_ID") == null ? null : (Integer) parametros.get("EMPRESA_ID");
				Date dataVendaInicial = parametros.get("dataVendaInicial") == null ? null : (Date) parametros.get("dataVendaInicial");
				Date dataVendaFinal = parametros.get("dataVendaFinal") == null ? null : (Date) parametros.get("dataVendaFinal");
				Date dataDevolucaoInicial = parametros.get("dataDevolucaoInicial") == null ? null : (Date) parametros.get("dataDevolucaoInicial");
				Date dataDevolucaoFinal = parametros.get("dataDevolucaoFinal") == null ? null : (Date) parametros.get("dataDevolucaoFinal");
				Boolean isApenasBilhetesImpressos = parametros.get("isApenasBilhetesImpressos") == null ? Boolean.FALSE : Boolean.valueOf(parametros.get("isApenasBilhetesImpressos").toString());

				String puntoVentas = null;
				for (PuntoVenta pv : lsPuntoVenta) {
					if (lsPuntoVenta.indexOf(pv) == 0) {
						puntoVentas = "" + pv.getPuntoventaId();
					} else {
						puntoVentas += ", " + pv.getPuntoventaId();
					}
				}

				String estados = null;
				for (Estado e : lsEstado) {
					if (lsEstado.indexOf(e) == 0) {
						estados = "" + e.getEstadoId();
					} else {
						estados += ", " + e.getEstadoId();
					}
				}

				String sql = getSql(empresaId, puntoVentas, estados, dataVendaInicial, dataVendaFinal, dataDevolucaoInicial, dataDevolucaoFinal, isApenasBilhetesImpressos);

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

				if(dataVendaInicial != null) {
					stmt.setString("dataVendaInicial", DateUtil.getStringDate(dataVendaInicial, "dd/MM/yyyy HH:mm"));
				}
				
				if(dataVendaFinal != null) {
					stmt.setString("dataVendaFinal", DateUtil.getStringDate(dataVendaFinal, "dd/MM/yyyy HH:mm"));
				}
				
				if(dataDevolucaoInicial != null) {
					stmt.setString("dataDevolucaoInicial", DateUtil.getStringDate(dataDevolucaoInicial, "dd/MM/yyyy HH:mm"));
				}
				
				if(dataDevolucaoFinal != null) {
					stmt.setString("dataDevolucaoFinal", DateUtil.getStringDate(dataDevolucaoFinal, "dd/MM/yyyy HH:mm"));
				}

				rset = stmt.executeQuery();

				List<DevolucaoBilhetes> lsDev = new ArrayList<DevolucaoBilhetes>();
				while (rset.next()) {

					DevolucaoBilhetes db = new DevolucaoBilhetes();
					db.setFecVenta(rset.getDate("FECHOR_VENTA"));
					db.setFecDevolucao(rset.getDate("FECHOR_DEVOLUCAO"));
					db.setUf(rset.getString("UF"));
					db.setNumFolioSistema(rset.getString("NUMFOLIOSISTEMA"));
					db.setEmpresaId(rset.getInt("EMPRESA_ID"));
					db.setEmpresa((String) rset.getObject("NOMB_EMPRESA"));
					db.setNumpuntoventa((String) rset.getObject("NUMPUNTOVENTA"));
					db.setNombpuntoventa((String) rset.getObject("NOMBPUNTOVENTA"));
					db.setPrecioBase((BigDecimal) rset.getObject("PRECIOBASE"));
					db.setPrecioPagado((BigDecimal) rset.getObject("PRECIOPAGADO"));
					db.setMulta((BigDecimal) rset.getObject("MULTA"));
					
					lsDev.add(db);
				}

				setLsDadosRelatorio(lsDev);
			}
		});

	}

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

	private String getSql(Integer empresaId, String puntoVentas, String estados, Date dataVendaInicial, Date dataVendaFinal, Date dataDevolucaoInicial, Date dataDevolucaoFinal, Boolean isApenasBilhetesImpressos) {

		StringBuilder sql = new StringBuilder();
		sql.append("SELECT E.NOMBEMPRESA AS NOMB_EMPRESA, ");
		sql.append("  E.EMPRESA_ID AS EMPRESA_ID, ");
		sql.append("  PTV.NUMPUNTOVENTA AS NUMPUNTOVENTA, ");
		sql.append("  PTV.NOMBPUNTOVENTA AS NOMBPUNTOVENTA, ");
		sql.append("  bori.fechorventa AS fechor_venta, ");
		sql.append("  b.fechorventa AS fechor_devolucao, ");
		sql.append("  coalesce(b.numfoliosistema, b.numoperacion) AS numfoliosistema, ");
		sql.append("  est.cveestado AS uf, ");
		sql.append("  b.preciobase AS preciobase, ");
		sql.append("  b.preciopagado AS preciopagado, ");		
		sql.append("  sum( coalesce(EE.IMPINGRESO,0)) as multa ");
		sql.append("FROM BOLETO B ");
		sql.append("INNER JOIN MARCA M ON M.MARCA_ID = B.MARCA_ID AND M.ACTIVO = 1 ");
		sql.append("INNER JOIN EMPRESA E ON E.EMPRESA_ID = M.EMPRESA_ID ");
		sql.append("INNER JOIN PUNTO_VENTA PTV ON PTV.PUNTOVENTA_ID = B.PUNTOVENTA_ID ");
		sql.append("INNER JOIN PARADA ORI ON (B.ORIGEN_ID = ORI.PARADA_ID ) ");
		sql.append("INNER JOIN PARADA DES ON (B.DESTINO_ID = DES.PARADA_ID ) ");
		sql.append("INNER JOIN CIUDAD CO ON (CO.CIUDAD_ID = ORI.CIUDAD_ID ) ");
		sql.append("INNER JOIN CIUDAD CD ON (CD.CIUDAD_ID = DES.CIUDAD_ID ) ");
		sql.append("INNER JOIN ESTADO EST ON EST.ESTADO_ID = CO.ESTADO_ID ");
		sql.append("LEFT JOIN BOLETO BORI ON BORI.BOLETO_ID = B.BOLETOORIGINAL_ID ");
		sql.append("LEFT JOIN evento_extra ee on b.boletooriginal_id = ee.boleto_id ");
		sql.append("WHERE B.MOTIVOCANCELACION_ID IN (31,32,10,37,99,36) ");
		sql.append("AND B.INDSTATUSBOLETO = 'C' ");
		sql.append("AND B.INDCANCELACION = 1 ");

		if(isApenasBilhetesImpressos) {
			sql.append("AND B.NUMFOLIOPREIMPRESO IS NOT NULL ");
		}
		
		if(dataVendaInicial != null) {
			sql.append("AND BORI.FECHORVENTA >= TO_DATE(:dataVendaInicial,'DD/MM/YYYY HH24:MI') ");
		}
		
		if(dataVendaFinal != null) {
			sql.append("AND BORI.FECHORVENTA <= TO_DATE(:dataVendaFinal,'DD/MM/YYYY HH24:MI') ");
		}
		
		if(dataDevolucaoInicial != null) {
			sql.append("AND B.FECHORVENTA >= TO_DATE(:dataDevolucaoInicial,'DD/MM/YYYY HH24:MI') ");
		}
		
		if(dataDevolucaoFinal != null) {
			sql.append("AND B.FECHORVENTA <= TO_DATE(:dataDevolucaoFinal,'DD/MM/YYYY HH24:MI') ");
		}
		
		sql.append("AND B.CATEGORIA_ID NOT IN (SELECT VALORCONSTANTE FROM CONSTANTE WHERE NOMBCONSTANTE = 'GRATUIDADE_CRIANCA') ");
		sql.append(estados == null ? "" : "AND EST.ESTADO_ID IN (" + estados + ") ");
		sql.append(puntoVentas == null ? "" : "AND PTV.PUNTOVENTA_ID IN (" + puntoVentas + ") ");
		sql.append(empresaId == null ? "" : "AND E.EMPRESA_ID IN (" + empresaId + ") ");
		
		sql.append(" GROUP BY ");
		sql.append("   e.nombempresa, ");
		sql.append("   e.empresa_id, ");
		sql.append("   ptv.numpuntoventa, ");
		sql.append("   ptv.nombpuntoventa, ");
		sql.append("   bori.fechorventa, ");
		sql.append("   b.fechorventa, ");
		sql.append("   coalesce(b.numfoliosistema, b.numoperacion), ");
		sql.append("   est.cveestado, ");
		sql.append("   b.preciobase, ");
		sql.append("   b.preciopagado ");

		sql.append("ORDER BY NOMB_EMPRESA, FECHOR_VENTA ");

		return sql.toString();
	}

	@Override
	protected void processaParametros() throws Exception {
	}

}
