package com.ejie.ab04b.service.svt;

import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ejie.ab04b.constantes.Constantes;
import com.ejie.ab04b.constantes.TipoTareaFlujo;
import com.ejie.ab04b.constantes.TipoTareaPlatea;
import com.ejie.ab04b.dao.custom.TareaTramiteAperturasCustomDao;
import com.ejie.ab04b.evento.ManejadorTareas;
import com.ejie.ab04b.evento.ManejadorTareasAperturas;
import com.ejie.ab04b.evento.ManejadorTareasOS2;
import com.ejie.ab04b.evento.ManejadorTareasOS3;
import com.ejie.ab04b.exception.AB04BException;
import com.ejie.ab04b.model.Buzon;
import com.ejie.ab04b.model.ComunicacionApertura;
import com.ejie.ab04b.model.Tarea;
import com.ejie.ab04b.model.TareaAperturas;
import com.ejie.ab04b.model.TareaErronea;
import com.ejie.ab04b.model.TramiteAperturas;
import com.ejie.ab04b.service.BuzonService;
import com.ejie.ab04b.service.ComunicacionAperturaService;
import com.ejie.ab04b.service.TareaErroneaService;
import com.ejie.ab04b.service.platea.PlateaTramitacionService;
import com.ejie.ab04b.util.Utilities;
import com.ejie.mbt.xml.Task;

/**
 * @author GFI-NORTE
 *
 */
/**
 * @author GFI-NORTE
 * 
 */
@Service(value = "svtService")
public class SvtService {

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

	@Autowired()
	private ComunicacionAperturaService comunicacionAperturaService;
	@Autowired()
	private BuzonService buzonService;

	@Autowired()
	private PlateaTramitacionService plateaTramitacionService;
	@Autowired()
	private ManejadorTareasAperturas manejadorTareaAperturas;
	@Autowired()
	private ManejadorTareasOS2 manejadorTareaOS2;
	@Autowired()
	private ManejadorTareasOS3 manejadorTareaOS3;

	@Autowired()
	private TareaTramiteAperturasCustomDao tareaTramiteAperturasCustomDao;
	@Autowired()
	private TareaErroneaService tareaErroneaService;

	/**
	 * folderId String procedureId String String.
	 *
	 * @param folderId
	 *            the folder id
	 * @param procedureId
	 *            the procedure id
	 * @return the string
	 */
	public String obtenerMailboxInstructor(String folderId,
			String procedureId) {

		ManejadorTareas manejadorTareas = this
				.obtenerManejadorTareas(procedureId);
		String codTerritorio = manejadorTareas
				.getTerritorioExpedienteByFolderId(folderId);

		Buzon buzon = this.buzonService.obtenerBuzon(procedureId,
				codTerritorio);

		return buzon.getMailbox076();
	}

	/**
	 * folderId String procedureId String String.
	 *
	 * @param folderId
	 *            the folder id
	 * @param procedureId
	 *            the procedure id
	 * @return the string
	 */
	public String obtenerMailboxOsalan(String folderId, String procedureId) {

		ManejadorTareas manejadorTareas = this
				.obtenerManejadorTareas(procedureId);
		String codTerritorio = manejadorTareas
				.getTerritorioExpedienteByFolderId(folderId);

		Buzon buzon = this.buzonService.obtenerBuzonOsalan(codTerritorio);

		return buzon.getMailbox076();
	}

	/**
	 * folderId String procedureId String String.
	 *
	 * @param folderId
	 *            the folder id
	 * @param procedureId
	 *            the procedure id
	 * @return the string
	 * @throws Exception
	 */
	public String obtenerFolderNumber(String folderId, String procedureId)
			throws Exception {

		SvtService.LOGGER.info("obtenerFolderNumber entramos");

		ManejadorTareas manejadorTareas = this
				.obtenerManejadorTareas(procedureId);

		String numexp = null;

		try {

			int contador = 0;

			// intentamos 3 veces recuperar la solicitud por si no le ha dado
			// tiempo a guardar

			while (contador < 3 && numexp == null) {

				contador++;
				SvtService.LOGGER.info("obtenerFolderNumber select");
				numexp = manejadorTareas
						.obtenerFolderNumberByFolderId(folderId);
				SvtService.LOGGER
						.info("obtenerFolderNumber select valor=" + numexp);
				if (numexp == null) {

					TimeUnit.SECONDS.sleep(2);
					SvtService.LOGGER.info("reintentamos");
				}

			}

			if (contador == 3) {

				throw new AB04BException(
						"No existe solicitud con folderID: " + folderId);

			}
		} catch (Exception e) {
			SvtService.LOGGER.error("obtenerFolderNumber error", e);
			throw new AB04BException("Error: " + e.getMessage());
		}

		return numexp;
	}

	/**
	 * folderId String procedureId String String.
	 *
	 * @param folderId
	 *            the folder id
	 * @param procedureId
	 *            the procedure id
	 * @return the string
	 */
	public String expedienteTieneDocumentacionCorrecta(String folderId,
			String procedureId) {

		ManejadorTareas manejadorTareas = this
				.obtenerManejadorTareas(procedureId);
		String doc_correcto = manejadorTareas
				.getDocCorrExpedienteByFolderId(folderId);

		SvtService.LOGGER.info(
				"Devolvemos documentacion correcta {} para el expediente {}",
				doc_correcto, folderId);

		return doc_correcto;
	}

