package com.ejie.ab39a.service;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Service;

import com.ejie.ab39a.constantes.Constantes;
import com.ejie.ab39a.constantes.TipoEntidadEnum;
import com.ejie.ab39a.model.CertificadoPDF;
import com.ejie.ab39a.model.ElementosArbol;
import com.ejie.ab39a.model.ElementosPe;
import com.ejie.ab39a.model.Entidades;
import com.ejie.ab39a.model.PlanesEstrategicos;
import com.ejie.ab39a.utils.UtilCertificados;
import com.ejie.ab39a.utils.UtilProperties;

/**
 * Eje.
 * 
 *  
 */
@Service(value = "pdfService")
public class PdfServiceImpl implements PdfService {

	private final static boolean blnCertificadosAFichero = false;
	private static final Logger logger = LoggerFactory.getLogger(PdfServiceImpl.class);

	/**
	 * Generar excel pe
	 * 
	 * @param appMessageSource
	 *            ReloadableResourceBundleMessageSource appMessageSource
	 * @param plan
	 *            PlanesEstrategicos plan
	 * @param lista
	 *            List<ElementosArbol> lista
	 * @return ByteArrayOutputStream ByteArrayOutputStream
	 * @throws FileNotFoundException
	 *             e e
	 * @throws IOException
	 *             e e
	 */
	public ByteArrayOutputStream generarPdfPE(ReloadableResourceBundleMessageSource appMessageSource,
			PlanesEstrategicos plan, List<ElementosArbol> lista) throws FileNotFoundException, IOException {

		// Codigo referente a la generacion del pdf
		// -------------------------------------------------------------
		// Recuperacion del idioma
		Locale locale = LocaleContextHolder.getLocale();
		String idioma = locale.getLanguage();

		HashMap<String, String> valoresVariables = new HashMap<String, String>();

		StringBuilder sTmp = new StringBuilder();

		// valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_NOMBRECAS,
		// plan.getNombre());
		// valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_NOMBREEUS,
		// plan.getNombreeus());
		Entidades ent = plan.getEntidad();
		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_NOMBRE_ENTIDAD, ent.getDesentidad());
		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_NOMBREPE, plan.getNombreEsEu());

		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_ANYO_INI, String.valueOf(plan.getAnyoinicio()));
		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_ANYO_FIN, String.valueOf(plan.getAnyofin()));
		// --------------------------------------------
		// Solo debe mostrarse para entidades de tipo 1
		if (ent.getTipoEntidad().longValue() == TipoEntidadEnum.HERRI_ADMINISTRAZIOA.getId()) {
			valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_INDICE_OBLIGAT,
					String.valueOf(plan.getIndiceObligat()));
			valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_NIVEL_CUMPLIMIENTO,
					String.valueOf(plan.getNivelCumplimientoReqeus()));
		} else {
			valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_INDICE_OBLIGAT, "");
			valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_NIVEL_CUMPLIMIENTO, "");
		}
		// ------------------------------------------------
		// Solo debe mostrarse para entidades de tipo 2 y 3
		if ((ent.getTipoEntidad().longValue() == TipoEntidadEnum.ENPRESA_PRIBATUA.getId())
				|| (ent.getTipoEntidad().longValue() == TipoEntidadEnum.ENTE_PUBLIKOA.getId())) {
			valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_PORCENTAJE_BILING,
					String.valueOf(plan.getPorcentajeBiling()));
		} else {
			valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_PORCENTAJE_BILING, "");
		}
		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_FECHA_ACEPTACION, plan.getFechaAceptacionPlanStr());
		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_IMG_CABECERA,
				UtilProperties.getProperty(Constantes.PARAMETRO_PROPERTIES_PDF_PLANE_IMG_CABECERA));
		// -------------------------------------------------------------
		// Recuperacion de las filas de los EJES y elementos

		sTmp = new StringBuilder("");
		String sEstiloEJE = "celdaDatosPlanNombreEJE";
		String sEstiloObjetivo = "celdaDatosPlanDatoLargo";
		// String sEstiloDatos = "celdaDatosPlanDatoCorto";
		List<ElementosArbol> elementoArbol = lista.get(0).getHijosArbol();
		for (int i = 0; i < elementoArbol.size(); i++) {

			sTmp.append("<tr>\n");
			// Nombre del elemento
			sTmp.append("<td class=\"").append(sEstiloEJE);
			sTmp.append("\">");
			sTmp.append(idioma.equals(Constantes.IDIOMA_ES) ? elementoArbol.get(i).getNombrecasA()
					: elementoArbol.get(i).getNombreA());
			sTmp.append("</td>");

			// Objetivo del elemento
			sTmp.append("<td colspan='6' class=\"").append(sEstiloObjetivo);
			sTmp.append("\">");
			sTmp.append(idioma.equals(Constantes.IDIOMA_ES) ? elementoArbol.get(i).getHelburucasA()
					: elementoArbol.get(i).getHelburuA());
			sTmp.append("</td>");
			/*
			 * sTmp.append("<td class=\"").append(sEstiloDatos).append(
			 * "\">&nbsp;</td>");
			 * sTmp.append("<td class=\"").append(sEstiloDatos).append(
			 * "\">&nbsp;</td>\n");
			 * sTmp.append("<td class=\"").append(sEstiloDatos).append(
			 * "\">&nbsp;</td>");
			 * sTmp.append("<td class=\"").append(sEstiloDatos).append(
			 * "\">&nbsp;</td>\n");
			 * sTmp.append("<td class=\"").append(sEstiloDatos).append(
			 * "\">&nbsp;</td>");
			 * sTmp.append("<td class=\"").append(sEstiloDatos).append(
			 * "\">&nbsp;</td>\n");
			 */
			sTmp.append("</tr>\n");
			this.getEjesElementosTR_HTML(idioma, sTmp, elementoArbol.get(i).getHijosArbol());

		}

		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_FILAS_EJES_ELEMENTOS, sTmp.toString());

		// Recuperacion de literales segun idioma
		Object[] params = {};
		String sIdioma = "";
		sIdioma = appMessageSource.getMessage(Constantes.PARAMETRO_PROPERTIES_PLAN_LIT_TIT_PLANE, params, locale);
		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_TIT_PLANE, sIdioma);
		sIdioma = appMessageSource.getMessage(Constantes.PARAMETRO_PROPERTIES_PLAN_LIT_NOMBRE_ENTIDAD, params, locale);
		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_NOMBRE_ENTIDAD, sIdioma);
		sIdioma = appMessageSource.getMessage(Constantes.PARAMETRO_PROPERTIES_PLAN_LIT_NOMBRE_PLAN, params, locale);
		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_NOMBRE_PLAN, sIdioma);
		sIdioma = appMessageSource.getMessage(Constantes.PARAMETRO_PROPERTIES_PLAN_LIT_ANYOINICIO, params, locale);
		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_ANYOINICIO, sIdioma);
		sIdioma = appMessageSource.getMessage(Constantes.PARAMETRO_PROPERTIES_PLAN_LIT_ANYOFIN, params, locale);
		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_ANYOFIN, sIdioma);
		// --------------------------------------------
		// Solo debe mostrarse para entidades de tipo 1
		if (ent.getTipoEntidad().longValue() == TipoEntidadEnum.HERRI_ADMINISTRAZIOA.getId()) {
			sIdioma = appMessageSource.getMessage(Constantes.PARAMETRO_PROPERTIES_PLAN_LIT_INDICE, params, locale);
			valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_INDICE, sIdioma);
			sIdioma = appMessageSource.getMessage(Constantes.PARAMETRO_PROPERTIES_PLAN_LIT_NIVELCUMPL, params, locale);
			valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_NIVELCUMPL, sIdioma);
		} else {
			valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_INDICE, "");
			valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_NIVELCUMPL, "");
		}
		// ------------------------------------------------
		// Solo debe mostrarse para entidades de tipo 2 y 3
		if ((ent.getTipoEntidad().longValue() == TipoEntidadEnum.ENPRESA_PRIBATUA.getId())
				|| (ent.getTipoEntidad().longValue() == TipoEntidadEnum.ENTE_PUBLIKOA.getId())) {
			sIdioma = appMessageSource.getMessage(Constantes.PARAMETRO_PROPERTIES_PLAN_LIT_PORCENTAJE, params, locale);
			valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_PORCENTAJE, sIdioma);
		} else {
			valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_PORCENTAJE, "");
		}
		sIdioma = appMessageSource.getMessage(Constantes.PARAMETRO_PROPERTIES_PLAN_LIT_FECHAACEP, params, locale);
		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_FECHAACEP, sIdioma);
		sIdioma = appMessageSource.getMessage(Constantes.PARAMETRO_PROPERTIES_PLAN_LIT_NOMBRE, params, locale);
		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_NOMBRE, sIdioma);
		/*
		 * sIdioma = appMessageSource.getMessage(Constantes.
		 * PARAMETRO_PROPERTIES_PLAN_LIT_OBJETIVO, params, locale);
		 * valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_OBJETIVO,
		 * sIdioma);
		 */
		sIdioma = appMessageSource.getMessage(Constantes.PARAMETRO_PROPERTIES_PLAN_LIT_HASIERA, params, locale);
		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_HASIERA, sIdioma);
		sIdioma = appMessageSource.getMessage(Constantes.PARAMETRO_PROPERTIES_PLAN_LIT_AURRE, params, locale);
		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_AURRE, sIdioma);
		sIdioma = appMessageSource.getMessage(Constantes.PARAMETRO_PROPERTIES_PLAN_LIT_AMAI, params, locale);
		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_AMAI, sIdioma);
		sIdioma = appMessageSource.getMessage(Constantes.PARAMETRO_PROPERTIES_PLAN_LIT_EUS, params, locale);
		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_EUS, sIdioma);
		sIdioma = appMessageSource.getMessage(Constantes.PARAMETRO_PROPERTIES_PLAN_LIT_ELEBI, params, locale);
		valoresVariables.put(Constantes.VALOR_VARIABLE_PLAN_LIT_ELEBI, sIdioma);

		// -------------------------------------------------------------
		// Fin de valores recuperados de las plantillas
		// -------------------------------------------------------------

		CertificadoPDF cert = new CertificadoPDF();
		cert.setRutaPlantilla(UtilProperties.getProperty(Constantes.PARAMETRO_PROPERTIES_PDF_PLANE_HTML));
		cert.setRutaICC(UtilProperties.getProperty(Constantes.PARAMETRO_PROPERTIES_PDF_ICC_PROFILE));
		cert.setRutaImagenes(UtilProperties.getProperty(Constantes.PARAMETRO_PROPERTIES_PDF_DIR_IMAGENES));
		ArrayList<String> rutasCss = new ArrayList<String>();
		rutasCss.add(UtilProperties.getProperty(Constantes.PARAMETRO_PROPERTIES_PDF_PLANE_CSS));
		cert.setRutasCss(rutasCss);

		ArrayList<String> rutasFuente = new ArrayList<String>();
		rutasFuente.add(UtilProperties.getProperty(Constantes.PARAMETRO_PROPERTIES_PDF_FUENTE));
		cert.setRutasFuente(rutasFuente);

		// cert.setRutaMarcaAgua(this.utilidadesProperties
		// .getProperty(Constantes.PARAMETRO_PROPERTIES_CERTIFICADO_EVAL_CURSO_MARCAAGUA));
		ByteArrayOutputStream baos = null;
		cert.setDatosVariables(valoresVariables);
		cert.setPonerMarcaAgua(false);
		cert.setAddNumerosDePagina(true);
		cert.setPosXNumPag(Constantes.LONG_OCHOCIENTOS);
		cert.setPosYNumPag(Constantes.LONG_VEINTE);
		try {
			baos = this.getCertificadoPDF(cert);

			String sNombreFichero = UtilProperties.getProperty(Constantes.PARAMETRO_PROPERTIES_PDF_SALIDA_DIR)
					+ "/pdfPlanEstrategico" + System.currentTimeMillis() + ".pdf";
			// Inicio de comentar antes de subir, esta solo para testear el
			// funcionamiento sacando el pdf a disco
			if (PdfServiceImpl.blnCertificadosAFichero) {
				FileOutputStream pdfGenerado = null;
				try {
					pdfGenerado = new FileOutputStream(new File(sNombreFichero));
					pdfGenerado.write(baos.toByteArray());
					pdfGenerado.flush();
				} catch (Exception e) {
					throw (e);
				} finally {
					if (null != pdfGenerado) {
						pdfGenerado.close();
					}
				}

			}
			// Fin de comentar antes de subir, esta solo para testear el
			// funcionamiento sacando el pdf a disco

		} catch (Exception e) {
			PdfServiceImpl.logger.info("error");
		}
		return baos;
	}

	/**
	 * 
	 * @param idioma
	 *            String
	 * @param sTmp
	 *            StringBuffer
	 * @param elementoArbol
	 *            List<ElementosArbol>
	 */
	private void getEjesElementosTR_HTML(String idioma, StringBuilder sTmp, List<ElementosArbol> elementoArbol) {
		ElementosPe elemPe = null;

		for (int x = 0; x < elementoArbol.size(); x++) {
			elemPe = (ElementosPe) elementoArbol.get(x);
			sTmp.append(elemPe.getTR_HTML(idioma));

			if ((null != elemPe.getHijosArbol()) && (elemPe.getHijosArbol().size() > 0)) {
				getEjesElementosTR_HTML(idioma, sTmp, elemPe.getHijosArbol());
			}

		}
	}

	/**
	 * Generacion del certificado
	 * 
	 * @param certificadoPDF
	 *            CertificadoPDF
	 * @return ByteArrayOutputStream
	 * @throws Exception
	 *             e
	 */
	public ByteArrayOutputStream getCertificadoPDF(CertificadoPDF certificadoPDF) throws Exception {

		ByteArrayOutputStream baos = new ByteArrayOutputStream();

		FileInputStream plantillaHtml = new FileInputStream(new File(certificadoPDF.getRutaPlantilla()));

		UtilCertificados.generarPDF(plantillaHtml, baos, certificadoPDF);

		return baos;

	}

}
