package com.ejie.p06b.manager;

import java.io.IOException;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.TextMessage;
import javax.naming.NamingException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;

import com.ejie.p06b.util.P06BFecha;
import com.ejie.p06b.util.P06BParametros;

import com.ejie.p06b.dao.solreclamacion.P06bAltaMediadoresDao;
import com.ejie.p06b.datatype.model.P06B64T00Datatype;
import com.ejie.p06b.exception.P06BModMediadorException;
import com.ejie.p06b.log.P06BLog;
//import com.ejie.p06b.manager.contextSubmissionEvent.ChannelInfoTypeEvent;
//import com.ejie.p06b.manager.contextSubmissionEvent.ContextSubmissionEvent;
//import com.ejie.p06b.manager.notificationBody.NotificationBody;
//import com.ejie.p06b.manager.contextSubmissionEvent.ApplicantInfoEvent;
//import com.ejie.p06b.manager.contextSubmissionEvent.NoticeChannelEvent;
import com.ejie.aa87b.manager.contextSubmissionEvent.ChannelInfoTypeEvent;
import com.ejie.aa87b.manager.contextSubmissionEvent.ContextSubmissionEvent;
import com.ejie.aa87b.manager.notificationBody.NotificationBody;
import com.ejie.aa87b.manager.contextSubmissionEvent.ApplicantInfoEvent;
import com.ejie.aa87b.manager.contextSubmissionEvent.NoticeChannelEvent;
import com.ejie.p06b.manager.detailInfo.DetailInfo;
import com.ejie.p06b.manager.ejgvDocument.EjgvDocument;
import com.ejie.p06b.manager.ejgvDocument.Persons;
import com.ejie.p06b.model.DatosMediadores;
import com.ejie.p06b.utils.R76bParameters;
import com.ejie.p06b.x43.handler.HeaderHandlerResolver;

//import com.ejie.c42.x43.wsclient.Exception_Exception;
import com.ejie.aa87b.x43Toolkit.wsclient.Exception_Exception;
//import com.ejie.c42.x43.wsclient.X43KWebService;
import com.ejie.aa87b.x43Toolkit.wsclient.X43KWebService;
//import com.ejie.c42.x43.wsclient.X43KWebService_Service;
import com.ejie.aa87b.x43Toolkit.wsclient.X43KWebService_Service;

import com.ejie.p06b.general.P06BConstantes;

public class P06bMng {
	
	private static Properties parametros = null;
	
	//private static String PROCEDIMIENTO_ALTA_REG_MEDIADORES_SEGUROS = R76bMng.getProperties().getProperty("idProcAltaRegMedSeg");
	public static final String PROCEDIMIENTO_ALTA_REG_MEDIADORES_SEGUROS = P06BParametros.get("idProcAltaRegMedSeg");
	public static final String PROCEDIMIENTO_MODIF_REG_MEDIADORES_SEGUROS = P06BParametros.get("idProcModRegMedSeg");
	public static final String PROCEDIMIENTO_CANCEL_REG_MEDIADORES_SEGUROS = P06BParametros.get("idProcCancelRegMedSeg");
	public static final String PROCEDIMIENTO_AUTORIZACION_REG_MEDIADORES_SEGUROS = P06BParametros.get("idProcAutorizTransRegMedSeg");
	
	
	//private static String X43TOOLKIT_URL = R76bMng.getProperties().getProperty("X43TOOLKIT_URL");
	public static final String X43TOOLKIT_URL = P06BParametros.get("X43TOOLKIT_URL");
	
	/**
	 * Constructor por defecto
	 */
	private P06bMng() {
	}
	
