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

import java.sql.Connection;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.rjconsultores.ventaboletos.relatorios.utilitarios.ArrayDataSource;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.Relatorio;
import com.rjconsultores.ventaboletos.relatorios.utilitarios.RelatorioBilhetesVendidosEstoqueAgenciaBean;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.web.utilerias.NamedParameterStatement;

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

/**
 * @author Wallace
 *
 */
public class RelatorioBilhetesVendidosEstoqueAgencia extends Relatorio {
	private List<RelatorioBilhetesVendidosEstoqueAgenciaBean> lsDadosRelatorio;

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

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

				Connection conexao = this.relatorio.getConexao();
				Map<String, Object> parametros = this.relatorio.getParametros();
				String  pnutoVentasIds = (String) parametros.get("NUMPUNTOVENTA");
				Integer empresa = (Integer) parametros.get("EMPRESA_ID");
				Date datainicial = (Date) parametros.get("DATA_INICIAL");
				Date dataFinal = (Date) parametros.get("DATA_FINAL");
				Integer aidfTipoId = (Integer) parametros.get("AIDFTIPO_ID");
				Integer aidfId = (Integer) parametros.get("AIDF_ID");
				
				NamedParameterStatement stmt = new NamedParameterStatement(conexao, sql(pnutoVentasIds, aidfTipoId, aidfId));
								
				stmt.setInt("EMPRESA_ID", empresa);
				stmt.setString("dataInicio", DateUtil.getStringDate(datainicial, "dd/MM/yyyy") + " 00:00:00");
				stmt.setString("dataFinal", DateUtil.getStringDate(dataFinal, "dd/MM/yyyy") + " 23:59:59");
				if(aidfTipoId != null) {
					stmt.setInt("aidfTipo",aidfTipoId);
				}
				if(aidfId != null) {
					stmt.setInt("aidfId",aidfId);
				}

				ResultSet rset = stmt.executeQuery();
				List<RelatorioBilhetesVendidosEstoqueAgenciaBean> lsTemp = new ArrayList<>();
				List<RelatorioBilhetesVendidosEstoqueAgenciaBean> lsRelatorioBilhetesVendidosEstoqueAgenciaBean = new ArrayList<>();
				List<RelatorioBilhetesVendidosEstoqueAgenciaBean> lsRelatorioBilhetesVendidosEstoqueAgenciaBeanGeradoSequencia = new ArrayList<>();
				while (rset.next()) {

					Map<String, Object> dataResult = new HashMap<String, Object>();
									
					RelatorioBilhetesVendidosEstoqueAgenciaBean bean  = new RelatorioBilhetesVendidosEstoqueAgenciaBean();
					bean.setAidfId(rset.getInt("aidfId"));
					bean.setNombpuntoventa(rset.getString("descpuntoVenta"));
					bean.setSerie(rset.getString("serie"));
					bean.setFechorVenta(DateUtil.getDateFromString(rset.getString("dataVenda"), "ddMMyyyy"));
					bean.setChave(rset.getString("chave"));
					bean.setFolio(rset.getString("folio"));
					bean.setNomeEmpresa(rset.getString("nomeEmpresa"));
					bean.setTipoEvento(rset.getString("tipoAidf"));
					lsRelatorioBilhetesVendidosEstoqueAgenciaBean.add(bean);
					
					this.dados.add(dataResult);

				}
				
				Map<String, String> map = new HashMap<String, String>();
				for (RelatorioBilhetesVendidosEstoqueAgenciaBean i : lsRelatorioBilhetesVendidosEstoqueAgenciaBean) {
					map.put(i.getChave(), i.getChave());					
				}
				for (Map.Entry<String, String> entry : map.entrySet()) {
					for (RelatorioBilhetesVendidosEstoqueAgenciaBean i : lsRelatorioBilhetesVendidosEstoqueAgenciaBean) {					 
					       if(entry.getKey().equals(i.getChave())) {
					    	   lsTemp.add(i);				
					       }
					    }
					
					for (RelatorioBilhetesVendidosEstoqueAgenciaBean bean : lsTemp) {
						lsRelatorioBilhetesVendidosEstoqueAgenciaBeanGeradoSequencia.addAll(agruparSequenciasBilhetes(lsTemp));
						break;						
					}
					lsTemp = new ArrayList<>();
				}
			
