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.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.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 RelatorioDevolucaoBilhetes extends Relatorio {
	
	private static Logger log = Logger.getLogger(RelatorioDevolucaoBilhetes.class);

	public RelatorioDevolucaoBilhetes(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");

				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);
				log.debug(sql);

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

				stmt.setString("DATA_INICIO", DateUtil.getStringDate(((Timestamp) parametros.get("DATA_INICIO")), "dd/MM/yyyy HH:mm:ss"));
				stmt.setString("DATA_FINAL", DateUtil.getStringDate(((Timestamp) parametros.get("DATA_FINAL")), "dd/MM/yyyy HH:mm:ss"));

				rset = stmt.executeQuery();

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

					DevolucaoBilhetes db = new DevolucaoBilhetes();
					db.setEstado((String) rset.getObject("ESTADO"));
					db.setAidf((String) rset.getObject("AIDF"));
					db.setNumFolioSistema((String) rset.getObject("AIDF") == null ? (String) rset.getObject("NUMFOLIOSISTEMA") : (String) rset.getObject("AIDF"));
					db.setSerieSubSerie((String) rset.getObject("SERIE_SUBSERIE"));
					db.setFolio((String) rset.getObject("FOLIO"));
					db.setUf((String) rset.getObject("UF"));
					db.setFechorVenta((String) rset.getObject("FECHOR_VENTA"));
					db.setEstadoId(rset.getObject("ESTADO_ID") == null ? null : ((BigDecimal) rset.getObject("ESTADO_ID")).intValue());
					db.setIcms((BigDecimal) rset.getObject("ICMS"));
					db.setPrecioBase((BigDecimal) rset.getObject("PRECIOBASE"));
					db.setPrecioPagado((BigDecimal) rset.getObject("PRECIOPAGADO"));
					db.setEmpresaId(rset.getObject("EMPRESA_ID") == null ? null : ((BigDecimal) rset.getObject("EMPRESA_ID")).intValue());
					db.setEmpresa((String) rset.getObject("NOMB_EMPRESA"));

					BigDecimal valorIcms = BigDecimal.ZERO;
					valorIcms = db.getPrecioPagado().multiply(db.getIcms().divide(BigDecimal.valueOf(100)));
					db.setValorIcms(valorIcms);

					db.setPorcMunicipal(rset.getObject("PORC_MUNICIPAL") == null ? BigDecimal.ZERO : (BigDecimal) rset.getObject("PORC_MUNICIPAL"));
					db.setPorcEstadual(rset.getObject("PORC_ESTADUAL") == null ? BigDecimal.ZERO : (BigDecimal) rset.getObject("PORC_ESTADUAL"));

					boolean isEstadual = ((BigDecimal) rset.getObject("IS_ESTADUAL")).equals(BigDecimal.ZERO) ? false : true;

					BigDecimal estornoMunicipal = BigDecimal.ZERO;
					BigDecimal estornoEstadual = BigDecimal.ZERO;
					if (isEstadual) {
						estornoEstadual = valorIcms.multiply(db.getPorcEstadual().divide(BigDecimal.valueOf(100)));
					} else {
						estornoMunicipal = valorIcms.multiply(db.getPorcMunicipal().divide(BigDecimal.valueOf(100)));
					}
					db.setEstornoMunicipal(estornoMunicipal);
					db.setEstornoEstadual(estornoEstadual);

					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) {

		StringBuilder sql = new StringBuilder();
		sql.append("SELECT COALESCE(AIDF.ACFISCAL,SUBSTR(ML2.NUMSERIE20, -6, 7)) AS AIDF, ");
		sql.append("  COALESCE(CAJ.NUMFOLIOSISTEMA, CAJ.NUMOPERACION) AS NUMFOLIOSISTEMA, ");
		sql.append("  CASE WHEN ML2.NUMSERIE20 IS NULL THEN CAJ.NUMSERIEPREIMPRESA ELSE NULL END AS SERIE_SUBSERIE, ");
		sql.append("  CAJ.NUMFOLIOPREIMPRESO AS FOLIO, ");
		sql.append("  CAJ.PRECIOPAGADO AS PRECIOPAGADO, ");
		sql.append("  CAJ.PRECIOBASE AS PRECIOBASE, ");
		sql.append("  E.NOMBEMPRESA AS NOMB_EMPRESA, ");
		sql.append("  E.EMPRESA_ID AS EMPRESA_ID, ");
		sql.append("  EST.ESTADO_ID AS ESTADO_ID, ");
		sql.append("  EST.NOMBESTADO AS ESTADO, ");
		sql.append("  EST.CVEESTADO AS UF, ");
		sql.append("  EST.ICMS AS ICMS, ");
		sql.append("  TO_CHAR(CAJ.FECHORVENTA, 'DD/MM/YYYY') AS FECHOR_VENTA, ");
		sql.append("  CASE WHEN CO.ESTADO_ID <> CD.ESTADO_ID THEN 1 ELSE 0 END IS_ESTADUAL, ");
		sql.append("  EI.PORCREDMUNICIPAL AS PORC_MUNICIPAL, ");
		sql.append("  EI.PORCREDESTADUAL AS PORC_ESTADUAL ");
		sql.append("FROM CAJA CAJ ");
		sql.append("INNER JOIN EMPRESA E ON E.EMPRESA_ID = CAJ.MARCA_ID ");
		sql.append("INNER JOIN PUNTO_VENTA PTV ON PTV.PUNTOVENTA_ID = CAJ.PUNTOVENTA_ID ");
		sql.append("INNER JOIN PARADA ORIGEM ON (CAJ.ORIGEN_ID = ORIGEM.PARADA_ID ) ");
		sql.append("INNER JOIN PARADA DESTINO ON (CAJ.DESTINO_ID = DESTINO.PARADA_ID ) ");
		sql.append("INNER JOIN CIUDAD CO ON (CO.CIUDAD_ID = ORIGEM.CIUDAD_ID ) ");
		sql.append("INNER JOIN CIUDAD CD ON (CD.CIUDAD_ID = DESTINO.CIUDAD_ID ) ");
		sql.append("INNER JOIN ESTADO EST ON EST.ESTADO_ID = CO.ESTADO_ID ");
		sql.append("LEFT JOIN BOLETO B ON (B.NUMASIENTO = CAJ.NUMASIENTO ");
		sql.append("                       AND B.FECCORRIDA = CAJ.FECCORRIDA ");
		sql.append("                       AND B.CORRIDA_ID = CAJ.CORRIDA_ID) ");
		sql.append("LEFT JOIN FISCAL_ML2 ML2 ON ML2.BOLETO_ID = B.BOLETO_ID ");
		sql.append("LEFT JOIN EMPRESA_IMPOSTO EI ON EST.ESTADO_ID = EI.ESTADO_ID AND EI.EMPRESA_ID = CAJ.MARCA_ID ");
		sql.append("LEFT JOIN AIDF AIDF ON ((AIDF.SERIE = CAJ.NUMSERIEPREIMPRESA OR ");
		sql.append("                     AIDF.SERIE = SUBSTR(CAJ.NUMSERIEPREIMPRESA,1,INSTR(CAJ.NUMSERIEPREIMPRESA,'-',1)-1)) ");
		sql.append("                     AND (CAJ.NUMFOLIOPREIMPRESO BETWEEN AIDF.FORMINICIAL AND AIDF.FORMFINAL)) ");
		sql.append("WHERE CAJ.MOTIVOCANCELACION_ID IN (32) ");
		sql.append("AND CAJ.FECHORVENTA BETWEEN TO_DATE(:DATA_INICIO,'DD/MM/YYYY HH24:MI:SS') AND TO_DATE(:DATA_FINAL,'DD/MM/YYYY HH24:MI:SS') ");
		sql.append("AND CAJ.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 CAJ.MARCA_ID IN (" + empresaId + ") ");
		sql.append("GROUP BY COALESCE(AIDF.ACFISCAL,SUBSTR(ML2.NUMSERIE20, -6, 7)), ");
		sql.append("  COALESCE(CAJ.NUMFOLIOSISTEMA, CAJ.NUMOPERACION), ");
		sql.append("  CASE WHEN ML2.NUMSERIE20 IS NULL THEN CAJ.NUMSERIEPREIMPRESA ELSE NULL END, ");
		sql.append("  CAJ.NUMFOLIOPREIMPRESO, ");
		sql.append("  CAJ.PRECIOPAGADO, ");
		sql.append("  CAJ.PRECIOBASE, ");
		sql.append("  E.NOMBEMPRESA, ");
		sql.append("  E.EMPRESA_ID, ");
		sql.append("  EST.ESTADO_ID, ");
		sql.append("  EST.NOMBESTADO, ");
		sql.append("  EST.CVEESTADO, ");
		sql.append("  EST.ICMS, ");
		sql.append("  TO_CHAR(CAJ.FECHORVENTA, 'DD/MM/YYYY'), ");
		sql.append("  (CASE WHEN CO.ESTADO_ID <> CD.ESTADO_ID THEN 1 ELSE 0 END), ");
		sql.append("  EI.PORCREDMUNICIPAL, ");
		sql.append("  EI.PORCREDESTADUAL ");
		sql.append("ORDER BY NOMB_EMPRESA, ESTADO, FECHOR_VENTA ");

		return sql.toString();
	}

	@Override
	protected void processaParametros() throws Exception {
	}

}