	/**
	 * Método que obtiene el objeto de propiedades de la aplicación
	 * 
	 * @return Devuelve un objeto Properties con las propiedades de la
	 *         aplicación
	 */
	public static Properties getProperties() {
		try {
			if (P06bMng.parametros == null) {
				P06bMng.parametros = new P06BParametros().getParametros();
			}
		} catch (IOException ioe) {
			P06BLog.send(0,P06bMng.class, "(getProperties) Error al cargar el fichero de propiedades de la aplicación");
		}
		return P06bMng.parametros;
	}
	
	
	/**
	 * Recupera el cuerpo CDATA del mensaje del evento
	 * 
	 * @param message
	 *            Mensaje del evento
	 * @return Devuelve un objeto de tipo NotificationCData con la información
	 *         contenida en este cuerpo
	 */
	public static ContextSubmissionEvent getNotificationCData(String message, P06B64T00Datatype p06B64T00Datatype) throws JAXBException {

		// Se parsea para informar NotificationBody
		NotificationBody notification = null;
		P06BLog.send(0,P06bMng.class, "(getNotificationCData) Parseando la respuesta del evento");
		JAXBContext jaxbNotificationBody = JAXBContext
				.newInstance(NotificationBody.class);
		Unmarshaller jaxbUnmarshallerNotBody = jaxbNotificationBody
				.createUnmarshaller();
		StringReader readerNotBody = new StringReader(message);
		notification = (NotificationBody) jaxbUnmarshallerNotBody
				.unmarshal(readerNotBody);
		p06B64T00Datatype.setContextSubmissionEvent(notification.getXmlValue().get(0));

		// Se parsea para informar ContextSubmissionEvent
		ContextSubmissionEvent contextSubmissionEvent = null;
		P06BLog.send(0,P06bMng.class, "(getNotificationCData) Parseando el CDATA de la respuesta del evento");
		JAXBContext jaxbNotificationCData = JAXBContext
				.newInstance(ContextSubmissionEvent.class);
		Unmarshaller jaxbUnmarshallerNotCData = jaxbNotificationCData
				.createUnmarshaller();
		StringReader readerNotCData = new StringReader(
				notification.getXmlValue().get(0));
		contextSubmissionEvent = (ContextSubmissionEvent) jaxbUnmarshallerNotCData
				.unmarshal(readerNotCData);

		P06BLog.send(0,P06bMng.class, "(getNotificationCData) Revisando el procedimiento asociado al evento");
		boolean bProcConocido = false;
		if (contextSubmissionEvent.getProcedureID() != null){
			if ( (contextSubmissionEvent.getProcedureID().equals( P06bMng.PROCEDIMIENTO_ALTA_REG_MEDIADORES_SEGUROS)) ||
			(contextSubmissionEvent.getProcedureID().equals( P06bMng.PROCEDIMIENTO_MODIF_REG_MEDIADORES_SEGUROS)) ||
			(contextSubmissionEvent.getProcedureID().equals( P06bMng.PROCEDIMIENTO_CANCEL_REG_MEDIADORES_SEGUROS)) ||
			(contextSubmissionEvent.getProcedureID().equals( P06bMng.PROCEDIMIENTO_AUTORIZACION_REG_MEDIADORES_SEGUROS)) ){
				bProcConocido = true;
			}
		}
		if (bProcConocido){
			// Se devuelve el objeto de notificación contenido en el CDATA
			P06BLog.send(0,P06bMng.class, "(getNotificationCData) Procedimiento de mediadores de seguros: " + contextSubmissionEvent.getProcedureID());
			return contextSubmissionEvent;
		} else {
			// No se trata de una solicitud del procedimiento del alta de
			// epsvs (0602107)
			P06BLog.send(0,P06bMng.class, "(getNotificationCData) Tipo de procedimiento no contemplado");
			return null;
		}

	}
	
