package com.FitBank.web.servlet;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import com.FitBank.web.util.EjecutarEventos;
import com.FitBank.xml.Mensaje.Bloque;
import com.FitBank.xml.Mensaje.Campo;
import com.FitBank.xml.Mensaje.Criterio;
import com.FitBank.xml.Mensaje.DatoGeneral;
import com.FitBank.xml.Mensaje.MensajeXml;

/**
 * Servlet utilizado para mostrar mensajes en pantalla. Devuelve un XML que NO
 * esta en el formato FITBANK estandar. Este XML es descargado a traves de AJAX
 * por la clase de mensajes, y mediante el interprete XML DOM incluido en todo
 * web browser actual lee los mensajes y las despliega al usuario.
 * 
 * @author FitBank
 * @version 1.0 Enero 2006
 */

public class MensajesUsuario extends BaseServlets {
	private static final long serialVersionUID = -5171988389968829444L;

	protected void inicializar() {
		aceptarGet();
		aceptarPost();
		verificarSesion();
	}

	public void procesarPedido() {
		if (pedido.getParameter("consMensajesUsuario") != null
				&& pedido.getParameter("consMensajesUsuario").equals("true")) {
			consultarMensajesUsuario();
		} else if (pedido.getParameter("procMensajesUsuario") != null)
			mantenimientoMensajesUsuario();
		else if (pedido.getParameter("genMensajesUsuario") != null
				&& pedido.getParameter("genMensajesUsuario").equals("true"))
			generarMensajesUsuario();
	}

	/**
	 * Consulta las notificaciones pendientes, y aquellas que ya han sido
	 * procesadas en el curso del dï¿½a actual. Devuelve al cliente un documento
	 * XML que no estï¿½ en el formato FITBANK estï¿½ndar, y que es interpretado
	 * a trav�s del web browser para mostrar las notificaciones al usuario.
	 */
	private void consultarMensajesUsuario() {
		Map mapaTipos = new HashMap();
		mapaTipos.put("cpersona", "persona");
		mapaTipos.put("ccuenta", "cuenta");
		mapaTipos.put("cidioma", "persona");

		EjecutarEventos eventoNt = new EjecutarEventos();
		eventoNt.procesoXml.getXmlMensaje().setEncabezado(copyEncabezado());
		eventoNt.ejecutarConsulta(pedido);

		List listaTipos = determinarTipo(eventoNt);

		String xml = null;

		if (listaTipos.size() > 0) {
			eventoNt.procesoXml.getXmlMensaje().setEncabezado(copyEncabezado());
			String tipo = (String) mapaTipos.get(listaTipos.get(0));
			pedido.setAttribute("tipoMensajeUsuario", tipo);
			eventoNt.ejecutarConsulta(pedido);
			xml = generateXMLMensajesUsuario(eventoNt);
		}

		respuesta.setContentType("text/xml");
		obtenerWriter();

		writer.print(xml);
		writer.close();
	}

	/**
	 * Inserta o actualiza una notificaci�n seg�n los par�metros enviados.
	 */
	private void mantenimientoMensajesUsuario() {
		EjecutarEventos eventoNt = new EjecutarEventos();
		eventoNt.procesoXml.getXmlMensaje().setEncabezado(copyEncabezado());

		eventoNt.ejecutarMantenimiento(pedido, false);

		obtenerWriter();
		writer.print("Notificacion insertada exitosamente");
		writer.close();
	}

	/**
	 * Genera una notificaciï¿½n a partir de la captura de un error.
	 */
	private void generarMensajesUsuario() {
		String codErr = pedido.getParameter("codErr");
		String[] msgUsuarioVals = null;
		Vector aut = evento.procesoXml.getXmlMensaje().autorizaciones;

		for (int i = 0; i < aut.size(); i++) {
			if (aut.elementAt(i) != null
					&& (aut.elementAt(i) instanceof DatoGeneral)) {
				DatoGeneral dtg = (DatoGeneral) aut.elementAt(i);

				if (dtg.getNombre().equals("NTF")) {
					String notStr = dtg.getValor();
					String[] vals = notStr.split("\\|");

					if (vals[1].equals(codErr)) {
						msgUsuarioVals = vals;
						break;
					}
				}
			}
		}

		evento.procesoXml.getXmlMensaje().borrarObjeto("NTF",
				MensajeXml.SEC_AUT);

		String toRet = "new Array('" + msgUsuarioVals[0] + "', '"
				+ msgUsuarioVals[1] + "', '" + msgUsuarioVals[2] + "', '"
				+ msgUsuarioVals[3] + "', '" + msgUsuarioVals[4] + "', '"
				+ msgUsuarioVals[5] + "')";

		obtenerWriter();
		writer.println(toRet);
		writer.close();
	}

