package com.rjconsultores.ventaboletos.relatorios.impl;

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

import com.rjconsultores.ventaboletos.entidad.Constante;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.ArrayDataSource;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.service.ConstanteService;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

public class RelatorioCancelamentoVendaCartao extends Relatorio {

	private ConstanteService constanteService;

	public RelatorioCancelamentoVendaCartao(Map<String, Object> parametros, Connection conexao, ConstanteService constanteService) throws Exception {
		super(parametros, conexao);
		this.constanteService = constanteService;

		this.setCustomDataSource(new ArrayDataSource(this) {

			@Override
			public void initDados() throws Exception {
				Connection conexao = this.relatorio.getConexao();
				Map<String, Object> parametros = this.relatorio.getParametros();
				final Integer CARTAO_CREDITO = 2;
				String sql = getSql();

				NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql);

				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()));
				stmt.setInt("formaPagoCredito", CARTAO_CREDITO);
				stmt.setInt("empresaId", Integer.valueOf(parametros.get("EMPRESA_ID") + ""));

				ResultSet rset = stmt.executeQuery();

				while (rset.next()) {
					Map<String, Object> dataResult = new HashMap<String, Object>();
					dataResult.put("estabelecimento", rset.getString("nombpuntoventa"));
					dataResult.put("pv_cancelamento", rset.getString("pv_cancel"));

					if (rset.getString("numtarjeta") != null) {
						dataResult.put("cartao", rset.getString("numtarjeta").replace('*', ' ').trim());
					}

					dataResult.put("datavenda", rset.getDate("fechorventa"));
					dataResult.put("datadevolucao", rset.getDate("datadevolucao"));
					dataResult.put("valor_total_compra", rset.getBigDecimal("valor_cesta"));
					dataResult.put("valorvenda", rset.getBigDecimal("valor_venda"));
					dataResult.put("valorcancelar", rset.getBigDecimal("valor_cancelar"));
					dataResult.put("autorizacao", rset.getString("numautorizacion"));
					dataResult.put("motivo", rset.getString("descmotivo"));
					dataResult.put("numerositef", rset.getString("numsitef"));
					dataResult.put("nsu", rset.getString("nsu"));
					dataResult.put("numfoliosistema", rset.getString("numfoliosistema") != null ? rset.getString("numfoliosistema") : "");
					this.dados.add(dataResult);
				}

				this.resultSet = rset;
			}
		});
	}

	@Override
	protected void processaParametros() throws Exception {
	}

	private String getSql() {
		StringBuilder sql = new StringBuilder();

		/* Boletos apenas com venda e cancelamento direto com corrida */
		sql.append("SELECT DISTINCT B.BOLETO_ID, P.NOMBPUNTOVENTA, PO.NOMBPUNTOVENTA AS PV_CANCEL, O.NUMTARJETA, B.FECHORVENTA, PTOVTA.NUMSITEF, ")
				.append("'OCD' AS DESCMOTIVO, O.NUMAUTORIZACION, O.NSU, B.NUMFOLIOSISTEMA, O.FECINC AS DATADEVOLUCAO, O.NUMOPERACION, ")
				.append("(COALESCE(B.PRECIOPAGADO,0) + COALESCE(B.IMPORTEOUTROS,0)+ COALESCE(B.IMPORTEPEDAGIO,0)+ COALESCE(B.IMPORTESEGURO,0) + COALESCE(B.IMPORTETAXAEMBARQUE,0)) AS VALOR_VENDA, ")

				.append("CASE WHEN O.VALOR_TARJETA > 0 ")
				.append("THEN TO_CHAR(COALESCE(O.VALOR_TARJETA,0),'FM9999999.90') ")
				.append("ELSE TO_CHAR(COALESCE(O.VALOR_PAGAR,0),'FM9999999.90') ")
				.append("END AS VALOR_CANCELAR, ")

				.append("(SELECT SUM(COALESCE(B1.PRECIOPAGADO,0) + COALESCE(B1.IMPORTEOUTROS,0) + COALESCE(B1.IMPORTEPEDAGIO,0) + COALESCE(B1.IMPORTESEGURO,0) + COALESCE(B1.IMPORTETAXAEMBARQUE,0)) ")
				.append(" FROM BOLETO B1 ")
				.append(" WHERE B1.NUMOPERACION = B.NUMOPERACION ")
				.append(" AND B1.BOLETOORIGINAL_ID IS NULL ")
				.append(") AS VALOR_CESTA ")
				.append("FROM OCD O ")
				.append("INNER JOIN BOLETO B ON O.BOLETO_ID = B.BOLETO_ID ")
				.append("                    AND B.BOLETOORIGINAL_ID IS NULL ")
				.append("                    AND B.CORRIDA_ID IS NOT NULL ")
				.append("                    AND B.FECCORRIDA IS NOT NULL ")
				.append("INNER JOIN BOLETO_FORMAPAGO BFP ON BFP.BOLETO_ID = B.BOLETO_ID ")
				.append("INNER JOIN PUNTO_VENTA P ON P.PUNTOVENTA_ID = B.PUNTOVENTA_ID ")
				.append("INNER JOIN PTOVTA_EMPRESA PTOVTA ON B.PUNTOVENTA_ID = PTOVTA.PUNTOVENTA_ID ")
				.append("INNER JOIN MARCA M ON M.MARCA_ID = B.MARCA_ID AND M.EMPRESA_ID = PTOVTA.EMPRESA_ID ")
				.append("INNER JOIN PUNTO_VENTA PO ON PO.PUNTOVENTA_ID = O.PUNTOVENTA_ID ")
				.append("WHERE O.FECINC BETWEEN :data_inicial AND :data_final ")
				.append("AND O.NSU is not null ")
				.append("AND BFP.FORMAPAGO_ID = :formaPagoCredito ")
				.append("AND M.EMPRESA_ID = :empresaId ");

		if (parametros.get("NUMPUNTOVENTA") != null) {
			sql.append("AND P.PUNTOVENTA_ID IN (")
					.append(parametros.get("NUMPUNTOVENTA"))
					.append(") ");
		}
		Constante constante = constanteService.buscarPorNomeConstante("PUNTO_VENTA_J3");
		if(constante != null
				&& constante.getActivo()
				&& constante.getValorconstante() != null
				&& !constante.getValorconstante().isEmpty()){
			sql.append("AND (B.PTOVTAVENTA_ID <> ")
			   .append(constante.getValorconstante())
			   .append(" OR B.PUNTOVENTA_ID <> ")
			   .append(constante.getValorconstante())
			   .append(") ");
		}
		sql.append("UNION ALL ");

		/* Boletos com entrega/transferencia/troca antes do cancelamento com corrida */
		sql.append("SELECT DISTINCT B.BOLETO_ID, P.NOMBPUNTOVENTA, PO.NOMBPUNTOVENTA  AS PV_CANCEL, O.NUMTARJETA, B.FECHORVENTA, PTOVTA.NUMSITEF, ")
				.append("'OCD' AS DESCMOTIVO, O.NUMAUTORIZACION, O.NSU, B.NUMFOLIOSISTEMA, O.FECINC AS DATADEVOLUCAO, O.NUMOPERACION, ")
				.append("(COALESCE(B.PRECIOPAGADO,0) + COALESCE(B.IMPORTEOUTROS,0)+ COALESCE(B.IMPORTEPEDAGIO,0)+ COALESCE(B.IMPORTESEGURO,0) + COALESCE(B.IMPORTETAXAEMBARQUE,0)) AS VALOR_VENDA, ")

				.append("CASE WHEN O.VALOR_TARJETA > 0 ")
				.append("THEN TO_CHAR(COALESCE(O.VALOR_TARJETA,0),'FM9999999.90') ")
				.append("ELSE TO_CHAR(COALESCE(O.VALOR_PAGAR,0),'FM9999999.90') ")
				.append("END AS VALOR_CANCELAR, ")

				.append("(SELECT SUM(COALESCE(B1.PRECIOPAGADO,0) + COALESCE(B1.IMPORTEOUTROS,0) + COALESCE(B1.IMPORTEPEDAGIO,0) + COALESCE(B1.IMPORTESEGURO,0) + COALESCE(B1.IMPORTETAXAEMBARQUE,0)) ")
				.append(" FROM BOLETO B1 ")
				.append(" WHERE B1.NUMOPERACION = BR.NUMOPERACION ")
				.append(" AND B1.BOLETOORIGINAL_ID IS NULL ")
				.append(") AS VALOR_CESTA ")
				.append("FROM OCD O ")
				.append("INNER JOIN BOLETO B ON O.BOLETO_ID = B.BOLETO_ID ")
				.append("INNER JOIN BOLETO BR ON BR.BOLETO_ID = B.BOLETOORIGINAL_ID ")
				.append("                     AND BR.CORRIDA_ID IS NOT NULL ")
				.append("                     AND BR.FECCORRIDA IS NOT NULL ")
				.append("INNER JOIN BOLETO_FORMAPAGO BFP ON BFP.BOLETO_ID = B.BOLETO_ID ")
				.append("INNER JOIN PUNTO_VENTA P ON P.PUNTOVENTA_ID = BR.PUNTOVENTA_ID ")
				.append("INNER JOIN PTOVTA_EMPRESA PTOVTA ON BR.PUNTOVENTA_ID = PTOVTA.PUNTOVENTA_ID ")
				.append("INNER JOIN MARCA M ON M.MARCA_ID = BR.MARCA_ID AND M.EMPRESA_ID = PTOVTA.EMPRESA_ID ")
				.append("INNER JOIN PUNTO_VENTA PO ON PO.PUNTOVENTA_ID = O.PUNTOVENTA_ID ")
				.append("WHERE O.FECINC BETWEEN :data_inicial AND :data_final ")
				.append("AND O.NSU is not null ")
				.append("AND BFP.FORMAPAGO_ID = :formaPagoCredito ")
				.append("AND M.EMPRESA_ID = :empresaId ");

		if (parametros.get("NUMPUNTOVENTA") != null) {
			sql.append("AND P.PUNTOVENTA_ID IN (")
					.append(parametros.get("NUMPUNTOVENTA"))
					.append(") ");
		}

		if(constante != null
				&& constante.getActivo()
				&& constante.getValorconstante() != null
				&& !constante.getValorconstante().isEmpty()){
			sql.append("AND (B.PTOVTAVENTA_ID <> ")
			   .append(constante.getValorconstante())
			   .append(" OR B.PUNTOVENTA_ID <> ")
			   .append(constante.getValorconstante())
			   .append(") ");
		}
		sql.append("UNION ALL ");

		/* Boletos apenas com venda e cancelamento direto sem corrida */
		sql.append("SELECT DISTINCT B.BOLETO_ID, P.NOMBPUNTOVENTA, PO.NOMBPUNTOVENTA  AS PV_CANCEL, O.NUMTARJETA, B.FECHORVENTA, PTOVTA.NUMSITEF, ")
				.append("'OCD' AS DESCMOTIVO, O.NUMAUTORIZACION, O.NSU, B.NUMFOLIOSISTEMA, O.FECINC AS DATADEVOLUCAO, O.NUMOPERACION, ")
				.append("(COALESCE(B.PRECIOPAGADO,0) + COALESCE(B.IMPORTEOUTROS,0)+ COALESCE(B.IMPORTEPEDAGIO,0)+ COALESCE(B.IMPORTESEGURO,0) + COALESCE(B.IMPORTETAXAEMBARQUE,0)) AS VALOR_VENDA, ")

				.append("CASE WHEN O.VALOR_TARJETA > 0 ")
				.append("THEN TO_CHAR(COALESCE(O.VALOR_TARJETA,0),'FM9999999.90') ")
				.append("ELSE TO_CHAR(COALESCE(O.VALOR_PAGAR,0),'FM9999999.90') ")
				.append("END AS VALOR_CANCELAR, ")

				.append("(SELECT SUM(COALESCE(B1.PRECIOPAGADO,0) + COALESCE(B1.IMPORTEOUTROS,0) + COALESCE(B1.IMPORTEPEDAGIO,0) + COALESCE(B1.IMPORTESEGURO,0) + COALESCE(B1.IMPORTETAXAEMBARQUE,0)) ")
				.append(" FROM BOLETO B1 ")
				.append(" WHERE B1.NUMOPERACION = B.NUMOPERACION ")
				.append(" AND B1.BOLETOORIGINAL_ID IS NULL ")
				.append(") AS VALOR_CESTA ")
				.append("FROM OCD O ")
				.append("INNER JOIN BOLETO B ON O.BOLETO_ID = B.BOLETO_ID ")
				.append("                    AND B.BOLETOORIGINAL_ID IS NULL ")
				.append("                    AND B.CORRIDA_ID IS NULL ")
				.append("                    AND B.FECCORRIDA IS NULL ")
				.append("INNER JOIN BOLETO_FORMAPAGO BFP ON BFP.BOLETO_ID = B.BOLETO_ID ")
				.append("INNER JOIN PUNTO_VENTA P ON P.PUNTOVENTA_ID = B.PUNTOVENTA_ID ")
				.append("INNER JOIN PTOVTA_EMPRESA PTOVTA ON B.PUNTOVENTA_ID = PTOVTA.PUNTOVENTA_ID ")
				.append("INNER JOIN MARCA M ON M.MARCA_ID = B.MARCA_ID AND M.EMPRESA_ID = PTOVTA.EMPRESA_ID ")
				.append("INNER JOIN PUNTO_VENTA PO ON PO.PUNTOVENTA_ID = O.PUNTOVENTA_ID ")
				.append("WHERE O.FECINC BETWEEN :data_inicial AND :data_final ")
				.append("AND O.NSU is not null ")
				.append("AND BFP.FORMAPAGO_ID = :formaPagoCredito ")
				.append("AND M.EMPRESA_ID = :empresaId ");

		if (parametros.get("NUMPUNTOVENTA") != null) {
			sql.append("AND P.PUNTOVENTA_ID IN (")
					.append(parametros.get("NUMPUNTOVENTA"))
					.append(") ");
		}

		if(constante != null
				&& constante.getActivo()
				&& constante.getValorconstante() != null
				&& !constante.getValorconstante().isEmpty()){
			sql.append("AND (B.PTOVTAVENTA_ID <> ")
			   .append(constante.getValorconstante())
			   .append(" OR B.PUNTOVENTA_ID <> ")
			   .append(constante.getValorconstante())
			   .append(") ");
		}

		sql.append("ORDER BY FECHORVENTA, DATADEVOLUCAO, NUMFOLIOSISTEMA ");

		return sql.toString();
	}

}
