/**
 * 
 */
package com.ejie.ad74a.process;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.ejie.ad74a.exception.BatchProcessException;
import com.ejie.ad74a.model.NotifPostales;
import com.ejie.ad74a.model.Procesos;
import com.ejie.ad74a.service.NotifPostalesService;
import com.ejie.ad74a.service.ProcesosService;
import com.ejie.ad74a.util.UtilDates;
import com.ejie.ad74a.util.constantes.ConstantesBatch;
import com.ejie.ad74a.util.constantes.EstadosProcesosBatchEnum;
import com.ejie.ad74a.util.constantes.ProcesosBatchEnum;
import com.ejie.ad74a.util.constantes.TipoNotificacionComunicacionEnum;
import com.ejie.x38.dto.TableRequestDto;

/**
 * Proceso encargado de refrescar la situación de todos los envios de
 * notificaciones postales.
 * 
 * @author JBHG
 *
 */
@Component(value = "refrescoSituacionesEnvio")
public class RefrescoSituacionesEnvioProcess implements IProcess {

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

	private static final Long BATCH_SIZE = 10L;

	@Autowired
	private ProcesosService procesosService;

	@Autowired
	private NotifPostalesService notifPostalesService;

	/**
	 * Ejecuta el proceso de refresco de situaciones
	 */
	@Override
	public void execute(String... args) throws BatchProcessException {
		/*
		 * [jbhg] Se comenta toda la parte del registro del proceso en BBDD hasta que se
		 * adapte la tabla de PROCESOS para que admita códigos de tipos de procesos de
		 * dos cifras
		 */
//		Procesos proceso = new Procesos();
//		Throwable t = null;// Excepcion que puede dar el proceso batch
		try {
			if (logger.isDebugEnabled()) {
				logger.debug("Params: {}", Arrays.asList(args).stream().map(i -> i).collect(Collectors.joining(", ")));
			}
			// Crea el registro de proceso
//			proceso = createProcessDB();

			/*-
			 * EJECUTAR LOGICA DEL PROCESO
			 * Batch de {@ BATCH_SIZE} elementos
			 */
			TableRequestDto tableRequestDto;
			List<NotifPostales> notifPostalesList;
			NotifPostales filter = new NotifPostales();
			// Recupera notificaciones no finalizadas (y que tengan guardado un idEnvio)
			filter.setTipoNot88(TipoNotificacionComunicacionEnum.NOTIFICACION.getValor());
			filter.setFinalizada88(ConstantesBatch.VAL_NUM_NO);
			filter.setConIdEnvioInformado(true);
			Long page = 1L;// Primera página
			do {
				// Prepara query para recuperar batch de notificaciones
				tableRequestDto = new TableRequestDto(BATCH_SIZE, page++, "IDNOTIFPOSTAL88", "ASC");
				notifPostalesList = this.notifPostalesService.findAllLike(filter, tableRequestDto, null);
				if (CollectionUtils.isNotEmpty(notifPostalesList)) {
					// Consulta sus datos en aa66
					// Actualiza en bbdd el resultado
					this.notifPostalesService.updateMultipleSituacionEnvio(notifPostalesList);
				}
				/*
				 * Repetir si el numero de registros recogidos es del tamaño del batch (eso
				 * quiere decir que probablemente haya otra página más que recuperar).
				 */
			} while (CollectionUtils.size(notifPostalesList) == BATCH_SIZE.intValue());

		} catch (Exception e) {
//			t = e;
			throw new BatchProcessException(e);
		} finally {
			// Finalizar el registro de proceso
//			closeProcessDB(proceso, t);
		}

	}

	/*
	 * Crea el registro del proceso actual en la tabla de bbdd
	 */
	@SuppressWarnings("unused")
	private Procesos createProcessDB() {
		Procesos proceso;
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(UtilDates.getFechaSistema());
		// Creamos un proceso nuevo
		// 1- Insertar el nuevo proceso en la tabla AD74A98T00
		proceso = new Procesos();
		proceso.setEstado98(EstadosProcesosBatchEnum.PENDIENTE.getId());
		proceso.setUsuAlta98("AD74A");
		proceso.setTipoProceso98(ProcesosBatchEnum.REFRESCO_SITUACIONES_ENVIO.getId());
		proceso.setProceso98(
				"refSitEnv_" + calendar.get(Calendar.YEAR) + String.format("%02d", (calendar.get(Calendar.MONTH) + 1))
						+ String.format("%02d", calendar.get(Calendar.DAY_OF_MONTH)));
		proceso.setFInicio98(new Date());
		proceso = this.procesosService.add(proceso);
		return proceso;
	}

	/*
	 * Cierra el registro de proceso con el resultado obtenido (OK en caso de no
	 * haber excepcion, ERROR en otro caso)
	 */
	@SuppressWarnings("unused")
	private void closeProcessDB(Procesos proceso, Throwable e) {
		if (proceso.getIdProceso98() != null) {
			if (e != null) {// Acabado con error
				proceso.setEstado98(EstadosProcesosBatchEnum.ERROR.getId());
				proceso.setError98(e.getMessage().substring(0, Math.min(e.getMessage().length(), 799))); // M�ximo 800
				this.procesosService.actualizarAError(proceso);
			} else {
				this.procesosService.actualizarAFinalizado(proceso);
			}
		}
	}
}
