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

import java.math.BigDecimal;
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.relatorios.negocio.CalculoImposto;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.DataSource;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.ExceptionConfiguracao;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

/**
 * @author Bruno H. G. Gouvêa <bruno@rjconsultores.com.br>
 * 
 */
public class RelatorioTaxasLinha extends Relatorio {

	/**
	 * @param parametros
	 * @param conexao
	 * @throws Exception
	 */
	public RelatorioTaxasLinha(Map<String, Object> parametros, Connection conexao) throws Exception {
		super(parametros, conexao);
		CalculoImposto.limpaCache();

		this.setCustomDataSource(false, new DataSource(this) {

			public void initDados() throws Exception {
				Connection conexao = this.relatorio.getConexao();
				Map<String, Object> parametros = this.relatorio.getParametros();
				String puntosVentaIds = (String) parametros.get("NUMPUNTOVENTA");

				String sql = getSql(puntosVentaIds);

				NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql);

				stmt.setInt("TIPO_DATA", (Integer) parametros.get("TIPO_DATA"));
				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()));

				if (parametros.get("EMPRESA_ID") != null)
					stmt.setInt("EMPRESA_ID", (Integer) parametros.get("EMPRESA_ID"));
				else
					stmt.setNull("EMPRESA_ID", java.sql.Types.INTEGER);

				if (parametros.get("ORIGEN_ID") != null)
					stmt.setInt("ORIGEN_ID", (Integer) parametros.get("ORIGEN_ID"));
				else
					stmt.setNull("ORIGEN_ID", java.sql.Types.INTEGER);

				if (parametros.get("DESTINO_ID") != null)
					stmt.setInt("DESTINO_ID", (Integer) parametros.get("DESTINO_ID"));
				else
					stmt.setNull("DESTINO_ID", java.sql.Types.INTEGER);

				ResultSet rset = stmt.executeQuery();

				this.resultSet = rset;

			}

