package com.ejie.ad74a.helper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.support.ReloadableResourceBundleMessageSource;

import com.ejie.ad74a.exceptions.ErrorField;
import com.ejie.ad74a.exceptions.Mensaje;
import com.ejie.ad74a.exceptions.ParametroKey;
import com.ejie.ad74a.util.comun.UtilLiterales;
import com.ejie.ad74a.util.comun.Utilidades;
import com.ejie.ad74a.util.constantes.Constantes;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * ErroresViewHelper.
 * 
 * @author GFI
 */

public final class ErroresViewHelper {

	/**
	 * Constructor de ErroresViewHelper
	 */
	private ErroresViewHelper() {
	}

	/**
	 * Metodo que convierte una lista de ErrorField en la sálida a Formato html para
	 * su tratamiento por el FeedBack de Errores. Formato p.ej.:
	 * 
	 * //
	 * <ul class="rup-maint_feedbackUL">
	 * Se han producido los siguientes errores:<br>
	 * <li><b>DNI:</b>
	 * <ul>
	 * <li>El campo es obligatorio.</li>
	 * </ul>
	 * </li>
	 * </ul>
	 * 
	 * @param messageSource ReloadableResourceBundleMessageSource mensajeSource
	 * @param errorFields   lista de errorField
	 * @return String Error formateado
	 */
	public static String obtenerErrorRup(ReloadableResourceBundleMessageSource messageSource,
			List<ErrorField> errorFields) {
		StringBuilder stb = new StringBuilder(Constantes.STRING_BUILDER_INIT);
		if (!Utilidades.isEmptyList(errorFields)) {
			// Generar Inicio
			stb.append("<ul class='rup-maint_feedbackUL'>");
			stb.append(UtilLiterales.getLiteralMessage(messageSource, "validacion.titulo"));
			stb.append("<br/>");
			boolean hayCampo = false;
			boolean esPrimerCampo;
			for (ErrorField errorField : errorFields) {
				hayCampo = false;
				if (errorField != null && errorField.getCampo() != null) {
					hayCampo = true;
					// Generar Campo
					stb.append("<li>").append("<b>");
					esPrimerCampo = true;
					for (String campo : errorField.getCampo()) {
						if (!esPrimerCampo) {
							stb.append(", ");
						}
						stb.append(UtilLiterales.getLiteralMessage(messageSource, campo));
						esPrimerCampo = false;
					}
					stb.append(":</b>");
				}
				boolean hayMensaje = false;
				for (Mensaje mensaje : errorField.getMensajes()) {
					// Generar Mensaje
					if (hayCampo && !hayMensaje) {
						stb.append("<ul>");
					}
					if (!hayCampo) {
						stb.append("<li>").append("<b>");
					} else {
						stb.append("<li>");
					}
					stb.append(mensaje.isTraducido() ? mensaje.getKey()
							: UtilLiterales.getLiteralMessageWithParams(messageSource, mensaje.getKey(),
									ErroresViewHelper.parseParametroKeyToObject(messageSource,
											mensaje.getParametrosKey())));
					if (!hayCampo) {
						stb.append("</b>");
						stb.append("</li>");
					} else {
						stb.append("</li>");
					}
					hayMensaje = true;
				}
				if (hayCampo && hayMensaje) {
					stb.append("</ul>");
				}
				if (hayCampo) {
					stb.append("</li>");
				}
			}
			stb.append("</ul>");
		}
		return stb.toString();
	}

