package com.ejie.ad74a.validacion;

import java.math.BigInteger;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Component;

import com.ejie.ad74a.exceptions.Ad74aException;
import com.ejie.ad74a.exceptions.ErrorField;
import com.ejie.ad74a.model.Cuentas;
import com.ejie.ad74a.model.Direcciones;
import com.ejie.ad74a.model.Solicitantes;
import com.ejie.ad74a.service.SolicitantesService;
import com.ejie.ad74a.util.comun.UtilLiterales;
import com.ejie.ad74a.util.comun.UtilValidaciones;
import com.ejie.ad74a.util.comun.Utilidades;
import com.ejie.ad74a.util.constantes.Constantes;
import com.ejie.ad74a.util.constantes.modelos.TipoSolicitantes;
import com.ejie.ad74a.util.comun.Utilidades;

@Component(value = "CuentasValidator")
public class CuentasValidator {
	private static final Logger LOGGER = LoggerFactory.getLogger(CuentasValidator.class);

	private static final String LABEL_APELLIDO101 = "solicitantes.apellido101";
	private static final String LABEL_APELLIDO201 = "solicitantes.apellido201";
	private static final String LABEL_NOMBRE01 = "solicitantes.nombre01";
	private static final String LABEL_BENEFICIARIO01 = "solicitantes.beneficiario01";
	private static final String LABEL_TIPOIDENTIFICADOR01 = "solicitantes.tipoIdentificador01";
	private static final String LABEL_IDENTIFICADOR01 = "solicitantes.identificador01";
	private static final String LABEL_DNI_ERRONEO = "cuentas.DniErroneo";
	private static final String LABEL_NIE_ERRONEO = "cuentas.NieErroneo";
	private static final String LABEL_TIPO_DOCUMENTO_NULL = "cuentas.tipoCuenta";
	private static final String LABEL_NUMCUENTA_ERRONEO = "cuentas.numCuentaErroneo";
	private static final String LABEL_ERROR_FORMATO_NUMCUENTA = "cuentas.formatoNumCuentaErroneo";
	private static final String LABEL_SEXO01 = "solicitantes.sexo01";
	private static final String LABEL_TLFNOSERVICIO01 = "solicitantes.tlfnoservicio01";

	public static final int MAX_LENGTH_IDENTIFICADOR01 = 20;
	public static final int MAX_LENGTH_NOMBRE01 = 100;
	public static final int MAX_LENGTH_APELLIDOS01 = 200;

	private static final String LABEL_ERROR_CAMBIO_TIT = "error.cambioTitular";

	// Label de campos para mensajes de error.

	@Autowired
	private SolicitantesService solicitantesService;

	@Resource
	private ReloadableResourceBundleMessageSource appMessageSource;

	public void tipoDocumentoNotNull(List<ErrorField> errorFields, Cuentas cuentas) {
		CuentasValidator.LOGGER.info("SolicitantesValidator: validateSolicitante ");

		if (cuentas.getCodTipoIdenTitular05().contentEquals("")) {
			errorFields.add(new ErrorField(CuentasValidator.LABEL_TIPO_DOCUMENTO_NULL,
					UtilValidaciones.LABEL_IDENTIFICADOR_NULL));
		}

	}

	public void validateDNI(List<ErrorField> errorFields, Cuentas cuentas) {
		CuentasValidator.LOGGER.info("SolicitantesValidator: validateSolicitante ");

		if (Boolean.FALSE.equals(Utilidades.isValidDni(cuentas.getIdenTitular05()))) {
			errorFields.add(new ErrorField(CuentasValidator.LABEL_DNI_ERRONEO, UtilValidaciones.LABEL_ERROR_NIF_NIE));
		}

	}

	public void validateNIE(List<ErrorField> errorFields, Cuentas cuentas) {
		CuentasValidator.LOGGER.info("SolicitantesValidator: validateSolicitante ");

		if (Boolean.FALSE.equals(Utilidades.isValidNie(cuentas.getIdenTitular05()))) {
			errorFields.add(new ErrorField(CuentasValidator.LABEL_NIE_ERRONEO, UtilValidaciones.LABEL_ERROR_NIF_NIE));
		}

	}

	public void validateIBAN(List<ErrorField> errorFields, Cuentas cuentas) {
		CuentasValidator.LOGGER.info("SolicitantesValidator: validateSolicitante ");

		if (Boolean.FALSE.equals(validarIBAN(cuentas.getNumCuenta05()))) {
			errorFields.add(new ErrorField(CuentasValidator.LABEL_NUMCUENTA_ERRONEO,
					CuentasValidator.LABEL_ERROR_FORMATO_NUMCUENTA));
		}

	}

	public static boolean validarIBAN(String cuenta) {
		int IBANNUMBER_MIN_SIZE = 15;
		int IBANNUMBER_MAX_SIZE = 34;
		BigInteger IBANNUMBER_MAGIC_NUMBER = new BigInteger("97");
		String newAccountNumber = cuenta.trim();

		// Check that the total IBAN length is correct as per the country. If not, the
		// IBAN is invalid. We could also check
		// for specific length according to country, but for now we won't
		if (newAccountNumber.length() < IBANNUMBER_MIN_SIZE || newAccountNumber.length() > IBANNUMBER_MAX_SIZE) {
			return false;
		}

		// Move the four initial characters to the end of the string.
		newAccountNumber = newAccountNumber.substring(4) + newAccountNumber.substring(0, 4);

		// Replace each letter in the string with two digits, thereby expanding the
		// string, where A = 10, B = 11, ..., Z = 35.
		StringBuilder numericAccountNumber = new StringBuilder();
		for (int i = 0; i < newAccountNumber.length(); i++) {
			numericAccountNumber.append(Character.getNumericValue(newAccountNumber.charAt(i)));
		}

		// Interpret the string as a decimal integer and compute the remainder of that
		// number on division by 97.
		BigInteger ibanNumber = new BigInteger(numericAccountNumber.toString());
		return ibanNumber.mod(IBANNUMBER_MAGIC_NUMBER).intValue() == 1;

	}

}
