
package filtrocuentabancaria;

import java.math.BigInteger;
import java.util.Map;

public class CuentaBancaria {
    private String numeroCuenta;

    public String getNumeroCuenta() {
        return numeroCuenta;
    }

    public void setNumeroCuenta(String numeroCuenta) {
        this.numeroCuenta = numeroCuenta;
    }

    public static void filtroCuenta(String numeroCuenta) throws GenericaExcepcion {
        int factores[] = {1,2,4,8,5,10,9,7,3,6};
        int acumulador, digitoCalculado;
        int codigoErrorAcumulativo = 0;
        
        //     VERIFICACION NUMERO DIGITOS CUENTA
        if (numeroCuenta.length() != 24)
            throw new GenericaExcepcion(-1);
         
        //     VERIFICACION DIGITOS VALIDOS
        if (numeroCuenta.charAt(0) != 'E')
            throw new GenericaExcepcion(1);
        
        if (numeroCuenta.charAt(1) != 'S')
            throw new GenericaExcepcion(2);
        
        boolean encontradoDigitoNoNumerico = false;
        int contadorPosiciones = 2;
        while (contadorPosiciones <= 23 && !encontradoDigitoNoNumerico) {
            if (numeroCuenta.codePointAt(contadorPosiciones) < 48 || numeroCuenta.codePointAt(contadorPosiciones) >57)
                encontradoDigitoNoNumerico = true;
            contadorPosiciones++;
        }
        
        if (encontradoDigitoNoNumerico)
            throw new GenericaExcepcion(contadorPosiciones);
          
        //     VERIFICACION DIGITOS CONTROL IBAN
        int numeroControlIBAN = 98 - (new BigInteger(numeroCuenta.substring(4, 24) + "142800").mod(BigInteger.valueOf(97)).intValue());
        String digitosControlIBAN = String.valueOf(numeroControlIBAN);
        if (numeroControlIBAN < 10)
            digitosControlIBAN = "0" + digitosControlIBAN;
        
        if (digitosControlIBAN.compareTo(numeroCuenta.substring(2, 4)) != 0)
            codigoErrorAcumulativo += 32;          
        
        //     VERIFICACION DIGITO CONTROL VALIDACION CONJUNTO EEEESSSS
        acumulador = 0;
        for (int i=4; i<=11; i++)   
            acumulador += (numeroCuenta.codePointAt(i) - 48) * factores[i - 2];
           
        digitoCalculado = 11 -(acumulador % 11);
        switch(digitoCalculado)
        { case 10: digitoCalculado = 1;
                   break;
          case 11: digitoCalculado = 0;
                   break;                   
        }
        
        if (digitoCalculado != (numeroCuenta.codePointAt(12) - 48))
            codigoErrorAcumulativo += 64; 
        
        //     VERIFICACION DIGITO CONTROL VALIDACION NUMERO CUENTA NNNNNNNNNN
        acumulador = 0;
        for (int i=14; i<=23; i++)   
            acumulador += (numeroCuenta.codePointAt(i) - 48) * factores[i - 14];
           
        digitoCalculado = 11 -(acumulador % 11);
        switch(digitoCalculado)
        { case 10: digitoCalculado = 1;
                   break;
          case 11: digitoCalculado = 0;
                   break;                   
        }
          
        if (digitoCalculado != (numeroCuenta.codePointAt(13) - 48))
            codigoErrorAcumulativo += 128; 
        
        if (codigoErrorAcumulativo > 0)
            throw new GenericaExcepcion(codigoErrorAcumulativo);
    }   
    
    public String getNombreEntidadBancaria(Map<String, String> entidadesBancarias) {
        String nombreEntidadBancaria = "Entidad no registrada en el Map";
        if (entidadesBancarias.containsKey(numeroCuenta.substring(4, 8)))
            nombreEntidadBancaria = entidadesBancarias.get(numeroCuenta.substring(4, 8));
        return nombreEntidadBancaria;
    } 
    
    public String getSucursalBancaria(Map<String, String> sucursalesBancarias) {
        String direccionSucursalBancaria = "Sucursal no registrada en el Map";
        if (sucursalesBancarias.containsKey(numeroCuenta.substring(8, 12)))
            direccionSucursalBancaria = sucursalesBancarias.get(numeroCuenta.substring(8, 12));
        return direccionSucursalBancaria;
    }     
}