	/**
	 * mailboxTaskId String taskType String.
	 *
	 * @param mailboxTaskId
	 *            the mailbox task id
	 * @param taskType
	 *            the task type
	 * @throws Exception
	 */
	public void process(String mailboxTaskId, String taskType)
			throws Exception {

		try {
			// Antes de nada preparamos la tarea, para así saber a qué
			// procedimiento
			// corresponde
			Task task = this.plateaTramitacionService.prepararTarea(
					mailboxTaskId, TipoTareaPlatea.valueOf(taskType));

			ManejadorTareas manejadorTareas = this
					.obtenerManejadorTareas(task.getProcedureID());

			if (TipoTareaPlatea.NOTIFICACION.name().equals(taskType)
					|| TipoTareaPlatea.COMUNICACION.name().equals(taskType)) {
				manejadorTareas.processEnviarNotificacion(task);
			} else if (TipoTareaPlatea.REGISTRANOTI.name().equals(taskType)) {
				manejadorTareas.processRegistrarComunicacionPostal(task);
			}
		} catch (Exception e) {

			TareaErronea tarea = new TareaErronea(mailboxTaskId, taskType);
			tareaErroneaService.add(tarea);

			throw e;
		}

	}

	/**
	 * folderId String String.
	 *
	 * @param folderId
	 *            the folder id
	 * @return the string
	 */
	public String esAperturaObra(String folderId) {

		ComunicacionApertura apertura = this.comunicacionAperturaService
				.findByFolderId(folderId);

		return apertura.getIndobra056();
	}

	/**
	 * folderId String String.
	 *
	 * @param folderId
	 *            the folder id
	 * @return the string
	 */
	public String hayQueComunicarOS2(String folderId) {

		ComunicacionApertura apertura = this.comunicacionAperturaService
				.findByFolderId(folderId);

		// Apertura de tipo Centro (indobra056 = 'N')
		// Apertura de nueva creación (tipape056 -> tipape071 = '1')
		// Número total de trabajadores (trbtot056) > 50
		if (apertura != null
				&& Constantes.VALUE_NO.equals(apertura.getIndobra056())
				&& Constantes.APERTURA_SUBTIPO_NUEVA_CREACION
						.equals(apertura.getTipoApertura().getTipape071())
				&& apertura
						.getTrbtot056() > Constantes.UMBRAL_NUMERO_TRABAJADORES_CENTRO) {

			TareaAperturas tareaAperturas = new TareaAperturas();
			Tarea tarea = new Tarea();
			tarea.setTaskId090(
					TipoTareaFlujo.ENVIAR_COMUNICACION_OS2.getTaskId());
			tareaAperturas.setTipoTarea(tarea);
			TramiteAperturas tramite = new TramiteAperturas();
			tramite.setApertura(apertura);
			tareaAperturas.setTramiteAperturas(tramite);

			if (tareaTramiteAperturasCustomDao
					.vfindTareaEnElMismoAno(tareaAperturas) != null) {
				return Constantes.VALUE_NO;
			} else {
				return Constantes.VALUE_SI;
			}

		}

		return Constantes.VALUE_NO;
	}

	/**
	 * folderId String String.
	 *
	 * @param folderId
	 *            the folder id
	 * @return the string
	 */
	public String hayQueComunicarOS3(String folderId) {

		ComunicacionApertura apertura = this.comunicacionAperturaService
				.findByFolderId(folderId);

		// Apertura de tipo Centro (indobra056 = 'N')
		// Apertura de nueva creación (tipape056 -> tipape071 = '1')
		// Número total de trabajadores (trbtot056) <= 50
		if (apertura != null
				&& Constantes.VALUE_NO.equals(apertura.getIndobra056())
				&& Constantes.APERTURA_SUBTIPO_NUEVA_CREACION
						.equals(apertura.getTipoApertura().getTipape071())
				&& apertura
						.getTrbtot056() <= Constantes.UMBRAL_NUMERO_TRABAJADORES_CENTRO) {
			TareaAperturas tareaAperturas = new TareaAperturas();
			Tarea tarea = new Tarea();
			tarea.setTaskId090(
					TipoTareaFlujo.ENVIAR_COMUNICACION_OS2_OS3.getTaskId());
			tareaAperturas.setTipoTarea(tarea);
			TramiteAperturas tramite = new TramiteAperturas();
			tramite.setApertura(apertura);
			tareaAperturas.setTramiteAperturas(tramite);

			if (tareaTramiteAperturasCustomDao
					.vfindTareaEnElMismoAno(tareaAperturas) != null) {
				return Constantes.VALUE_NO;
			} else {
				return Constantes.VALUE_SI;
			}

		}

		return Constantes.VALUE_NO;
	}

	/**
	 * procedureId String ManejadorTareas.
	 *
	 * @param procedureId
	 *            the procedure id
	 * @return the manejador tareas
	 */
	private ManejadorTareas obtenerManejadorTareas(String procedureId) {

		SvtService.LOGGER
				.info("Devolvemos el manejador de tareas dependiendo de: "
						+ procedureId);

		if (Utilities.getInstance().obtenerProcedureIdApertura()
				.equals(procedureId)) {
			return this.manejadorTareaAperturas;
		} else if (Utilities.getInstance().obtenerProcedureIdOs2()
				.equals(procedureId)) {
			return this.manejadorTareaOS2;
		} else if (Utilities.getInstance().obtenerProcedureIdOs3()
				.equals(procedureId)) {
			return this.manejadorTareaOS3;
		}
		return null;
	}

}
