package com.mx.dla.dda.reporte.acumulateBuys.bos;

import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mx.dla.dda.contrato.transaccion.exceptions.dtos.TransaccionException;
import com.mx.dla.dda.general.constants.MesesAnio;
import com.mx.dla.dda.general.utilerias.FechaUtilerias;
import com.mx.dla.dda.reporte.acumulateBuys.dao.ReporteAcumulateBuysDAO;
import com.mx.dla.dda.reporte.acumulateBuys.dto.acumulateBuysEstudiosDTO;
import com.mx.dla.dda.reporte.general.dtos.CeldaBaseDTO;
import com.mx.dla.dda.reporte.reportecfg.daos.ReporteConfiguracionDAO;
import com.mx.dla.dda.reportes.ExcelGeneratorProcess.bos.ExcelGeneratorProcessBO;
import com.mx.dla.dda.reportes.generaxml.generaXMLimpl;
import com.mx.dla.global.bos.BaseBO;

@Service
public class ReporteAcumulateBuysBO extends BaseBO {
	
	@Autowired
	private ReporteAcumulateBuysDAO acumulatebuysDAO;
	
	@Autowired
	private ReporteConfiguracionDAO reporteconfiguracionDAO;
	
	@Autowired
	private ExcelGeneratorProcessBO excelGeneratorProcessBO;
	
	@Autowired
	private generaXMLimpl genXml;
	
	public List<acumulateBuysEstudiosDTO> obtenEstudios() throws Exception{
		
		List<acumulateBuysEstudiosDTO> estudios = null;
		
		try{
			
			estudios = acumulatebuysDAO.obtenerEstudios();
			
			logger.debug("ReporteAcumulateBuys.obtenEstudios - [{}]",estudios);
			
		}catch(Exception e){
			throw new TransaccionException("Error al obtener estudios en AcumulateBuys ::: ", e);
		}
		return estudios;
		
	}
	
	public List<acumulateBuysEstudiosDTO> obtenEstudiosConfig(String user) throws Exception{
		
		List<acumulateBuysEstudiosDTO> estudios = null;
		
		try{
			
			estudios = acumulatebuysDAO.ObtenerEstudiosConfig(user);
			
			logger.debug("ReporteAcumulateBuys.obtenEstudiosConfig - [{}]",estudios);
			
		}catch(Exception e){
			throw new TransaccionException("Error al obtener estudios configurados en AcumulateBuys ::: ", e);
		}
		
		return estudios;
		
	}
	
