package com.ejie.ad74a.tareas.service;

import java.util.List;

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.ExpedientesDao;
import com.ejie.ad74a.exceptions.ManagerErrors;
import com.ejie.ad74a.jms.util.ModelApplicationParser;
import com.ejie.ad74a.model.Estados;
import com.ejie.ad74a.model.Expedientes;
import com.ejie.ad74a.service.tramitacion.TramitacionService;
import com.ejie.ad74a.util.constantes.EstadoNotificacionEnum;
import com.ejie.ad74a.util.constantes.EstadosExpedienteEnum;
import com.ejie.ad74a.util.constantes.TareasEnum;
import com.ejie.ad74a.ws.client.platea.model.task.Task;
import com.ejie.ad74a.ws.client.platea.service.PlateaService;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TTask;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TTaskType;

/**
 * Gestión de la Tarea de Acuse de Notificación
 * 
 * @author IBERMATICA
 */

@Service(value = "tareaAcuseNotificacionService")
public class TareaAcuseNotificacionServiceImpl implements TareaAcuseNotificacionService {

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

	@Autowired
	private TramitacionService tramitacionService;

	@Autowired
	private PlateaService plateaService;

	@Autowired
	private ExpedientesDao expedientesDao;

	/**
	 * Método que gestiona el evento de Tarea Sugerida
	 * 
	 */
	public void tareaSugerida(Task task) throws Throwable {
		TareaAcuseNotificacionServiceImpl.logger.info("TareaAcuseNotificacionServiceImpl.tareaSugerida -"
				+ task.getTaskID() + "-" + task.getMailboxTaskID() + "- inicio ");

		String numRegistro = ModelApplicationParser.getNumRegistryFromTask(task);

		Expedientes expediente = new Expedientes();
		expediente.setFolderId00(task.getFolderID());
		List<Expedientes> listaExpedientes = expedientesDao.findAll(expediente, null);

		if (null != listaExpedientes && listaExpedientes.size() > 0) {
			expediente = listaExpedientes.get(0);
		} else {
			ManagerErrors
					.manageError("Error al sugerir la tarea de estudio: no se ha encontrado el expediente FolderId: "
							+ task.getFolderID());
		}

		// ** En función del ID de la tarea se especifica la acción ** //
		switch ((TareasEnum.getEnumByTaskId(task.getTaskID()))) {
		case ACUSENOTIFICACION_SUBSANA:
			expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_SUBSANACION.getId()));
			this.expedientesDao.updateEstado(expediente);
			break;

