package com.ejie.ad74a.jms.service;

import java.util.HashMap;
import java.util.Map;

import javax.jms.Message;
import javax.jms.TextMessage;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ejie.ad74a.dao.ErrorJmsDao;
import com.ejie.ad74a.exceptions.Ad74aException;
import com.ejie.ad74a.exceptions.ManagerErrors;
import com.ejie.ad74a.jms.util.JMSHelper;
import com.ejie.ad74a.jms.util.MessageParser;
import com.ejie.ad74a.jms.util.ModelApplicationParser;
import com.ejie.ad74a.model.ErrorJms;
import com.ejie.ad74a.scheduler.JobSchedulerService;
import com.ejie.ad74a.scheduler.SchedulerJobType;
import com.ejie.ad74a.service.BandejaPapel0Service;
import com.ejie.ad74a.util.constantes.Constantes;
import com.ejie.ad74a.ws.client.platea.model.notification.NotificationBody;

/**
 * EntidadesServiceImpl generated by UDA, 21-jul-2021 10:42:45.
 * 
 * @author UDA
 */

@Service(value = "plateaJMSService")
public class PlateaJMSServiceImpl implements PlateaJMSService {

	private static final Logger logger = LoggerFactory.getLogger(PlateaJMSServiceImpl.class);

	@Autowired
	private RequestJMSService requestJMSService;

	@Autowired
	private TaskJMSService taskJMSService;

	@Autowired
	private LocatorJMSService locatorJMSService;

	@Autowired
	private ErrorJmsDao errorJmsDao;

	@Autowired
	private JobSchedulerService jobSchedulerService;

	@Autowired
	BandejaPapel0Service bandejaPapel0Service;

	@Override
	public synchronized void tratarMessage(Message inMessage) throws Throwable {
		PlateaJMSServiceImpl.logger.debug("PlateaJMSServiceImpl - tratarMessage");

		TextMessage msg = null;
		String strQueEvento = "";

		String idMensaje = "";
		if (inMessage instanceof TextMessage) {
			msg = (TextMessage) inMessage;
			PlateaJMSServiceImpl.logger.debug("PlateaJMSServiceImpl - onMessage msg: " + msg);
			// Recuperamos el NotificationBody
			NotificationBody notificationBody = null;
			boolean error = false;
			try {
				MessageParser<NotificationBody> parserTarea = new MessageParser<NotificationBody>(
						NotificationBody.class.getPackage().getName());

				notificationBody = parserTarea.parse(msg.getText());
			} catch (Exception e) {
				PlateaJMSServiceImpl.logger
						.error("PlateaJMSServiceImpl.onMessage - Error al parsear el mensaje de la cola " + e);
				error = true;
			}
			if (!error) {
				Map<String, Object> mapaMensaje = JMSHelper.parsearMensajeJms(msg.getText());
				try {
					mapaMensaje.put("jmsid", inMessage.getStringProperty("messageIdPropagado"));
				} catch (Exception e) {
					PlateaJMSServiceImpl.logger.error("PlateaJMSServiceImpl.onMessage - Error al recuperar el jmsid");
				}

				try {
					strQueEvento = (String) mapaMensaje.get("EventWhat");
					// enrutamos segun tipo de evento
					if (Constantes.R02_REQUEST.equals(strQueEvento)) {
						/********* EVENTO SOLICITUD *****************/
						this.requestJMSService.proccesRequest(notificationBody, mapaMensaje);
					} else if (Constantes.R02_TASK.equals(strQueEvento)) {
						/********* EVENTO TAREAS *****************/
						this.taskJMSService.tratamientoTask(notificationBody, mapaMensaje);
					} else if (Constantes.LOCATOR_RESULT.equals(strQueEvento)) {
						/********* EVENTO TAREAS *****************/
						this.locatorJMSService.tratamientoLocator(notificationBody, mapaMensaje);
					}
				} catch (Throwable e) {
					PlateaJMSServiceImpl.logger.error("Error al tratar el message: ");
					// guardamos el mensaje de error
					ErrorJms mensajeJms = ModelApplicationParser.getMensajeJmsToError(mapaMensaje);
					if (e instanceof Ad74aException) {
						Ad74aException ex = (Ad74aException) e;
						mensajeJms.setErrormsg50(getErrorMessage(ex.getMessage()));
						mensajeJms.setError50(ex.getCodeError());
						PlateaJMSServiceImpl.logger.error("Error procesar evento: " + ex.getMessage());
					} else {
						mensajeJms.setErrormsg50(getErrorMessage(ExceptionUtils.getStackTrace(e)));
						PlateaJMSServiceImpl.logger.error("Error procesar evento: " + ExceptionUtils.getStackTrace(e));
					}
					mensajeJms.setMensaje50(msg.getText());
					mensajeJms = errorJmsDao.add(mensajeJms);

					try {
						// ** Programar RE-Ejecución en diferido ** //
						HashMap<String, String> params = new HashMap<String, String>();
						params.put("id", mensajeJms.getId50().toString());
						this.jobSchedulerService.programarEjecucion(SchedulerJobType.ERROR, params);
					} catch (Exception e2) {
						// Solo para que no haga rollback
						PlateaJMSServiceImpl.logger
								.error("Error programando re-ejecución: " + ExceptionUtils.getStackTrace(e2));
					}
				}
			}

		}

		inMessage.acknowledge();

		PlateaJMSServiceImpl.logger.debug("PlateaJMSServiceImpl.onMessage - Fin " + idMensaje);
	}

