package com.dla.dda.utils;

import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dla.dda.domain.constants.ErrorCodes;
import com.dla.dda.domain.exceptions.utils.ErrorUtils;
import com.dla.dda.domain.model.response.AmortizacionResponse;
import com.dla.dda.domain.model.response.PresupuestoResponse;
import com.dla.dda.persistence.model.DdaTAmortizable;
import com.dla.dda.persistence.model.DdaTContrato;
import com.dla.dda.utils.date.DateUtils;
import com.dla.dda.utils.validator.CollectionsValidator;

public class ErrorHandler {

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

	/**
	 * @see Agrega errores al listado de la collection
	 * @param response
	 * @param error
	 */
	public static void addError(PresupuestoResponse response, ErrorCodes error) {

		List<ErrorCodes> errors = CollectionsValidator.safeList(response.getError());
		errors.add(error);
		response.setError(errors);

	}

	public static void addError(PresupuestoResponse response, ErrorCodes error, String message) {

		ErrorUtils.setMessage(error, message);
		List<ErrorCodes> errors = CollectionsValidator.safeList(response.getError());
		errors.add(error);
		response.setError(errors);

	}

	/**
	 * @see Metodo que evalua si se cuenta con un monto para la amortizacion
	 * @param response
	 * @param data
	 * @param message
	 */
	public static void validate(PresupuestoResponse response, DdaTAmortizable data, String message) {

		if (data == null || data.getMonto() == null || data.getMonto().isEmpty()) {

			ErrorCodes error = ErrorCodes.DATA_NOT_EXIST;

			ErrorUtils.setMessage(error, message);

			List<ErrorCodes> errors = CollectionsValidator.safeList(response.getError());
			errors.add(error);
			response.setError(errors);

			logger.error("Error [{}] [{}] [{}]", error, error.getCode(), error.getDetail());

		}

	}

	public static void validate(PresupuestoResponse response, DdaTContrato data, String message) {

		if (data == null || data.getDdaTApartado() == null || data.getDdaTApartado().getIdApartado() == null) {

			ErrorCodes error = ErrorCodes.DATA_NOT_EXIST;

			ErrorUtils.setMessage(error, message);

			List<ErrorCodes> errors = CollectionsValidator.safeList(response.getError());

			errors.add(error);

			response.setError(errors);

			logger.error("Error [{}] [{}]", error.getCode(), error.getDetail());

		}

	}

	public static void validate(PresupuestoResponse response, String messageOk, String messageError) {

		Double estudioTotal = response.getContratoEstudio() + response.getValorContrato();

		logger.info(" estudioTotal [{}] = contratoEstudio [{}] + valorContrato [{}]", estudioTotal,
				response.getContratoEstudio(), response.getValorContrato());

		ErrorCodes code = ErrorCodes.UNKNOW_ERROR;

		List<?> errors = CollectionsValidator.safeList(response.getError());
		Boolean errosExist = errors.size() > 0;
		Boolean cumplePresupuesto = (estudioTotal <= response.getAmortizableEstudio());

		logger.info(" cumplePresupuesto [{}] = ( estudioTotal [{}] <= amortizableEstudio [{}] )", cumplePresupuesto,
				estudioTotal, response.getAmortizableEstudio());

		logger.info(" Cumple presupuesto [{}] errores [{}]", cumplePresupuesto, errors.size());

		if (cumplePresupuesto && !errosExist) {
			code = ErrorCodes.SUCCESS;
			ErrorUtils.setMessage(code, messageOk);
		} else if (!cumplePresupuesto && !errosExist) {
			code = ErrorCodes.BUSSINES_ERROR;
		} else {
			code = ErrorCodes.UNEXPECTED_EROR;
			ErrorUtils.setMessage(code, messageError);
		}

		response.setMsg(code.getDetail());
		response.setEstatus(code.getCode());

		logger.info("validate [{}] [{}]", code.getCode(), code.getDetail());

	}

	/**
	 * @see Valida que si la fecha de inicio del contrato es menor a
	 *      DDA_SINCRONIZACION CON SAP regresar siempre OK
	 * @param response
	 * @param errorList
	 */
	public static void validate(PresupuestoResponse response, Date inicioCto, Date sincronizacion) {

		ErrorCodes code = ErrorCodes.UNKNOW_ERROR;

		if (sincronizacion == null || inicioCto == null) {
			code = ErrorCodes.UNEXPECTED_EROR;
			ErrorUtils.setMessage(code, "Fecha nula");

		} else if (DateUtils.compararFechasSincronizacion(inicioCto, sincronizacion)) {
			code = ErrorCodes.SUCCESS;
			ErrorUtils.setMessage(code, "Fecha de inicio de contrato es valida (es menor a la fecha de sync sap)");
		}

		response.setMsg(code.getDetail());
		response.setEstatus(code.getCode());

		logger.info("validate [{}] [{}]", code.getCode(), code.getDetail());
	}

	/**
	 * @see Ajusta los errores y manda codigo de error
	 * @param response
	 * @param errorList
	 */
	public static void addError(AmortizacionResponse response, PresupuestoResponse errorList) {

		List<ErrorCodes> errors = CollectionsValidator.safeList(errorList.getError());

		if (errors.isEmpty()) {

			errorList.setEstatus(ErrorCodes.SUCCESS_PROCESS.getCode());
			errorList.setMsg(ErrorCodes.SUCCESS_PROCESS.getDetail());

		} else {
			errorList.setEstatus(ErrorCodes.FAIL.getCode());
			errorList.setMsg(ErrorCodes.FAIL.getDetail());

		}

		response = (response != null) ? response : new AmortizacionResponse();

		response.setResponseCode(errorList.getEstatus());
		response.setDetail(errorList.getMsg());
		response.setError(errorList.getError());

	}

}