	/**
	 * Copia el encabezado del evento principal, sin las referencias a
	 * subsistema, transacci�n y versi�n, para no alterarlos en
	 * manipulaciones posteriores.
	 * 
	 * @return un Vector con el encabezado del evento principal sin las
	 *         referencias a <SUB>, <TRN> y <VER>.
	 */
	private Vector copyEncabezado() {
		Vector newEnc = new Vector();
		Vector srcEnc = evento.procesoXml.getXmlMensaje().encabezado;

		for (int i = 0; i < srcEnc.size(); i++) {
			DatoGeneral dato = (DatoGeneral) srcEnc.elementAt(i);

			if (!dato.getNombre().equalsIgnoreCase("SUB")
					&& !dato.getNombre().equalsIgnoreCase("TRN")
					&& !dato.getNombre().equalsIgnoreCase("VER"))
				newEnc.add(dato);
		}

		return newEnc;
	}

	/**
	 * Procesa el evento de la consulta y genera un XML (que no estï¿½ en el
	 * formato FIT-BANK) con las notificaciones.
	 * 
	 * @param eventoNt
	 *            EjecutarEventos con el evento que contiene el mensaje de
	 *            respuesta
	 * @return un String con el XML de la lista de eventos.
	 */
	private String generateXMLMensajesPersona(EjecutarEventos eventoNt) {
		Bloque[] bloques = {
		// (Bloque) eventoNt.procesoXml.getXmlMensaje().detalle[0]
		// .elementAt(1),
		(Bloque) eventoNt.procesoXml.getXmlMensaje().detalle[0].elementAt(0) };

		// ////////Armado de documento XML con lista de
		// notificaciones///////////

		// String xml = "<?xml version=\"1.0\"
		// encoding=\"UTF-8\"?><FITBANK><NOT><NOM>Prueba</NOM><SUB>00</SUB><TRN>0001</TRN><FNT>01-01-2007</FNT><VER>01</VER><PND>true</PND></NOT><NOT><NOM>Prueba
		// 2</NOM><SUB>00</SUB><TRN>0999</TRN><FNT>02-02-2007</FNT><VER>01</VER><PND>true</PND></NOT></FITBANK>";
		String xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"
				+ "<FITBANK>";
		String isEmpty = "<EMPTY>true</EMPTY>";
		String codigoP = null;

		for (int blqCnt = 0; blqCnt < bloques.length; blqCnt++) {
			if (bloques[blqCnt].getNroRegistros() >= 1) {
				isEmpty = "";
				for (int i = 0; i < bloques[blqCnt].size(); i++) {
					Object elemento = bloques[blqCnt].campos.elementAt(i);
					if ((elemento instanceof Campo)
							&& !(elemento instanceof Criterio)) {
						Campo cmp = (Campo) elemento;

						if (cmp.getNombre().equals("493001")) {
							codigoP = cmp.getValor() != null ? cmp.getValor()
									: null;
						}

						if (cmp.getNombre().equals("493002"))// TEXTO
						{
							xml += "<NOT><NOM>" + codigoP + ": "
									+ cmp.getValor() + "</NOM></NOT>";
						}
					}
				}
			}
		}
		xml += isEmpty + "" + "</FITBANK>";
		//System.out.println(xml); // Despliega XML a enviar al cliente
		return xml;
	}