	/**
	 * Recupera la información adicional de la petición llamadno al servicio de
	 * Platea a partir de su identificador de solicitud
	 * 
	 * @param idSolicitud
	 *            Identificador de la solicitud
	 * @return Devuelve un objeto de tipo EjgvDocument con la información
	 *         adicional de la petición
	 */
	public static EjgvDocument getRequestInformation(String idSolicitud, P06B64T00Datatype p06B64T00Datatype) throws JAXBException, MalformedURLException, Exception_Exception {

		// Se inicializa la petición al servicio de X43 (Platea)
		P06BLog.send(2,P06bMng.class,"(getRequestInformation) Inicializando la petición al servicio de X43 (Platea)");
		
		// Se inicializa la petición al servicio de X43 (Platea)
		P06BLog.send(2,P06bMng.class,"(getRequestInformation) Inicializando la petición al servicio de X43 (Platea)");
		X43KWebService_Service service = null;
//		service = new X43KWebService_Service(new URL(P06bMng.X43TOOLKIT_URL));
		service = new X43KWebService_Service(new URL(P06bMng.X43TOOLKIT_URL), new QName("com/ejie/toolkit/xml", "x43kWebService"));
		
		HeaderHandlerResolver handlerResolver = new HeaderHandlerResolver();
		service.setHandlerResolver(handlerResolver);

		X43KWebService x43Service = service.getX43KWebServicePort();

		// Se invoca al método getRequestInformation con el identificador de
		// solicitud asociada
		P06BLog.send(2,P06bMng.class, "(getRequestInformation) Invocando al método getRequestInformation con el identificador de solicitud asociada: "
						+ idSolicitud);
		String document = x43Service.getRequestInformation(idSolicitud, null);
		p06B64T00Datatype.setEjgvDocument(document);

		// Se parsea el XML de respuesta del método getRequestInformation al objeto asociado
		EjgvDocument ejgvDocument = null;
		P06BLog.send(2, P06bMng.class, "(getRequestInformation) Parseando el XML de respuesta del método getRequestInformation al objeto asociado");
		JAXBContext jaxbContext = JAXBContext
				.newInstance(EjgvDocument.class);
		Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
		StringReader reader = new StringReader(document);
		ejgvDocument = (EjgvDocument) jaxbUnmarshaller.unmarshal(reader);
		P06BLog.send(2,P06bMng.class, "(getRequestInformation) Devolviendo el objeto con los datos de negocio una vez parseado");
		
		return ejgvDocument;
	}
	
	/**
	 * Parsea la informaciÃ³n de nuestro modelo de negocio
	 * 
	 * @param idSolicitud
	 *            Identificador de la solicitud
	 * @return Devuelve un objeto de tipo EjgvDocument con la informaciÃ³n
	 *         adicional de la peticion
	 */
	public static DetailInfo getDetailInfo(String detailInfoStr) {
		DetailInfo detailInfo = null;
		
		// Se parsea el contenido del modelo de negocio
		try {
			// Parseo de la respuesta del modelo de negocio
			P06BLog.send(2,P06bMng.class, "(getDetailInfo) Parseando la respuesta del modelo de negocio");
			JAXBContext jaxbDetailInfo = JAXBContext
					.newInstance(DetailInfo.class);
			Unmarshaller jaxbUnmarshallerDetailInfo = jaxbDetailInfo
					.createUnmarshaller();
			StringReader readerDetailInfo = new StringReader(detailInfoStr);
			detailInfo = (DetailInfo) jaxbUnmarshallerDetailInfo
					.unmarshal(readerDetailInfo);
		} catch (JAXBException jaxbExc) {
			P06BLog.send(2,P06bMng.class, "(getDetailInfo) Error al intentar parsear el XML de respuesta del modelo de negocio");
			return null;
		}
		
		return detailInfo;
	}
	
