package com.ejie.ab04b.control;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;

import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ejie.ab04b.constantes.Constantes;
import com.ejie.ab04b.constantes.TipoTareaFlujo;
import com.ejie.ab04b.constantes.TipoTareaPlatea;
import com.ejie.ab04b.constantes.TipoTramiteFlujo;
import com.ejie.ab04b.exception.AB04BException;
import com.ejie.ab04b.exception.AB04BParseException;
import com.ejie.ab04b.model.ComunicacionApertura;
import com.ejie.ab04b.model.DatosAviso;
import com.ejie.ab04b.model.DocumentoAperturas;
import com.ejie.ab04b.model.Folder;
import com.ejie.ab04b.model.pps.PPSReturnInfo;
import com.ejie.ab04b.service.ComunicacionAperturaService;
import com.ejie.ab04b.service.DatosAvisoService;
import com.ejie.ab04b.service.DatosNotificacionService;
import com.ejie.ab04b.service.FolderService;
import com.ejie.ab04b.service.pif.PifService;
import com.ejie.ab04b.service.platea.PPSAperturasService;
import com.ejie.ab04b.service.platea.PlateaTramitacionService;
import com.ejie.ab04b.service.platea.ReeService;
import com.ejie.ab04b.service.svt.SvtService;
import com.ejie.ab04b.util.PPSUtils;
import com.ejie.ab04b.util.Utilities;
import com.ejie.ab04b.util.seguridad.UtilSeguridad;
import com.ejie.ab04b.webservice.ToolkitWebService;
import com.ejie.ct.xml.Expedient;
import com.ejie.ct.xml.InfExpte;
import com.ejie.ctfm.xml.ContextSubmission;
import com.ejie.foldermanagement.xml.RequestReturn;
import com.ejie.mbt.xml.Task;

/**
 * ExpedientesController generated by UDA, 16-mar-2016 12:15:55.
 * 
 * @author UDA
 */

@Controller()
@RequestMapping(value = "/prueba")
public class PruebaController {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(PruebaController.class);

	@Autowired()
	private PlateaTramitacionService plateaTramitacionService;
	@Autowired()
	private ReeService reeService;
	@Autowired()
	private PPSAperturasService ppsAperturasService;
	@Autowired()
	private ComunicacionAperturaService comunicacionAperturaService;
	@Autowired()
	private DatosNotificacionService datosNotificacionService;
	@Autowired()
	private DatosAvisoService datosAvisoService;
	@Autowired()
	private FolderService folderService;
	// @Autowired()
	// private DocumentoAperturasService documentoAperturasService;
	// @Autowired()
	// private DatosNotificacionService datosNotificacionService;
	// @Autowired()
	// private GatService gatService;
	@Autowired()
	private SvtService svtService;

	private PifService pifService;

	// @Autowired()
	// private ToolkitService toolkitService;
	// private T65BFSDWSClasePort t65bFSDWSClasePort;

	/**
	 * Usamos este mÃ©todo para indicarle a Spring el formato que debe usar para
	 * serializar las fechas cuando cargamos la entidad en el Model. En el resto
	 * de peticiones que devuelven un objeto con la anotaciÃ³n '@ResponseBody'
	 * se usan los serializadores de UDA
	 * 
	 * binder WebDataBinder
	 *
	 * @param binder
	 *            the binder
	 */
	@InitBinder()
	public void initBinder(WebDataBinder binder) {

		Locale locale = LocaleContextHolder.getLocale();
		DateFormat dateFormat = null;
		if (locale.equals(Constantes.LOCALE_ES)) {
			dateFormat = new SimpleDateFormat(Constantes.ES_DATE_MASK);
		} else {
			dateFormat = new SimpleDateFormat(Constantes.EU_DATE_MASK);
		}
		binder.registerCustomEditor(Date.class,
				new CustomDateEditor(dateFormat, true));
	}

	/*
	 * OPERACIONES CRUD (Create, Read, Update, Delete)
	 */

	/**
	 * Inicia el controller.
	 * 
	 * view name
	 *
	 * @return the string
	 */
	@RequestMapping(value = "/init")
	public String initPruebaController() {

		PruebaController.LOGGER.info("PruebaController iniciado correctamente");

		return "prueba";
	}

	/**
	 * Llama al servicio web.
	 * 
	 * String
	 *
	 * @return the string
	 */
	@RequestMapping(value = "/wscall", method = RequestMethod.POST)
	public @ResponseBody() String callToolkitWs() {

		PruebaController.LOGGER.info("Test callToolkitWs");

		ToolkitWebService wsTester = new ToolkitWebService();

		String result = wsTester.obtenerListaModalidadOrganizacionPreventiva();

		PruebaController.LOGGER.info("Resultado: {}", result);

		return "";
	}