	/**
	 * Procesa el evento de la consulta y genera un XML (que no estï¿½ en el
	 * formato FIT-BANK) con las notificaciones.
	 * 
	 * @param eventoNt
	 *            EjecutarEventos con el evento que contiene el mensaje de
	 *            respuesta
	 * @return un String con el XML de la lista de eventos.
	 */
	private String generateXMLMensajesCuenta(EjecutarEventos eventoNt) {
		Bloque[] bloques = { (Bloque) eventoNt.procesoXml.getXmlMensaje().detalle[0]
				.elementAt(0) };
		String xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"
				+ "<FITBANK>";
		String isEmpty = "<EMPTY>true</EMPTY>";
		String codigoC = null;

		for (int blqCnt = 0; blqCnt < bloques.length; blqCnt++) {
			if (bloques[blqCnt].getNroRegistros() >= 1) {
				isEmpty = "";
				for (int i = 0; i < bloques[blqCnt].size(); i++) {
					Object elemento = bloques[blqCnt].campos.elementAt(i);
					if ((elemento instanceof Campo)
							&& !(elemento instanceof Criterio)) {
						Campo cmp = (Campo) elemento;
						if (cmp.getNombre().equals("492002")) {
							codigoC = cmp.getValor() != null ? cmp.getValor()
									: null;
						}
						if (cmp.getNombre().equals("492003"))// TEXTO
						{
							xml += "<NOT><NOM>" + codigoC + ": "
									+ cmp.getValor() + "</NOM></NOT>";
						}
					}
				}
			}
		}
		xml += isEmpty + "" + "</FITBANK>";
		//System.out.println(xml); // Despliega XML a enviar al cliente
		return xml;
	}

	/**
	 * Procesa el evento de la consulta y genera un XML (que no estï¿½ en el
	 * formato FIT-BANK) con las notificaciones.
	 * 
	 * @param eventoNt
	 *            EjecutarEventos con el evento que contiene el mensaje de
	 *            respuesta
	 * @return un String con el XML de la lista de eventos.
	 */
	private List determinarTipo(EjecutarEventos eventoNt) {
		Bloque[] bloques = { (Bloque) eventoNt.procesoXml.getXmlMensaje().detalle[0]
				.elementAt(0) };
		List listaTipos = new ArrayList();

		for (int blqCnt = 0; blqCnt < bloques.length; blqCnt++) {
			if (bloques[blqCnt].getNroRegistros() >= 1) {
				for (int i = 0; i < bloques[blqCnt].size(); i++) {
					Object elemento = bloques[blqCnt].campos.elementAt(i);
					Campo cmp = (Campo) elemento;
					if (cmp.getNombre().equals("16001")) {
						// TODO: Aqui no esta asignando el valor de la consulta
						listaTipos.add(cmp.getValor().toLowerCase());
					}
				}
			}
		}
		return listaTipos;
	}

	/**
	 * Procesa el evento de la consulta y genera un XML (que no estï¿½ en el
	 * formato FIT-BANK) con las notificaciones.
	 * 
	 * @param eventoNt
	 *            EjecutarEventos con el evento que contiene el mensaje de
	 *            respuesta
	 * @return un String con el XML de la lista de eventos.
	 */
	private String generateXMLMensajesUsuario(EjecutarEventos eventoNt) {
		Bloque[] bloques = { (Bloque) eventoNt.procesoXml.getXmlMensaje().detalle[0]
				.elementAt(0) };
		String xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"
				+ "<FITBANK>";
		String isEmpty = "<EMPTY>true</EMPTY>";
		String codigoP = null;
		String codigoC = null;

		for (int blqCnt = 0; blqCnt < bloques.length; blqCnt++) {
			if (bloques[blqCnt].getNroRegistros() >= 1) {
				isEmpty = "";

				for (int i = 0; i < bloques[blqCnt].size(); i++) {
					Object elemento = bloques[blqCnt].campos.elementAt(i);
					if ((elemento instanceof Campo)
							&& !(elemento instanceof Criterio)) {
						Campo cmp = (Campo) elemento;

						if (cmp.getNombre().equals("493001")) {
							codigoP = cmp.getValor() != null ? cmp.getValor()
									: null;
						}

						if (cmp.getNombre().equals("492002")) {
							codigoC = cmp.getValor() != null ? cmp.getValor()
									: null;
						}

						if (cmp.getNombre().equals("492003")) {
							xml += "<NOT><NOM>" + codigoC + ": "
									+ cmp.getValor() + "</NOM></NOT>";
						}
						if (cmp.getNombre().equals("493002")) {
							xml += "<NOT><NOM>" + codigoP + ": "
									+ cmp.getValor() + "</NOM></NOT>";
						}
					}
				}
			}
		}
		xml += isEmpty + "" + "</FITBANK>";
		//System.out.println(xml); // Despliega XML a enviar al cliente
		return xml;
	}
}