			public Object valueCustomFields(String fieldName) throws Exception {

				// Se não for pra subtrair o ICMS, realiza o calculo e adiciona o mesmo
				if ((Boolean) this.relatorio.getParametros().get("B_SUBTRAIR_ICMS")) {
					BigDecimal valorIcms = BigDecimal.ZERO;
					String indInterestadual = this.resultSet.getString("INTERESTADUAL");
					Integer idEstado = this.resultSet.getInt("ORIGEM_ESTADO_ID");
					Integer empresaId = this.resultSet.getInt("EMPRESA_ID");

					try {
						BigDecimal importeTaxaEmbarque = resultSet.getBigDecimal("IMPORTETAXAEMBARQUE") == null ? BigDecimal.ZERO : resultSet.getBigDecimal("IMPORTETAXAEMBARQUE");
						BigDecimal importePedagio = resultSet.getBigDecimal("IMPORTEPEDAGIO") == null ? BigDecimal.ZERO : resultSet.getBigDecimal("IMPORTEPEDAGIO");
						BigDecimal importeSeguro = resultSet.getBigDecimal("IMPORTESEGURO") == null ? BigDecimal.ZERO : resultSet.getBigDecimal("IMPORTESEGURO");

						BigDecimal totalEmbarque = resultSet.getBigDecimal("TOTAL_EMBARQUE") == null ? BigDecimal.ZERO : resultSet.getBigDecimal("TOTAL_EMBARQUE");
						BigDecimal totalPedagio = resultSet.getBigDecimal("TOTAL_PEDAGIO") == null ? BigDecimal.ZERO : resultSet.getBigDecimal("TOTAL_PEDAGIO");
						BigDecimal totalSeguro = resultSet.getBigDecimal("TOTAL_SEGURO") == null ? BigDecimal.ZERO : resultSet.getBigDecimal("TOTAL_SEGURO");

						if (fieldName.equals("IMPORTETAXAEMBARQUE") && !!importeTaxaEmbarque.equals(BigDecimal.ZERO)) {
							valorIcms = CalculoImposto.getValorImposto(this.relatorio.getConexao(), idEstado, empresaId, indInterestadual, BigDecimal.ZERO, BigDecimal.ZERO, importeTaxaEmbarque, BigDecimal.ZERO);
							return importeTaxaEmbarque.subtract(valorIcms);

						} else if (fieldName.equals("IMPORTEPEDAGIO") && !importePedagio.equals(BigDecimal.ZERO)) {
							valorIcms = CalculoImposto.getValorImposto(this.relatorio.getConexao(), idEstado, empresaId, indInterestadual, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, importePedagio);
							return importePedagio.subtract(valorIcms);

						} else if (fieldName.equals("IMPORTESEGURO") && !importeSeguro.equals(BigDecimal.ZERO)) {
							valorIcms = CalculoImposto.getValorImposto(this.relatorio.getConexao(), idEstado, empresaId, indInterestadual, BigDecimal.ZERO, importeSeguro, BigDecimal.ZERO, BigDecimal.ZERO);
							return importeSeguro.subtract(valorIcms);

						} else if (fieldName.equals("TOTAL_EMBARQUE") && !totalEmbarque.equals(BigDecimal.ZERO)) {
							valorIcms = CalculoImposto.getValorImposto(this.relatorio.getConexao(), idEstado, empresaId, indInterestadual, BigDecimal.ZERO, totalEmbarque, BigDecimal.ZERO, BigDecimal.ZERO);
							return totalEmbarque.subtract(valorIcms);

						} else if (fieldName.equals("TOTAL_PEDAGIO") && !totalPedagio.equals(BigDecimal.ZERO)) {
							valorIcms = CalculoImposto.getValorImposto(this.relatorio.getConexao(), idEstado, empresaId, indInterestadual, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, totalPedagio);
							return totalPedagio.subtract(valorIcms);

						} else if (fieldName.equals("TOTAL_SEGURO") && !totalSeguro.equals(BigDecimal.ZERO)) {
							valorIcms = CalculoImposto.getValorImposto(this.relatorio.getConexao(), idEstado, empresaId, indInterestadual, BigDecimal.ZERO, totalSeguro, BigDecimal.ZERO, BigDecimal.ZERO);
							return totalSeguro.subtract(valorIcms);

						}
					} catch (Exception e) {
						if (e instanceof ExceptionConfiguracao)
							this.relatorio.addInfoMsg(e.getMessage());
						else
							throw e;
					}
				}

				return null;
			}
		});
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio#processaParametros()
	 */
	@Override
	protected void processaParametros() throws Exception {
	}

	public HashMap<String, Object> getConfigImposto(Integer idEstado, Integer puntoVentaId) throws Exception {
		HashMap<String, Object> cacheConfig = null;

		try {
			cacheConfig = (HashMap<String, Object>) CalculoImposto.getConfigImpostoByEstadoOrigem(this.getConexao(), idEstado, puntoVentaId);
		} catch (Exception e) {
			if (e instanceof ExceptionConfiguracao)
				this.addInfoMsg(e.getMessage());
			else
				throw e;
		}

		return cacheConfig;
	}

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

		sql.append(" SELECT RT.PREFIXO, ");
		sql.append("        PO.DESCPARADA CIDADE_ORIGEM, ");
		sql.append("        PD.DESCPARADA CIDADE_DESTINO, ");
		sql.append("        CJ.IMPORTETAXAEMBARQUE, ");
		sql.append("        CJ.IMPORTEPEDAGIO, ");
		sql.append("        CJ.IMPORTESEGURO, ");
		sql.append("        EM.NOMBEMPRESA, ");
		sql.append("        EM.EMPRESA_ID, ");
		sql.append("        CJ.PUNTOVENTA_ID, ");
		sql.append("        PV.NOMBPUNTOVENTA, ");
		sql.append("        SUM(CASE WHEN (CJ.IMPORTETAXAEMBARQUE>0 and cj.motivocancelacion_id is null ) THEN 1 WHEN (CJ.IMPORTETAXAEMBARQUE>0 and cj.motivocancelacion_id is not null ) then -1 ELSE 0 END) EMBARQUE_VENDIDOS, ");
		sql.append("        SUM(CASE WHEN (CJ.IMPORTEPEDAGIO>0 and cj.motivocancelacion_id is null) THEN 1 WHEN (CJ.IMPORTEPEDAGIO>0 and cj.motivocancelacion_id is not null) THEN -1 ELSE 0 END) PEDAGIO_VENDIDOS, ");
		sql.append("        SUM(CASE WHEN (CJ.IMPORTESEGURO>0 and cj.motivocancelacion_id is null) THEN 1 WHEN (CJ.IMPORTESEGURO>0 and cj.motivocancelacion_id is not null) THEN -1 ELSE 0 END) SEGURO_VENDIDOS, ");
		sql.append("        CO.ESTADO_ID ORIGEM_ESTADO_ID, ");
		sql.append("        CD.ESTADO_ID DESTINO_ESTADO_ID, ");
		sql.append("        CASE ");
		sql.append("          WHEN CO.ESTADO_ID <> CD.ESTADO_ID THEN ");
		sql.append("           'S' ");
		sql.append("          ELSE ");
		sql.append("           'N' ");
		sql.append("        END INTERESTADUAL, ");
		sql.append("        SUM( (case when cj.motivocancelacion_id is null then 1  else -1 end) * CJ.IMPORTETAXAEMBARQUE) TOTAL_EMBARQUE, ");
		sql.append("        SUM( (case when cj.motivocancelacion_id is null then 1  else -1 end) * CJ.IMPORTEPEDAGIO) TOTAL_PEDAGIO, ");
		sql.append("        SUM( (case when cj.motivocancelacion_id is null then 1  else -1 end) * CJ.IMPORTESEGURO) TOTAL_SEGURO ");
		sql.append("   FROM CORRIDA     CR, ");
		sql.append("        RUTA        RT, ");
		sql.append("        PUNTO_VENTA PV, ");
		sql.append("        CAJA        CJ, ");
		sql.append("        PARADA      PO, ");
		sql.append("        PARADA      PD, ");
		sql.append("        CIUDAD      CO, ");
		sql.append("        CIUDAD      CD, ");
		sql.append("        EMPRESA     EM ");
		sql.append("  WHERE CR.RUTA_ID = RT.RUTA_ID ");
		sql.append("   AND (CJ.IMPORTETAXAEMBARQUE>0 OR CJ.IMPORTEPEDAGIO>0 OR CJ.IMPORTESEGURO>0) ");
		sql.append("    AND CJ.CORRIDA_ID = CR.CORRIDA_ID ");
		sql.append("    AND CJ.FECCORRIDA = CR.FECCORRIDA ");
		sql.append("    AND PO.PARADA_ID = CJ.ORIGEN_ID ");
		sql.append("    AND PD.PARADA_ID = CJ.DESTINO_ID ");
		sql.append("    AND PV.PUNTOVENTA_ID = CJ.PUNTOVENTA_ID ");
		sql.append("    AND EM.EMPRESA_ID = CJ.EMPRESACORRIDA_ID ");
		sql.append("    AND CO.CIUDAD_ID = PO.CIUDAD_ID ");
		sql.append("    AND CD.CIUDAD_ID = PD.CIUDAD_ID ");
		sql.append("    AND CJ.INDSTATUSOPERACION = 'F' ");
		sql.append("    AND CJ.INDREIMPRESION = 0 ");
		sql.append("    AND DECODE(:TIPO_DATA, 1, CJ.FECHORVENTA, 2, CJ.FECCORRIDA) BETWEEN ");
		sql.append("        :DATA_INICIAL AND :DATA_FINAL ");
		sql.append("    AND EM.EMPRESA_ID = NVL(:EMPRESA_ID, EM.EMPRESA_ID) ");

		if (!puntosVentaIds.equals("Todas")) {
			sql.append("    AND PV.PUNTOVENTA_ID IN (").append(puntosVentaIds).append(") ");
		}

		sql.append("    AND PO.PARADA_ID = NVL(:ORIGEN_ID, PO.PARADA_ID) ");
		sql.append("    AND PD.PARADA_ID = NVL(:DESTINO_ID, PD.PARADA_ID) ");

		sql.append("  GROUP BY RT.PREFIXO, ");
		sql.append("           PO.DESCPARADA, ");
		sql.append("           PD.DESCPARADA, ");
		sql.append("           CJ.IMPORTETAXAEMBARQUE, ");
		sql.append("           CJ.IMPORTEPEDAGIO, ");
		sql.append("           CJ.IMPORTESEGURO, ");
		sql.append("           CO.ESTADO_ID, ");
		sql.append("           CD.ESTADO_ID, ");
		sql.append("           EM.NOMBEMPRESA, ");
		sql.append("           EM.EMPRESA_ID, ");
		sql.append("       	   CJ.PUNTOVENTA_ID, ");
		sql.append("           PV.NOMBPUNTOVENTA ");
		sql.append("  ORDER BY EM.NOMBEMPRESA, PO.DESCPARADA, PD.DESCPARADA, PV.NOMBPUNTOVENTA ");

		return sql.toString();
	}
}