	/**
	 * Llama al servicio web.
	 * 
	 * folderId String
	 *
	 * @param folderId
	 *            the folder id String
	 * @return the folder proceedings
	 */
	@RequestMapping(value = "/getFolderProceedings", method = RequestMethod.POST)
	public @ResponseBody() String getFolderProceedings(
			@RequestParam(value = "folderId") String folderId) {

		PruebaController.LOGGER.info("Test getFolderProceedings");

		Expedient expediente = this.reeService
				.obtenerHistorialExpediente(folderId);

		PruebaController.LOGGER.info("Resultado correcto, {} tramites",
				expediente.getProceeding().size());

		return "";
	}

	/**
	 * Llama al servicio web.
	 * 
	 * taskId String
	 *
	 * @param taskId
	 *            the task id String
	 * @return the string
	 */
	@RequestMapping(value = "/prepareTask", method = RequestMethod.POST)
	public @ResponseBody() String prepareTask(
			@RequestParam(value = "taskId") String taskId) {

		PruebaController.LOGGER.info("Test prepareTask");

		Task tarea = this.plateaTramitacionService.prepararTarea(taskId,
				TipoTareaPlatea.APERTURA);

		PruebaController.LOGGER.info(
				"Resultado prepareTask, getMailboxTaskID {}",
				tarea.getMailboxTaskID());

		// this.plateaTramitacionService.estudiarDocumentacion(tarea);
		tarea = this.plateaTramitacionService.aperturaExpediente(tarea);

		return "";
	}

	/**
	 * Llama al servicio web.
	 * 
	 * String
	 *
	 * @return the string
	 */
	@RequestMapping(value = "/createTask", method = RequestMethod.POST)
	public @ResponseBody() String createTask() {

		PruebaController.LOGGER.info("Test createTask");

		InfExpte expediente = this.reeService.obtenerInformacionExpediente(
				"R02T94991FFD955B9278B2764F6BCA2C1ABB50A98F43");
		if (expediente != null) {
			expediente.toString();
			Expedient hExpediente = this.reeService.obtenerHistorialExpediente(
					"R02T94991FFD955B9278B2764F6BCA2C1ABB50A98F43");
			if (hExpediente != null) {
				hExpediente.toString();
			}
		}

		// this.plateaTramitacionService.crearTarea(
		// Utilities.getInstance().obtenerProcedureIdApertura(),
		// "CAMBIAR_COORDINADOR",
		// "adjuntar_comunic_cambio_coordinador_contratista",
		// "R02T15509F66647482A9A00104B70F7C46850E138E8A", "AB04B-01",
		// "AB04BDM");

		// this.gatService.obtenerTareas(
		// "R02T43EC9A355776BA3D50E7E52FA14C02819C2A7A46", "estudio",
		// true);

		File file = new File("C:\\prueba.pdf");
		try {
			InputStream is = new FileInputStream(file);
			String ruta = this.pifService.uploadDocument(is,
					"/t65e/ab04b/prueba.pdf", true);
			PruebaController.LOGGER.info("Ruta PIF", ruta);
		} catch (Exception e) {
			PruebaController.LOGGER.error("Error al subir a PIF", e);
		}

		return "";
	}

	/**
	 * Cambiarcoordinador.
	 * 
	 * the string
	 *
	 * @return the string
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	@RequestMapping(value = "/cambiarcoordinador", method = RequestMethod.POST)
	public @ResponseBody() String cambiarcoordinador() throws AB04BException {
		try {
			PruebaController.LOGGER.info("Test cambiarcoordinador");

			this.plateaTramitacionService.crearTarea(
					Utilities.getInstance().obtenerProcedureIdApertura(),
					TipoTramiteFlujo.CAMBIAR_COORDINADOR.name(),
					TipoTareaFlujo.ADJUNTAR_CARTA_CAMBIO_COORDINADOR_CONTRATISTA
							.getTaskId(),
					"R02T404C40602ED2CB8593CA8465CCB31893B917A22E",
					UtilSeguridad.getInstance().getNif(),
					UtilSeguridad.getInstance().getNombre());

			/*
			 * Ejecutar el paso de comunicación
			 * 
			 * this.plateaTramitacionService.crearTarea(
			 * Utilities.getInstance().obtenerProcedureIdApertura(),
			 * TipoTramiteFlujo.CAMBIAR_COORDINADOR.name(),
			 * TipoTareaFlujo.ENVAIR_COMUNICACION_CAMBIOCOORDINADOR_CONTRATISTA
			 * .getTaskId(), "R02T4283CCCBD09D51489F5A5E861C6A4657A416E3FF",
			 * UtilSeguridad.getInstance().getNif(),
			 * UtilSeguridad.getInstance().getNombre());
			 */