	public List<LinkedHashMap<String, String>> reporteAcumulateBuys(String origen,Long id_estudio,String typeAbono,String fechaInicio,String fechaFin) throws TransaccionException,IllegalArgumentException, IllegalAccessException, Exception {
		
		List<LinkedHashMap<String, String>> acumulateBuys = null;
		
		String condicionEstatusCarga = "and cga.ESTATUS_CARGA = 'OK'";
		String clave_reporte = "RAB";
		boolean muestraTOTAL = false;
		boolean muestraMeses = false;
		List<LinkedHashMap<String, Object>> configuracion = null;
		
		HashMap<String, Long> fechaInicialSplit = FechaUtilerias.getFechaValores(fechaInicio, "MM/yyyy");
		Long mesInicial = fechaInicialSplit.get("Month");
		Long anioInicial = fechaInicialSplit.get("Year");
		HashMap<String, Long> fechaFinalSplit = FechaUtilerias.getFechaValores(fechaFin, "MM/yyyy");
		Long mesFinal = fechaFinalSplit.get("Month");
		Long anioFinal = fechaFinalSplit.get("Year");

		String sumatorias_mensuales = ",";
		String sumatotal = "(";
		String endsumatotal =") as TOTAL";
		String meses_seleccionados = "";
		String meses_pivote = "";
		String monthPivot = "";

		SimpleDateFormat formater = new SimpleDateFormat("MM/yyyy");
		
		try{
			configuracion = reporteconfiguracionDAO.obtenerReporteConfiguracion(clave_reporte, id_estudio);
			
			Calendar beginCalendar = Calendar.getInstance();
			Calendar finishCalendar = Calendar.getInstance();

			beginCalendar.setTime(formater.parse(mesInicial + "/" + anioInicial));
			finishCalendar.setTime(formater.parse(mesFinal + "/" + anioFinal));
			
			if(origen.equals("cargaTransacciones"))
				condicionEstatusCarga = "";

			Integer index = 1;
			while (beginCalendar.before(finishCalendar) || beginCalendar.equals(finishCalendar)) {
				String month = StringUtils.leftPad(String.valueOf(beginCalendar.get(Calendar.MONTH) + 1), 2, "0");
				String year = String.valueOf(beginCalendar.get(Calendar.YEAR));
				
				monthPivot = month;
				month = getmonth(month);

				sumatorias_mensuales = sumatorias_mensuales + "NVL(SUM(" + month + "), 0) as " + month + ",";
				sumatotal = sumatotal + "SUM(" + month + ") + ";
				meses_seleccionados = meses_seleccionados + "NVL(" + month + ", 0 ) as " + month + ",";
				meses_pivote = meses_pivote + "'" + monthPivot + year + "' as " + month + ",";

				beginCalendar.add(Calendar.MONTH, 1);
				index++;
			}
			
			for (LinkedHashMap<String, Object> item : configuracion){
				for (Entry<String, Object> pair : item.entrySet()) {
					 logger.info("configuracion {} : {}", pair.getKey(), pair.getValue());
					   if(pair.getKey().equals("COLUMNA")){
						            if(pair.getValue().equals("TOTAL")){
						            	muestraTOTAL = true;
						            }else if(pair.getValue().equals("MES")){
						            	muestraMeses = true;
						            }
					   }
				}
				    
			}
			
			sumatotal = sumatotal.substring(0, sumatotal.length() - 2) + endsumatotal;
			//sumatorias_mensuales = sumatorias_mensuales + sumatotal;
			meses_seleccionados = meses_seleccionados.substring(0, meses_seleccionados.length() - 1);
			meses_pivote = meses_pivote.substring(0, meses_pivote.length() - 1);

			if(configuracion.isEmpty()){
				muestraTOTAL = true;
				muestraMeses = true;
			}	
			
			if(!muestraTOTAL && !muestraMeses){
				sumatorias_mensuales=" ";
			}else if(muestraTOTAL && !muestraMeses){
				sumatotal = "," + sumatotal;
				sumatorias_mensuales = sumatotal;
			}else if(!muestraTOTAL && muestraMeses){
				sumatorias_mensuales = sumatorias_mensuales.substring(0, sumatorias_mensuales.length() - 1);
			} else if(muestraTOTAL && muestraMeses){
				sumatorias_mensuales = sumatorias_mensuales + sumatotal;
			}
			
				   
			
			
			logger.info("sumatorias_mensuales{}", sumatorias_mensuales);
			logger.info("sumatotal{}", sumatotal);
			logger.info("meses_seleccionados{}", meses_seleccionados);
			logger.info("meses_pivote{}", meses_pivote);
		
			acumulateBuys = acumulatebuysDAO.reporteAcumulateBuys(condicionEstatusCarga,sumatorias_mensuales,meses_seleccionados,meses_pivote,mesFinal,anioFinal,mesInicial,anioInicial,id_estudio, typeAbono);			                                   
			
			logger.info("{}", acumulateBuys);
			
		}catch(Exception e){
			logger.error("Error-BO-reporteAcumulateBuys ::: {}", e);
		}
			
		return acumulateBuys;
		
	}
	