	/**
	 * Añade la información de negocio obtenida asociada al evento a base de
	 * datos
	 * 
	 * @param ejgvDocument
	 *            Objeto de tipo EjgvDocument con la información de negocio
	 *            asociada
	 * @return Devuelve el estado de la inserción, true si todo ha ido bien,
	 *         false si ha existido algún problema
	 */
	public static boolean addAltaMediadoresToDB(P06bAltaMediadoresDao p06bDao, EjgvDocument ejgvDoc, ContextSubmissionEvent cData, P06B64T00Datatype p06B64T00Datatype) throws SQLException, P06BModMediadorException {
		
		P06BLog.send(2,P06bMng.class, "(addAltaMediadoresToDB) Creación del objeto con los datos de negocio parseados");
		
		DatosMediadores datosAltaMediador = new DatosMediadores(p06bDao.getLastExpediente()+1, p06bDao, ejgvDoc, cData, p06B64T00Datatype);
		P06BLog.send(2,P06bMng.class, "(addAltaMediadoresToDB) insertarAltaMediador..." );
		p06bDao.insertarAltaMediador(datosAltaMediador, p06B64T00Datatype, ejgvDoc, cData);
		P06BLog.send(2,P06bMng.class, "(addAltaMediadoresToDB) insertarAltaMediador: Datos de la solicitud insertados en la base de datos de manera correcta");

		return true;
		
	}


	
	/**
	 * Añade la información de negocio obtenida asociada al evento a base de
	 * datos
	 * 
	 * @param ejgvDocument
	 *            Objeto de tipo EjgvDocument con la información de negocio
	 *            asociada
	 * @return Devuelve el estado de la inserción, true si todo ha ido bien,
	 *         false si ha existido algún problema
	 */
	public static boolean addModMediadoresToDB(P06bAltaMediadoresDao p06bDao, EjgvDocument ejgvDoc, ContextSubmissionEvent cData, P06B64T00Datatype p06B64T00Datatype) throws SQLException, P06BModMediadorException {
		
		P06BLog.send(2,P06bMng.class, "(addModMediadoresToDB) Creación del objeto con los datos de negocio parseados");
		
		DatosMediadores datosModifMediador = new DatosMediadores(p06bDao, ejgvDoc, cData, p06B64T00Datatype);
		P06BLog.send(2,P06bMng.class, "(addModMediadoresToDB) insertarModMediador..." );
		p06bDao.insertarModMediador(datosModifMediador, p06B64T00Datatype, ejgvDoc, cData);
		P06BLog.send(2,P06bMng.class, "(addModMediadoresToDB) insertarModMediador: Datos de la solicitud insertados en la base de datos de manera correcta");

		return true;
		
	}


	
	/**
	 * Añade la información de negocio obtenida asociada al evento a base de
	 * datos
	 * 
	 * @param ejgvDocument
	 *            Objeto de tipo EjgvDocument con la información de negocio
	 *            asociada
	 * @return Devuelve el estado de la inserción, true si todo ha ido bien,
	 *         false si ha existido algún problema
	 */
	public static boolean addAutMediadoresToDB(P06bAltaMediadoresDao p06bDao, EjgvDocument ejgvDoc, ContextSubmissionEvent cData, P06B64T00Datatype p06B64T00Datatype) throws SQLException, P06BModMediadorException {
		
		P06BLog.send(2,P06bMng.class, "(addAutMediadoresToDB) Creación del objeto con los datos de negocio parseados");
		
		int  i = 0;
		DatosMediadores datosModifMediador = new DatosMediadores(p06bDao, ejgvDoc, cData, p06B64T00Datatype, i);
		P06BLog.send(2,P06bMng.class, "(addAutMediadoresToDB) autorizarMediador..." );
		p06bDao.autorizarMediador(datosModifMediador, p06B64T00Datatype, ejgvDoc, cData);
		P06BLog.send(2,P06bMng.class, "(addAutMediadoresToDB) autorizarMediador: Datos de la solicitud insertados en la base de datos de manera correcta");

		return true;
		
	}


	
	/**
	 * Añade la información de negocio obtenida asociada al evento a base de
	 * datos
	 * 
	 * @param ejgvDocument
	 *            Objeto de tipo EjgvDocument con la información de negocio
	 *            asociada
	 * @return Devuelve el estado de la inserción, true si todo ha ido bien,
	 *         false si ha existido algún problema
	 */
	public static boolean addCancelMediadoresToDB(P06bAltaMediadoresDao p06bDao, EjgvDocument ejgvDocument, ContextSubmissionEvent cData, P06B64T00Datatype p06B64T00Datatype) throws SQLException, P06BModMediadorException {
		
		P06BLog.send(2,P06bMng.class, "(addCancelMediadoresToDB) Creación del objeto con los datos de negocio parseados");
		
		DatosMediadores datosCancelacionMediador = new DatosMediadores(p06bDao, ejgvDocument, cData, p06B64T00Datatype, true);
		P06BLog.send(2,P06bMng.class, "(addCancelMediadoresToDB) cancelacionMediador..." );
		p06bDao.cancelacionMediador(datosCancelacionMediador, p06B64T00Datatype, ejgvDocument);
		P06BLog.send(2,P06bMng.class, "(addCancelMediadoresToDB) cancelacionMediador: Cancelación efectuada en base de datos de manera correcta");

		return true;
		
	}


	
	/**
	 * Método que obtiene el identificador del procedimiento de alta de solicitud de reclamación
	 * 
	 * @return Devuelve un objeto String con el identificador del procedimiento
	 *         de alta de solicitud de reclamación
	 */
//	public static String getProcedimientoSolicitudReclamacion() {
//		return P06bMng.PROCEDIMIENTO_ALTA_REG_MEDIADORES_SEGUROS;
//	}


}