	public void retramitarFromJMSError(Long id) throws Throwable {
		PlateaJMSServiceImpl.logger.debug("PlateaJMSServiceImpl - inicio retramitarFromJMSError id:" + id);
		ErrorJms mensajeJms = new ErrorJms();
		mensajeJms.setId50(id);
		mensajeJms = errorJmsDao.find(mensajeJms);
		if (null != mensajeJms) {
			String mensaje = mensajeJms.getMensaje50Str();
			NotificationBody notificationBody = null;
			try {
				MessageParser<NotificationBody> parserTarea = new MessageParser<NotificationBody>(
						NotificationBody.class.getPackage().getName());
				notificationBody = parserTarea.parse(mensaje);
			} catch (Exception e) {
				ManagerErrors.manageException(e);
			}

			Map<String, Object> mapaMensaje = JMSHelper.parsearMensajeJms(mensaje);
			String strQueEvento = "";
			try {
				strQueEvento = (String) mapaMensaje.get("EventWhat");
				// enrutamos segun tipo de evento
				if (Constantes.R02_REQUEST.equals(strQueEvento)) {
					/********* EVENTO SOLICITUD *****************/
					requestJMSService.proccesRequest(notificationBody, mapaMensaje);
				} else if (Constantes.R02_TASK.equals(strQueEvento)) {
					/********* EVENTO TAREAS *****************/
					taskJMSService.tratamientoTask(notificationBody, mapaMensaje);
				} else if (Constantes.LOCATOR_RESULT.equals(strQueEvento)) {
					/********* EVENTO TAREAS *****************/
					this.locatorJMSService.tratamientoLocator(notificationBody, mapaMensaje);
				}
			} catch (Throwable e) {
				ManagerErrors.manageException(e);
			}

			// si ha ido bien, lo borramos de la tabla
			errorJmsDao.remove(mensajeJms);

			PlateaJMSServiceImpl.logger.debug("PlateaJMSServiceImpl - fin retramitarFromJMSError");
		}

	}