	public InputStream generaExcelAcumumlateBuys(String fileFileName,String origen,Long id_estudio,String typeAbono,String fechaInicio,String fechaFin) throws TransaccionException,IllegalArgumentException, IllegalAccessException, Exception {
		
		List<LinkedHashMap<String, String>> acumulateBuys = null;
		
		String condicionEstatusCarga = "and cga.ESTATUS_CARGA = 'OK'";
		String clave_reporte = "RAB";
		boolean muestraTOTAL = false;
		boolean muestraMeses = false;
		List<LinkedHashMap<String, Object>> configuracion = null;
		
		HashMap<String, Long> fechaInicialSplit = FechaUtilerias.getFechaValores(fechaInicio, "MM/yyyy");
		Long mesInicial = fechaInicialSplit.get("Month");
		Long anioInicial = fechaInicialSplit.get("Year");
		HashMap<String, Long> fechaFinalSplit = FechaUtilerias.getFechaValores(fechaFin, "MM/yyyy");
		Long mesFinal = fechaFinalSplit.get("Month");
		Long anioFinal = fechaFinalSplit.get("Year");

		String tituloReporte = "Reporte Acumulate Buys";
		String archivoGen="";
		String excelFileName = fileFileName + ".xlsx";
		fileFileName = fileFileName + ".xml";
		
		String sumatorias_mensuales = ",";
		String sumatotal = "(";
		String endsumatotal =") as TOTAL";
		String meses_seleccionados = "";
		String meses_pivote = "";
		String monthPivot = "";


		SimpleDateFormat formater = new SimpleDateFormat("MM/yyyy");
		
		try{
			configuracion = reporteconfiguracionDAO.obtenerReporteConfiguracion(clave_reporte, id_estudio);
			
			
			Calendar beginCalendar = Calendar.getInstance();
			Calendar finishCalendar = Calendar.getInstance();

			beginCalendar.setTime(formater.parse(mesInicial + "/" + anioInicial));
			finishCalendar.setTime(formater.parse(mesFinal + "/" + anioFinal));
			
			if(origen.equals("cargaTransacciones"))
			{
				condicionEstatusCarga = "";
			    tituloReporte = "Vista Previa Reporte Acumulate Buys";
			}
				

			Integer index = 1;
			while (beginCalendar.before(finishCalendar) || beginCalendar.equals(finishCalendar)) {
				String month = StringUtils.leftPad(String.valueOf(beginCalendar.get(Calendar.MONTH) + 1), 2, "0");
				String year = String.valueOf(beginCalendar.get(Calendar.YEAR));
				
				monthPivot = month;
				month = getmonth(month);

				sumatorias_mensuales = sumatorias_mensuales + "NVL(SUM(" + month + "), 0) as " + month + ",";
				sumatotal = sumatotal + "SUM(" + month + ") + ";
				meses_seleccionados = meses_seleccionados + "NVL(" + month + ", 0 ) as " + month + ",";
				meses_pivote = meses_pivote + "'" + monthPivot + year + "' as " + month + ",";

				beginCalendar.add(Calendar.MONTH, 1);
				index++;
			}
			
			for (LinkedHashMap<String, Object> item : configuracion){
				for (Entry<String, Object> pair : item.entrySet()) {
					 logger.info("configuracion {} : {}", pair.getKey(), pair.getValue());
					   if(pair.getKey().equals("COLUMNA")){
						            if(pair.getValue().equals("TOTAL")){
						            	muestraTOTAL = true;
						            }else if(pair.getValue().equals("MES")){
						            	muestraMeses = true;
						            }
					   }
				}
				    
			}
			
			sumatotal = sumatotal.substring(0, sumatotal.length() - 2) + endsumatotal;
			//sumatorias_mensuales = sumatorias_mensuales + sumatotal;
			meses_seleccionados = meses_seleccionados.substring(0, meses_seleccionados.length() - 1);
			meses_pivote = meses_pivote.substring(0, meses_pivote.length() - 1);

			
			if(configuracion.isEmpty()){
				muestraTOTAL = true;
				muestraMeses = true;
			}
			
			if(!muestraTOTAL && !muestraMeses){
				sumatorias_mensuales=" ";
			}else if(muestraTOTAL && !muestraMeses){
				sumatotal = "," + sumatotal;
				sumatorias_mensuales = sumatotal;
			}else if(!muestraTOTAL && muestraMeses){
				sumatorias_mensuales = sumatorias_mensuales.substring(0, sumatorias_mensuales.length() - 1);
			} else if(muestraTOTAL && muestraMeses){
				sumatorias_mensuales = sumatorias_mensuales + sumatotal;
			}
			

			logger.info("sumatorias_mensuales{}", sumatorias_mensuales);
			logger.info("sumatotal{}", sumatotal);
			logger.info("meses_seleccionados{}", meses_seleccionados);
			logger.info("meses_pivote{}", meses_pivote);
		
			acumulateBuys = acumulatebuysDAO.reporteAcumulateBuys(condicionEstatusCarga,sumatorias_mensuales,meses_seleccionados,meses_pivote,mesFinal,anioFinal,mesInicial,anioInicial,id_estudio, typeAbono);			                                   
			
			logger.info("{}", acumulateBuys);
			
			//genera el XML para reporte
			archivoGen = genXml.generaXMLabuys(acumulateBuys, fileFileName,tituloReporte);
			
			logger.info("{}", acumulateBuys);
			logger.info("xml en la ruta {}", archivoGen);
			
		}catch(Exception e){
			logger.error("Error-BO-reporteAcumulateBuys ::: {}", e);
		}
			
		return excelGeneratorProcessBO.generaExcelProceso(fileFileName, excelFileName);
		
	}

	
	public ArrayList<CeldaBaseDTO> obtenerHeader(String fechaInicio,String fechaFin, Long id_estudio)
			throws ParseException {
		
		String clave_reporte = "RAB";
		boolean muestraTOTAL = false;
		boolean muestraMeses = false;
		List<LinkedHashMap<String, Object>> configuracion = null;
		
		HashMap<String, Long> fechaInicialSplit = FechaUtilerias.getFechaValores(fechaInicio, "MM/yyyy");
		Long mesInicial = fechaInicialSplit.get("Month");
		Long anioInicial = fechaInicialSplit.get("Year");

		HashMap<String, Long> fechaFinalSplit = FechaUtilerias.getFechaValores(fechaFin, "MM/yyyy");
		Long mesFinal = fechaFinalSplit.get("Month");
		Long anioFinal = fechaFinalSplit.get("Year");


		ArrayList<CeldaBaseDTO> headers = new ArrayList<CeldaBaseDTO>();
		headers.add(new CeldaBaseDTO("ASSET_NAME", null, "Asset Name"));

		SimpleDateFormat formater = new SimpleDateFormat("MM/yyyy");

		Calendar beginCalendar = Calendar.getInstance();
		Calendar finishCalendar = Calendar.getInstance();

		beginCalendar.setTime(formater.parse(mesInicial + "/" + anioInicial));
		finishCalendar.setTime(formater.parse(mesFinal + "/" + anioFinal));
		
		configuracion = reporteconfiguracionDAO.obtenerReporteConfiguracion(clave_reporte, id_estudio);
		
		for (LinkedHashMap<String, Object> item : configuracion){
			for (Entry<String, Object> pair : item.entrySet()) {
				 logger.info("configuracion {} : {}", pair.getKey(), pair.getValue());
				   if(pair.getKey().equals("COLUMNA")){
					            if(pair.getValue().equals("TOTAL")){
					            	muestraTOTAL = true;
					            }else if(pair.getValue().equals("MES")){
					            	muestraMeses = true;
					            }
				   }
			}
			    
		}
		
		if(configuracion.isEmpty()){
			muestraTOTAL = true;
			muestraMeses = true;
		}

		Integer index = 0;
		if(muestraMeses){
			while (beginCalendar.before(finishCalendar) || beginCalendar.equals(finishCalendar)) {
				String month = MesesAnio.parse("" + (beginCalendar.get(Calendar.MONTH) + 1)).getDesc();
				String year = String.valueOf(beginCalendar.get(Calendar.YEAR));
	
				headers.add(new CeldaBaseDTO("M" + (index + 1), null, month.substring(0,3) + " - " + year));
	
				beginCalendar.add(Calendar.MONTH, 1);
				index++;
			}

		}
		
		if(muestraTOTAL){
			headers.add(new CeldaBaseDTO("TOTAL", null, "TOTAL"));	
		}
		
		return headers;
	}
	
	public String getmonth(String month){
		
		if(month.equals("01"))
		        month = "ENE";
		
		if(month.equals("02"))
	        month = "FEB";
		
		if(month.equals("03"))
	        month = "MAR";
		
		if(month.equals("04"))
	        month = "ABR";
		
		if(month.equals("05"))
	        month = "MAY";
		
		if(month.equals("06"))
	        month = "JUN";
		
		if(month.equals("07"))
	        month = "JUL";
		
		if(month.equals("08"))
	        month = "AGO";
		
		if(month.equals("09"))
	        month = "SEP";
		
		if(month.equals("10"))
	        month = "OCT";
		
		if(month.equals("11"))
	        month = "NOV";
		
		if(month.equals("12"))
	        month = "DIC";
		
		return month;
		
	}

	
}
