app.service('$validate', function() {
  function getNumberFromChar(letter) {
    switch (letter) {
      case '0': return 0;
      case '1': return 1;
      case '2': return 2;
      case '3': return 3;
      case '4': return 4;
      case '5': return 5;
      case '6': return 6;
      case '7': return 7;
      case '8': return 8;
      case '9': return 9;
      case 'A': return 10;
      case 'B': return 11;
      case 'C': return 12;
      case 'D': return 13;
      case 'E': return 14;
      case 'F': return 15;
      case 'G': return 16;
      case 'H': return 17;
      case 'I': return 18;
      case 'J': return 19;
      case 'K': return 20;
      case 'L': return 21;
      case 'M': return 22;
      case 'N': return 23;
      case 'O': return 24;
      case 'P': return 25;
      case 'Q': return 26;
      case 'R': return 27;
      case 'S': return 28;
      case 'T': return 29;
      case 'U': return 30;
      case 'V': return 31;
      case 'W': return 32;
      case 'X': return 33;
      case 'Y': return 34;
      case 'Z': return 35;
      default: return -1;
    }
  }

  function isValidString(v) {
    if (!v) {
      return false;
    }

    return (typeof v == 'string' || v instanceof String);
  }

  this.nif = function(value) {
    if (!isValidString(value)) {
      return false;
    }

    //Qualquer sequencia de 9 digitos iniciada por 1,2,5,6,7,8,9
    var re = new RegExp("[1,2,5,6,7,8,9]\\d{8}");
    if (!value.match(re)) {
      return false;
    }

    //calculo do total, de cada numero do contribuinte
    var total = 0;
    for (i = 0; i < 8; i++) {
      total += parseInt(value[i]) * (9 - i);
    }

    var check = 11 - (total % 11);
    if (check >= 10) {
      check = 0;
    }
    if(check !== parseInt(value[8])) {
      return false;
    }
    else {
      return true;
    }
  };

  this.niss = function(input) {
    if (!isValidString(input)) {
      return false;
    }

    input = input.replace(/\s+/g, '');
    if(input.length !== 11) {
      return false;
    }

    var factor =  [ 29, 23, 19, 17, 13, 11, 7, 5, 3, 2 ];
    var totalSum = 0;
    for (var i = 0; i<input.length-1; i++) {
      totalSum += parseInt(input[i] * factor[i]);
    }

    totalSum = 9-parseInt(totalSum % 10);
    var checkSum = parseInt(input[input.length-1]);

    return (totalSum === checkSum);
  };

  this.cc = function(input) {
    if (!isValidString(input)) {
      return false;
    }

    var sum = 0;
    var secondDigit = false;
    if(input.length !== 12) {
      return false;
    }
    for (var i = input.length-1; i >= 0; --i) {
      var valor = getNumberFromChar(input[i]);
      if (valor === -1) {
        return false;
      }
      if (secondDigit) {
        valor *= 2;
        if (valor > 9) {
          valor -= 9;
        }
      }
      sum += valor;
      secondDigit = !secondDigit;
    }
    return (sum % 10) === 0;
  };

  this.nib = function(value) {
    if (!isValidString(value)) {
      return false;
    }

    var re = new RegExp("^\\d{21}$");
    if (!value.match(re)) {
      return false;
    }

    var result = 0;
    for (var i = 0; i < 19; i++) {
      result += parseInt(value[i]);
      result *= 10;
      result %= 97;
    }
    result = 98 - ((result * 10) % 97);
    return parseInt(value.substring(19, 21)) === result;
  };
});