	private String getErrorMessage(String error) {
		if (null != error && error.length() > 800) {
			error = error.substring(0, 799);
		}
		return error;
	}

//	@Override
//	public synchronized void tratarMessagePapel0(Message inMessage) throws Throwable {
//		PlateaJMSServiceImpl.logger.debug("PlateaJMSServiceImpl - tratarMessagePapel0");
//
//		// Obtenemos el objeto NotificationBody
//		NotificationBody notificationBody = null;
//		boolean error = false;
//		try {
//			MessageParser<NotificationBody> parserNotification = new MessageParser<NotificationBody>(
//					NotificationBody.class.getPackage().getName());
//			notificationBody = parserNotification.parse(((TextMessage) inMessage).getText());
//
//		} catch (Exception pe) {
//			PlateaJMSServiceImpl.logger
//					.error("Ad74aMDBPapel0ClienteJMS Error al parsear el mensaje de la cola : " + pe.getMessage());
//			error = true;
//		}
//
//		if (!error) {
//
//			Map<String, Object> mapaMensaje = JMSHelper.parsearMensajeJms(((TextMessage) inMessage).getText());
//			try {
//				mapaMensaje.put("jmsid", inMessage.getStringProperty("messageIdPropagado"));
//			} catch (Exception e) {
//				PlateaJMSServiceImpl.logger.error("PlateaJMSServiceImpl.onMessage - Error al recuperar el jmsid");
//			}
//
//			try {
//				MessageParser<InputRegisterType> parserInputRegister = new MessageParser<InputRegisterType>(
//						InputRegisterType.class.getPackage().getName());
//				InputRegisterType input = parserInputRegister.parse(notificationBody.getXmlValue().get(0));
//				input.getDocuments().getDocumentOid();
//				BandejaPapel0 bandejaPapel0 = new BandejaPapel0();
//
//				// Lista de oids
//				bandejaPapel0.setListaOid(input.getDocuments().getDocumentOid());
//
//				String jmsIdID = inMessage.getStringProperty("messageIdPropagado");
//				if (jmsIdID == null) {
//					jmsIdID = " ";
//				}
//				bandejaPapel0.setIdjms12(jmsIdID);
//
//				// QR
//				bandejaPapel0.setQrcode12(input.getQRCode());
//
//				bandejaPapel0.setNumRegistro12(input.getRegistryNumber());
//				SimpleDateFormat formateador = new SimpleDateFormat("yyyyMMddHHmmss");
//				bandejaPapel0.setfRegistro12(formateador.parse(input.getRegistryDate()));
//
//				bandejaPapel0.setNumRegOriginal12(input.getOriginalRegistryNumber());
//				if (input.getOriginalRegistryDate() != null && !"".equals(input.getOriginalRegistryDate())) {
//					bandejaPapel0.setfRegOriginal12(formateador.parse(input.getOriginalRegistryDate()));
//				}
//
//				if (input.getPersons().getPerson() != null && !input.getPersons().getPerson().isEmpty()) {
//					bandejaPapel0.setRemitente12(input.getPersons().getPerson().get(0).getName());
//				}
//
//				// Por ahora ponemos todas las solicitudes como aceptadas
//				bandejaPapel0.setEstado12(EstadosBandejaPapel0.ACEPTADA);
//
//				this.bandejaPapel0Service.tratarPapel0(bandejaPapel0);
//
//			} catch (Throwable e) {
//				PlateaJMSServiceImpl.logger.error("Error al tratar el message: ");
//				// guardamos el mensaje de error
//				ErrorJms mensajeJms = ModelApplicationParser.getMensajeJmsToError(mapaMensaje);
//				if (e instanceof Ad74aException) {
//					Ad74aException ex = (Ad74aException) e;
//					mensajeJms.setErrormsg50(getErrorMessage(ex.getMessage()));
//					mensajeJms.setError50(ex.getCodeError());
//					PlateaJMSServiceImpl.logger.error("Error procesar evento: " + ex.getMessage());
//				} else {
//					mensajeJms.setErrormsg50(getErrorMessage(ExceptionUtils.getStackTrace(e)));
//					PlateaJMSServiceImpl.logger.error("Error procesar evento: " + ExceptionUtils.getStackTrace(e));
//				}
//				mensajeJms.setMensaje50(((TextMessage) inMessage).getText());
//				mensajeJms = errorJmsDao.add(mensajeJms);
//
//				try {
//					// ** Programar RE-Ejecución en diferido ** //
//					HashMap<String, String> params = new HashMap<String, String>();
//					params.put("id", mensajeJms.getId50().toString());
//					this.jobSchedulerService.programarEjecucion(SchedulerJobType.ERROR, params);
//				} catch (Exception e2) {
//					// Solo para que no haga rollback
//					PlateaJMSServiceImpl.logger
//							.error("Error programando re-ejecución: " + ExceptionUtils.getStackTrace(e2));
//				}
//			}
//
//		}
//
//		inMessage.acknowledge();
//
//	}

}