				Collections.sort(lsRelatorioBilhetesVendidosEstoqueAgenciaBeanGeradoSequencia, new Comparator<RelatorioBilhetesVendidosEstoqueAgenciaBean>() {
					@Override
					public int compare(RelatorioBilhetesVendidosEstoqueAgenciaBean rel1, RelatorioBilhetesVendidosEstoqueAgenciaBean rel2) {
						return DateUtil.compareDate(rel1.getFechorVenta(), rel2.getFechorVenta());
					}
				});

				this.resultSet = rset;
				setLsDadosRelatorio(lsRelatorioBilhetesVendidosEstoqueAgenciaBeanGeradoSequencia);
			}
		});
	}
	
	public void setLsDadosRelatorio(List<RelatorioBilhetesVendidosEstoqueAgenciaBean> lsDadosRelatorio) {
		this.setCollectionDataSource(new JRBeanCollectionDataSource(lsDadosRelatorio));
		this.lsDadosRelatorio = lsDadosRelatorio;
	}
	
	public List<RelatorioBilhetesVendidosEstoqueAgenciaBean> getLsDadosRelatorio() {
		return lsDadosRelatorio;
	}

	private String sql(String puntoVentasId, Integer aidfTipoId, Integer aidfId) {
		
		StringBuilder sql = new StringBuilder();
		
		sql.append(" SELECT TB.aidfId as aidfId,                                                                                                                                        ");
		sql.append(" TB.descpuntoVenta as descpuntoVenta,                                                                                                                                ");
		sql.append(" TB.SERIE as serie,                                                                                                                                                   ");
		sql.append(" TB.puntoventaId,                                                                                                                                             	 	  ");
		sql.append(" TB.dataVenda as dataVenda,                                                                                                                                      	  ");
		sql.append(" TB.chave as chave,                                                                                                                                               	  ");
		sql.append(" TB.nomeEmpresa as nomeEmpresa  , TB.folio as folio, TB.tipoAidf as tipoAidf                                                                                                                      ");
		sql.append(" FROM (SELECT DAB.AIDF_ID AS aidfId,                                                                                                                                  ");
		sql.append(" pv.nombpuntoventa AS descpuntoVenta,                                                                                                                                 ");
		sql.append("        c.numseriepreimpresa AS SERIE,                                                                                                                                ");
		sql.append("        c.puntoventa_id AS puntoventaId,                                                                                                                              ");
		sql.append("        to_char(c.fechorventa, 'ddMMyyyy') AS dataVenda,                                                                                                              ");
		sql.append("        DAB.AIDF_ID || c.numseriepreimpresa || c.puntoventa_id || to_char(c.fechorventa, 'ddMMyyyy') AS chave,                                                        ");
		sql.append("        em.nombEmpresa as nomeEmpresa , c.numfoliopreimpreso as folio, AIT.DESCTIPO tipoAidf                                                                                                     ");
		sql.append(" FROM caja c,                                                                                                                                                         ");
		sql.append("      PUNTO_VENTA PV,                                                                                                                                                 ");
		sql.append("      EMPRESA EM,                                                                                                                                                     ");
		sql.append("      AIDF_TIPO AIT,                                                                                                                                                  ");
		sql.append("      AIDF AI,                                                                                                                                                       ");
		sql.append("      ABASTO_BOLETO AB                                                                                                                                                ");
		sql.append(" LEFT JOIN DET_ABASTO_BOLETO DAB ON (AB.ABASTOBOLETO_ID = DAB.ABASTOBOLETO_ID)                                                                                        ");
		sql.append(" WHERE fechorventa  BETWEEN TO_DATE(:dataInicio,'dd/mm/yyyy hh24:mi:ss') AND TO_DATE(:dataFinal,'dd/mm/yyyy hh24:mi:ss')                                               ");
		sql.append("   AND TO_NUMBER(c.NUMFOLIOPREIMPRESO) BETWEEN TO_NUMBER(DAB.NUMFOLIOINICIAL) AND TO_NUMBER(DAB.NUMFOLIOFINAL)                                                        ");
//		sql.append("   AND c.PUNTOVENTA_ID = AB.PUNTOVENTA_ID                                                                                                                             ");
		if (puntoVentasId != null && !puntoVentasId.equals("-1")) {
			sql.append(" AND (c.PUNTOVENTA_ID in("+puntoVentasId+ ") or  AB.PUNTOVENTA_ID in("+puntoVentasId+") ) 										                                   ");
		}
		sql.append("   AND EM.EMPRESA_ID = AB.EMPRESA_ID                                                                                                                                  ");
		sql.append("   AND c.PUNTOVENTA_ID = PV.PUNTOVENTA_ID                                                                                                                             ");
		sql.append("    AND DAB.AIDF_ID = AI.AIDF_ID    AND  AI.ACTIVO = 1 AND AIT.ACTIVO = 1                                                                                               ");
		sql.append(aidfTipoId != null ?  " AND (AI.AIDFTIPO_ID =:aidfTipo  AND AIT.AIDFTIPO_ID = AI.AIDFTIPO_ID) " : "  AND AIT.AIDFTIPO_ID = AI.AIDFTIPO_ID                                ");
		sql.append(aidfId != null ?  " AND (AI.AIDF_ID =:aidfId  AND DAB.AIDF_ID = AI.AIDF_ID) " : "  AND DAB.AIDF_ID = AI.AIDF_ID  ");
		sql.append("    AND EM.EMPRESA_ID =:EMPRESA_ID   AND  (c.NUMSERIEPREIMPRESA = dab.NUMSERIEPREIMPRESA OR (c.NUMSERIEPREIMPRESA IS NULL and dab.NUMSERIEPREIMPRESA is null))          ");
		sql.append(" GROUP BY DAB.AIDF_ID,c.numseriepreimpresa, c.numfoliopreimpreso,                                                                                                       ");
		sql.append("          c.puntoventa_id,                                                                                                                                            ");
		sql.append("          to_char(c.fechorventa, 'ddMMyyyy'),                                                                                                                         ");
		sql.append("          pv.nombpuntoventa,                                                                                                                                          ");
		sql.append("          em.nombEmpresa,  AIT.DESCTIPO                                                                                                                                              ");
		sql.append(" 																																									 ");
		sql.append(" UNION ALL                                                                                                                                                            ");
		sql.append(" SELECT DAB.AIDF_ID AS aidfId,                                                                                                                                        ");
		sql.append(" pv.nombpuntoventa AS descpuntoVenta,                                                                                                                                 ");
		sql.append("         c.numseriepreimpresa AS SERIE,                                                                                                                               ");
		sql.append("        c.puntoventa_id AS puntoventaId,                                                                                                                              ");
		sql.append("        to_char(c.FECHORVTA, 'ddMMyyyy') AS dataVenda,                                                                                                                ");
		sql.append("        DAB.AIDF_ID || c.numseriepreimpresa || c.puntoventa_id || to_char(c.FECHORVTA, 'ddMMyyyy') AS chave,                                                          ");
		sql.append("         em.nombEmpresa as nomeEmpresa , c.numfoliopreimpreso as folio, AIT.DESCTIPO tipoAidf                                                                          ");
		sql.append(" FROM caja_diversos c,                                                                                                                                                ");
		sql.append("      PUNTO_VENTA PV,                                                                                                                                                 ");
		sql.append("      EMPRESA EM,                                                                                                                                                     ");
		sql.append("       AIDF AI,                                                                                                                                                       ");
		sql.append("     AIDF_TIPO AIT,                                                                                                                                                  ");
		sql.append("      ABASTO_BOLETO AB                                                                                                                                                ");
		sql.append(" LEFT JOIN DET_ABASTO_BOLETO DAB ON (AB.ABASTOBOLETO_ID = DAB.ABASTOBOLETO_ID)                                                                                        ");
		sql.append(" WHERE FECHORVTA  BETWEEN TO_DATE(:dataInicio,'dd/mm/yyyy hh24:mi:ss') AND TO_DATE(:dataFinal,'dd/mm/yyyy hh24:mi:ss')                                                 ");
		sql.append("   AND TO_NUMBER(c.NUMFOLIOPREIMPRESO) BETWEEN TO_NUMBER(DAB.NUMFOLIOINICIAL) AND TO_NUMBER(DAB.NUMFOLIOFINAL)                                                        ");
//		sql.append("   AND c.PUNTOVENTA_ID = AB.PUNTOVENTA_ID                                                                                                                             ");
		if (puntoVentasId != null && !puntoVentasId.equals("-1")) {
			sql.append(" AND (c.PUNTOVENTA_ID in("+puntoVentasId+ ") or  AB.PUNTOVENTA_ID in("+puntoVentasId+") )                                                                          ");
		}
		sql.append("   AND EM.EMPRESA_ID = AB.EMPRESA_ID                                                                                                                                  ");
		sql.append("   AND c.PUNTOVENTA_ID = PV.PUNTOVENTA_ID                                                                                                                             ");
		sql.append("    AND DAB.AIDF_ID = AI.AIDF_ID       AND AI.ACTIVO = 1 AND AIT.ACTIVO = 1                                                                                              ");
		sql.append(aidfTipoId != null ?  " AND (AI.AIDFTIPO_ID =:aidfTipo  AND AIT.AIDFTIPO_ID = AI.AIDFTIPO_ID) " : "  AND AIT.AIDFTIPO_ID = AI.AIDFTIPO_ID                                ");
		sql.append(aidfId != null ?  " AND (AI.AIDF_ID =:aidfId  AND DAB.AIDF_ID = AI.AIDF_ID) " : "  AND DAB.AIDF_ID = AI.AIDF_ID  ");
		sql.append("    AND EM.EMPRESA_ID =:EMPRESA_ID    AND   (c.NUMSERIEPREIMPRESA = dab.NUMSERIEPREIMPRESA OR (c.NUMSERIEPREIMPRESA IS NULL and dab.NUMSERIEPREIMPRESA is null))             ");
		sql.append(" GROUP BY DAB.AIDF_ID,c.numseriepreimpresa,   c.numfoliopreimpreso,                                                                                                    ");
		sql.append("          c.puntoventa_id,                                                                                                                                            ");
		sql.append("          to_char(c.FECHORVTA, 'ddMMyyyy'),                                                                                                                           ");
		sql.append("          pv.nombpuntoventa,                                                                                                                                          ");
		sql.append("          em.nombEmpresa,  AIT.DESCTIPO                                                                                                                                 ");
		sql.append(" )TB                                                                                                                                                                  ");
		sql.append(" ORDER BY to_number(TB.FOLIO)     																								                                       ");
		System.out.println(sql.toString());
		return sql.toString();
		
		
	}

	private  List<RelatorioBilhetesVendidosEstoqueAgenciaBean>  agruparSequenciasBilhetes(List<RelatorioBilhetesVendidosEstoqueAgenciaBean> lista) {
		
		
		int[] bilhetesInt = new int[lista.size()];
		int i = 0;
		
		for (RelatorioBilhetesVendidosEstoqueAgenciaBean relatorioBilhetesVendidosEstoqueAgenciaBean : lista) {
			bilhetesInt[i] = Integer.parseInt(relatorioBilhetesVendidosEstoqueAgenciaBean.getFolio());
			i++;
		}
		Arrays.sort(bilhetesInt);
		List<RelatorioBilhetesVendidosEstoqueAgenciaBean> listaAgrupada = new ArrayList<>();
		
		RelatorioBilhetesVendidosEstoqueAgenciaBean bean = lista.get(0);
		
			bilhetesInt = reajustarPosicaoArray(bilhetesInt.length, bilhetesInt, bilhetesInt[0], 1);
	        int inicio = bilhetesInt[0];
	        int fim = bilhetesInt.length == 1 ? bilhetesInt[0] : bilhetesInt[1];
	        
	        for (int j = 2; j < bilhetesInt.length; ++j) {
	            if (fim + 1 == bilhetesInt[j]) {
	            	fim++;
	            } else {
	            	listaAgrupada.add(gerarAgrupamento(inicio, fim, new RelatorioBilhetesVendidosEstoqueAgenciaBean(bean)));
	                inicio = bilhetesInt[j];
	                fim = bilhetesInt[j];
	            }
	        }
	             
	        listaAgrupada.add(gerarAgrupamento(inicio, fim, bean));
			
        return listaAgrupada; 		
	}
	

    private RelatorioBilhetesVendidosEstoqueAgenciaBean gerarAgrupamento(int inicio, int fim, RelatorioBilhetesVendidosEstoqueAgenciaBean bean) {
    	
    	RelatorioBilhetesVendidosEstoqueAgenciaBean object = new RelatorioBilhetesVendidosEstoqueAgenciaBean(bean);
    	
    
        if (inicio != fim) {
        	object.setQuantidade((fim-inicio+1));
        	object.setFolioInicial(inicio);
        	object.setFolioFinal(fim);

        } else {
        	object.setQuantidade(1);
        	object.setFolioInicial(inicio);
        	object.setFolioFinal(inicio);
        }
        return object;
    }
    private int[] reajustarPosicaoArray(int numero, int arr[],int x, int posicao)
    {
        int novoArray[] = new int[numero + 1];

        for (int i = 0; i < numero + 1; i++) {
            if (i < posicao - 1)
            	novoArray[i] = arr[i];
            else if (i == posicao - 1)
            	novoArray[i] = x;
            else
            	novoArray[i] = arr[i - 1];
        }
        return novoArray;
    }

	@Override
	protected void processaParametros() throws Exception {

	}

}