			return "";
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * Llama al servicio web.
	 * 
	 * String
	 *
	 * @return the string
	 * @throws AB04BException
	 *             the AB 04 B exception
	 * @throws FileNotFoundException
	 *             the file not found exception
	 */
	@RequestMapping(value = "/subirpdf", method = RequestMethod.POST)
	public @ResponseBody() String subirpdf()
			throws AB04BException, FileNotFoundException {

		PruebaController.LOGGER.info("Test subirpdf");

		// Lo subimos a PIF
		InputStream is = new FileInputStream("C:\\prueba.pdf");
		String rutaDokusi = "/t65e/ab04b/prueba.pdf";
		String rutaDoc = this.pifService.uploadDocument(is, rutaDokusi, true);

		PruebaController.LOGGER.info("rutaDoc " + rutaDoc);
		PruebaController.LOGGER.info("rutaDokusi " + rutaDokusi);

		return "";
	}

	/**
	 * Llama al servicio web.
	 * 
	 * taskId String
	 *
	 * @param taskId
	 *            the task id String
	 * @return the string
	 * @throws AB04BParseException
	 *             the AB 04 B parse exception
	 */
	@RequestMapping(value = "/studyTask", method = RequestMethod.POST)
	public @ResponseBody() String studyTask(
			@RequestParam(value = "taskId") String taskId)
			throws AB04BParseException {

		PruebaController.LOGGER.info("Test studyTask");

		// Task tarea = this.plateaTramitacionService.prepararTarea(taskId,
		// TipoTareaPlatea.ESTDOCU);
		//
		// StudyTaskData studyTaskData = tarea.getTaskInfo().getStudyTaskData();
		// studyTaskData.setResptarea(
		// new ObjectFactory().createStudyTaskDataResptarea("AB04B-01"));
		// studyTaskData.getSituaciones().getValue().add("OK");
		// studyTaskData.getSituaciones().getValue().add("KO");
		// studyTaskData.setSituacionID("OK");
		// studyTaskData
		// .setAccion(ConstantesPlateaTramitacion.ESTDOC_ACCION_GRABAR);
		//
		// PruebaController.LOGGER.info(
		// "Resultado prepareTask, getMailboxTaskID {}",
		// tarea.getMailboxTaskID());
		//
		// tarea = this.plateaTramitacionService.estudiarDocumentacion(tarea);

		// PRUEBA GUARDAR DATOS PRECARGA TOOLKIT
		// Documento documento = new Documento();
		// documento.setApplicantInfo(new ApplicantInfoType());
		// documento.setSender(new SenderType());
		// documento.setDetailInfo(
		// "<![CDATA[<campoRazonSocial>valor razon
		// social</campoRazonSocial>]]>");
		// String idPreSolicitud =
		// this.toolkitService.guardarDatosPrecargaToolkit(
		// Utilities.getInstance().obtenerProcedureIdApertura(),
		// documento);
		// PruebaController.LOGGER.info("Id pre solicitud {}", idPreSolicitud);

		// PRUEBA CREAR CONTEXT SUBMISSION PPS
		ComunicacionApertura apertura = new ComunicacionApertura("01", "2017",
				Long.parseLong(taskId));

		apertura = this.comunicacionAperturaService.findConObra(apertura);
		apertura.setDatosNotificacion(this.datosNotificacionService
				.find(apertura.getDatosNotificacion()));
		DatosAviso filterDatosAviso = new DatosAviso();
		filterDatosAviso.setDatosNotificacion(apertura.getDatosNotificacion());
		apertura.getDatosNotificacion().setListaDatosAviso(
				this.datosAvisoService.findAll(filterDatosAviso, null));

		Folder folder = new Folder("2", "01", "2017", Integer.parseInt(taskId));

		folder = this.folderService.findByPk(folder);

		List<DocumentoAperturas> listaDocumentos = new ArrayList<DocumentoAperturas>();
		// listaDocumentos.add(this.documentoAperturasService
		// .find(new DocumentoAperturas(146L)));
		ContextSubmission contextSubmission = this.ppsAperturasService
				.crearContextSubmission(apertura, listaDocumentos);

		RequestReturn requestReturn = this.ppsAperturasService
				.enviarSolicitudPresencial(contextSubmission);
		PPSReturnInfo ppsReturnInfo = PPSUtils.getInstance()
				.obtenerPPSReturnInfo(requestReturn);
		PruebaController.LOGGER.info("NUM REGISTRO {}",
				ppsReturnInfo.getNumRegistro());

		folder.setFolderid077(ppsReturnInfo.getFolderId());
		this.folderService.updateFolderId(folder);

		apertura.setFolderId056(ppsReturnInfo.getFolderId());
		this.comunicacionAperturaService.updateFilled(apertura);

		return "";
	}