	/**
	 * Metodo que traduce y serializa a json la lista de errorField pasada
	 * 
	 * @param messageSource ReloadableResourceBundleMessageSource mensajeSource
	 * @param errorFields   lista de errorField
	 * @return String json con el error
	 * 
	 * @throws IOException e, eerror al transformar a json
	 */
	public static String obtenerJsonErrorFields(ReloadableResourceBundleMessageSource messageSource,
			List<ErrorField> errorFields) throws IOException {
		if (!Utilidades.isEmptyList(errorFields)) {
			for (ErrorField errorField : errorFields) {
				if (errorField != null && errorField.getCampo() != null) {
					List<String> camposTraducidos = new ArrayList<String>();
					for (String campo : errorField.getCampo()) {
						camposTraducidos.add(UtilLiterales.getLiteralMessage(messageSource, campo));
					}
					errorField.setCampo(camposTraducidos.toArray(new String[0]));
				}
				for (Mensaje mensaje : errorField.getMensajes()) {
					mensaje.setKey(mensaje.isTraducido() ? mensaje.getKey()
							: UtilLiterales.getLiteralMessageWithParams(messageSource, mensaje.getKey(),
									ErroresViewHelper.parseParametroKeyToObject(messageSource,
											mensaje.getParametrosKey())));
					mensaje.setTraducido(true);
				}
			}
		}

		ObjectMapper mapper = new ObjectMapper();
		return mapper.toString();
	}

	/**
	 * Metodo que traduce y devuelve el mensaje pasado como parametro
	 * 
	 * @param messageSource ReloadableResourceBundleMessageSource mensajeSource
	 * @param mensaje       Mensaje, mensaje a traducir
	 * @return String mensaje traducido
	 */
	public static String obtenerMensaje(ReloadableResourceBundleMessageSource messageSource, Mensaje mensaje) {
		String mensajeStr = "";
		if (mensaje != null) {
			mensajeStr = mensaje.isTraducido() ? mensaje.getKey()
					: UtilLiterales.getLiteralMessageWithParams(messageSource, mensaje.getKey(),
							ErroresViewHelper.parseParametroKeyToObject(messageSource, mensaje.getParametrosKey()));
		}
		return mensajeStr;
	}

	/**
	 * Metodo que construye la respuesta para llamadas desde IE para escribir en el
	 * textarea el resultado
	 * 
	 * @param request           HttpServletRequest, la request
	 * @param response          HttpServletResponse, la response
	 * @param introduceTextArea boolean Indica si es necesario escribir el textarea.
	 *                          Caso especial de subida máxima permitida superada.
	 * @param texto             String, texto a escribir
	 * @throws IOException e error
	 */
	public static void writeRdoIframe(HttpServletRequest request, HttpServletResponse response,
			boolean introduceTextArea, String texto) throws IOException {
		ServletOutputStream outputStream = response.getOutputStream();
		if (introduceTextArea) {
			response.setStatus(HttpServletResponse.SC_OK);
		} else {
			response.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE);
		}
		response.setContentType("text/plain");
		response.setCharacterEncoding(Constantes.ENCODING_UTF8);
		if (introduceTextArea) {
			outputStream.write("<textarea status='406' statusText=''>".getBytes(Constantes.ENCODING_UTF8));
		}
		outputStream.write(texto.getBytes(Constantes.ENCODING_UTF8));
		if (introduceTextArea) {
			outputStream.write("</textarea>".getBytes(Constantes.ENCODING_UTF8));
		}
		outputStream.flush();
		outputStream.close();

		response.flushBuffer();
	}

	/**
	 * Metodo que parsea los parametros a objects
	 * 
	 * @param messageSource ReloadableResourceBundleMessageSource
	 * @param list          List<ParametroKey>
	 * @return Object[]
	 */
	private static Object[] parseParametroKeyToObject(ReloadableResourceBundleMessageSource messageSource,
			List<ParametroKey> list) {
		Object[] objetos = null;
		if (!Utilidades.isEmptyList(list)) {
			objetos = new Object[list.size()];
			int i = 0;
			for (ParametroKey parametroKey : list) {
				objetos[i] = parametroKey.isEsKey()
						? UtilLiterales.getLiteralMessage(messageSource, parametroKey.getValorParametro())
						: parametroKey.getValorParametro();
				i++;
			}
		}
		return objetos;
	}
}