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

import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
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.Entry;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.executor.result.ResultMapException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
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 ResultMapException, SQLException, TransaccionException {

		List<acumulateBuysEstudiosDTO> estudios = null;

		try {

			estudios = acumulatebuysDAO.obtenerEstudios();

			logger.debug("ReporteAcumulateBuys.obtenEstudios - [{}]", estudios);

		} catch (PersistenceException e) {
            throw new TransaccionException("Error al cargar los datos.", e);
        } catch (DataAccessException e) {
            throw new TransaccionException("Error al cargar los datos", e);
        }
		return estudios;

	}

	public List<acumulateBuysEstudiosDTO> obtenEstudiosConfig(String user) throws ResultMapException, SQLException, TransaccionException {

		List<acumulateBuysEstudiosDTO> estudios = null;

		try {

			estudios = acumulatebuysDAO.ObtenerEstudiosConfig(user);

			logger.debug("ReporteAcumulateBuys.obtenEstudiosConfig - [{}]", estudios);

		} catch (PersistenceException e) {
            throw new TransaccionException("Error al cargar los datos.", e);
        } catch (DataAccessException e) {
            throw new TransaccionException("Error al cargar los datos", e);
        }

		return estudios;

	}

	public List<LinkedHashMap<String, String>> reporteAcumulateBuys(String origen, Long id_estudio, String typeAbono,
			String fechaInicio, String fechaFin)
			throws ResultMapException, SQLException, 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;
			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 (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos.", e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos", e);
		}

		return acumulateBuys;

	}

	public InputStream generaExcelAcumumlateBuys(String fileFileName, String origen, Long id_estudio, String typeAbono,
			String fechaInicio, String fechaFin)
			throws ResultMapException, SQLException, TransaccionException, IllegalArgumentException, IllegalAccessException, ParseException, IOException {

		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;
			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 (PersistenceException e) {
            throw new TransaccionException("Error al cargar los datos.", e);
        } catch (DataAccessException e) {
            throw new TransaccionException("Error al cargar los datos", 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;

	}

}