	/**
	 * Enviar mensaje tarea.
	 * 
	 * task String
	 *
	 * @param task
	 *            the task String
	 * @return the string
	 */
	@RequestMapping(value = "enviarMensajeTarea")
	public String enviarMensajeTarea(
			@RequestParam(value = "taskArea") String task) {
		PruebaController.LOGGER.info("Entra en enviarMensajeTarea");
		try {
			if (Utilities.getInstance().isEmpty(task)) {
				InputStream is = PruebaController.class
						.getResourceAsStream("/message_task.xml");
				if (is != null) {
					String message = IOUtils.toString(is);
					this.encolarEnAvisos(message);
				} else {
					PruebaController.LOGGER.error("El IS es null");
				}
			} else {
				this.encolarEnAvisos(task);
			}
		} catch (Exception e) {
			PruebaController.LOGGER.error(
					"Error al enviar mensaje a la cola de avisos R02_TASK", e);
		}
		return "prueba";
	}

	/**
	 * Encolar en avisos.
	 * 
	 * mensaje String
	 *
	 * @param mensaje
	 *            the mensaje
	 */
	private void encolarEnAvisos(String mensaje) {
		QueueConnectionFactory qconFactory;
		QueueConnection qcon;
		QueueSession qsession;
		QueueSender qsender;
		Queue queue;
		TextMessage msg;

		try {
			Hashtable<String, String> env = new Hashtable<String, String>();
			env.put(Context.INITIAL_CONTEXT_FACTORY,
					"weblogic.jndi.WLInitialContextFactory");
			env.put(Context.PROVIDER_URL, "t3://wl11vf0132.ejiedes.net:7002");
			Context ctx = new InitialContext(env);

			qconFactory = (QueueConnectionFactory) ctx
					.lookup("ab04b.ab04bConnectionFactory");
			qcon = qconFactory.createQueueConnection();
			qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
			queue = (Queue) ctx.lookup("ab04b.ab04bAvisosQueue");
			qsender = qsession.createSender(queue);
			msg = qsession.createTextMessage();
			qcon.start();

			PruebaController.LOGGER.info("Mensaje a enviar: {}", mensaje);
			msg.setText(mensaje);

			qsender.send(msg);
		} catch (Exception e) {
			PruebaController.LOGGER.error("Error al configurar cola", e);
		}
	}

	/**
	 * Enviar mensaje dokusi transformacion.
	 * 
	 * oid String
	 *
	 * @param oid
	 *            the oid String
	 * @return the string
	 */
	@RequestMapping(value = "encolarDokusiAvisosTransfor")
	public String enviarMensajeDokusiTransformacion(
			@RequestParam(value = "oidTransformation") String oid) {
		PruebaController.LOGGER
				.info("Entra en enviarMensajeDokusiTransformacion");
		try {
			InputStream is = PruebaController.class
					.getResourceAsStream("/message_dokusi_transfor.xml");
			if (is != null) {
				String message = IOUtils.toString(is);
				message = message.replaceAll("##OID##", oid);
				this.encolarEnAvisos(message);
			} else {
				PruebaController.LOGGER.error("El IS es null");
			}
		} catch (Exception e) {
			PruebaController.LOGGER.error(
					"Error al enviar mensaje a la cola de avisos por parte de Dokusi",
					e);
		}
		return "prueba";
	}

	/**
	 * Process.
	 * 
	 * mailboxTaskId String taskType String
	 *
	 * @param mailboxTaskId
	 *            the mailbox task id
	 * @param taskType
	 *            the task type String
	 * @return the string
	 * @throws Exception
	 */
	@RequestMapping(value = "process")
	public @ResponseBody() String process(
			@RequestParam(value = "mailboxTaskId") String mailboxTaskId,
			@RequestParam(value = "taskType") String taskType)
			throws Exception {

		this.svtService.process(mailboxTaskId, taskType);
		return "";
	}

}