		default:
			break;
		}

		// almacenamos el tramite y la tarea
		this.tramitacionService.tratamientoTramiteTareaSugerida(task, numRegistro, expediente);

		TareaAcuseNotificacionServiceImpl.logger.info("TareaAcuseNotificacionServiceImpl.tareaSugerida -"
				+ task.getTaskID() + "-" + task.getMailboxTaskID() + "- fin ");
	}

	/**
	 * Método que gestiona el evento de Tarea Ejecutada
	 */
	public void tareaEjecutada(Task task) throws Throwable {
		TareaAcuseNotificacionServiceImpl.logger.info("TareaAcuseNotificacionServiceImpl.tareaEjecutada -"
				+ task.getTaskID() + "-" + task.getMailboxTaskID() + "- inicio ");

		this.tramitacionService.tratamientoTramiteTareaEjecutada(task, true);
		Expedientes expediente = new Expedientes();
		expediente.setFolderId00(task.getFolderID());
		List<Expedientes> listaExpedientes = expedientesDao.findAll(expediente, null);

		if (null != listaExpedientes && listaExpedientes.size() > 0) {
			expediente = listaExpedientes.get(0);
		} else {
			ManagerErrors
					.manageError("Error al sugerir la tarea de estudio: no se ha encontrado el expediente FolderId: "
							+ task.getFolderID());
		}
		Integer estadoNotificacion00 = null;
		if (task.getTaskInfo() != null && task.getTaskInfo().getDeliveredNotificationTaskData() != null
				&& EstadoNotificacionEnum.ID_DELIVERYSTATUS_ACUSADO
						.equalsIgnoreCase(task.getTaskInfo().getDeliveredNotificationTaskData().getDeliveryStatus())) {
			estadoNotificacion00 = EstadoNotificacionEnum.ACUSADO.getId();
		} else if (task.getTaskInfo() != null && task.getTaskInfo().getDeliveredNotificationTaskData() != null
				&& EstadoNotificacionEnum.ID_DELIVERYSTATUS_EXPIRADO
						.equalsIgnoreCase(task.getTaskInfo().getDeliveredNotificationTaskData().getDeliveryStatus())) {
			estadoNotificacion00 = EstadoNotificacionEnum.EXPIRADO.getId();
		}

		expediente.setEstadoNotificacion00(estadoNotificacion00);
		this.expedientesDao.updateEstadoNotificacion(expediente);

		// ** En función del ID de la tarea se especifica la acción ** //
		switch ((TareasEnum.getEnumByTaskId(task.getTaskID()))) {
		case ACUSENOTIFICACION_SUBSANA:
			expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_SUBSANACION.getId()));
			this.expedientesDao.updateEstado(expediente);
			break;
		case ACUSE_NOTI_TRAMITE_AUDIENCIA:
			// ** Actualizar estado del Expediente ** //
			expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_ALEGACIONES.getId()));
			this.expedientesDao.updateEstado(expediente);

			break;
		case ACUSE_NOTI_RESOL_DESIS:

			if (com.ejie.ad74a.util.constantes.Constantes.TiposDesistimiento.TIPO_DESISTIMIENTO_TACITO
					.equalsIgnoreCase(expediente.getTipoDesis00())) {

				// ** Actualizar estado del Expediente ** //
				expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_RECURSO.getId()));
				this.expedientesDao.updateEstado(expediente);

				// sugerir tramite de la apertura del plazo de recurso de desistimiento
				this.tramitacionService.sugerirTarea(task, TareasEnum.APER_PLAZO_RECUR_DESIS);

			} else if (com.ejie.ad74a.util.constantes.Constantes.TiposDesistimiento.TIPO_DESISTIMIENTO_EXPRESO
					.equalsIgnoreCase(expediente.getTipoDesis00())) {

				// ** Actualizar estado del Expediente ** //
				expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_CERRAR.getId()));
				this.expedientesDao.updateEstado(expediente);

				// sugerir tramite de cierre
				this.tramitacionService.sugerirTarea(task, TareasEnum.CIERRE);

			}

			// TODO ctualizamos el estado del expediente
			// expediente.setEstados(new
			// Estados(EstadosExpedienteEnum.PEND_RECURSO_DES.getId()));
			// this.expedientesDao.updateEstado(expediente);

			// Abrimos Plazo de Recurso de Desistimiento ** //
			// this.tramitacionService.sugerirTarea(task,
			// TareasEnum.APER_PLAZO_RECUR_DESIS.getProceedingId(),
			// TareasEnum.APER_PLAZO_RECUR_DESIS.getTaskId());
			break;
		// ** Especificar acciones propias en función del tipo de tarea ** //
		// *****************************************************
		case ACUSE_NOTI_RESOL_CONCESION:
		case ACUSE_NOTI_RESOL_DENEGACION:
		case ACUSE_DENEGACION_SERVICIO_AUDIENCIA:
		case ACUSE_NOTI_LIQUIDACION:

			// ** Actualizar estado del Expediente ** //
			expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_CERRAR.getId()));
			this.expedientesDao.updateEstado(expediente);

			// sugerir tramite de cierre
			this.tramitacionService.sugerirTarea(task, TareasEnum.CIERRE);

			break;
		default:
			break;
		}

		TareaAcuseNotificacionServiceImpl.logger.info("TareaAcuseNotificacionServiceImpl.tareaEjecutada -"
				+ task.getTaskID() + "-" + task.getMailboxTaskID() + "- fin ");

	}

	/**
	 * Preparación de la tarea
	 */
	public TTask prepararTarea(String taskGUID) throws Throwable {
		return plateaService.prepareTask(taskGUID, TTaskType.NOTIFICACION_ACUSAR);
	}

	/**
	 * Ejecución de la tarea
	 */
	public TTask ejecutarTarea(TTask task) throws Throwable {
		return plateaService.doTask(TareasEnum.getTaskType(task.getTaskID()), task);
	}

	/**
	 * Ejecución de la tarea de forma automática
	 */
	public void ejecutarTareaAutomatica(String taskGUID) throws Throwable {

	}

}
