module.exports = function(tin, country) {
    if (tin == null || country == null)
        return true;
    if (typeof tin != 'string' || typeof country != 'string')
        return false;

    tin = tin.toUpperCase();
    country = country.toLowerCase();

    let len = tin.length;

    let validators = {
        es: {
            regExp: /^[A-Z0-9]\d{7}[A-Z0-9]$/,
            validate: () => {
                let isCif = /[A-W]/.test(tin.charAt(0));
                let lastDigit = tin.charAt(len - 1);
                let computedDigit;

                if (isCif) {
                    let numbers = tin.substring(1, 8)
                        .split('')
                        .map(x => parseInt(x));

                    let pairSum = numbers
                        .filter((_, i) => i % 2 != 0)
                        .reduce((a, x) => a + x);

                    let oddSum = numbers
                        .filter((_, i) => i % 2 == 0)
                        .map(x => x * 2)
                        .join('')
                        .split('')
                        .map(x => parseInt(x))
                        .reduce((a, x) => a + x);

                    let sum = (pairSum + oddSum).toString();
                    let units = parseInt(sum.charAt(sum.length - 1));
                    let control = units == 0 ? 0 : 10 - units;
                    let isLetter = /^[A-Z]$/.test(lastDigit);
                    computedDigit = isLetter ? 'JABCDEFGHI'.charAt(control) : control.toString();
                } else {
                    // Foreign NIF
                    let index = 'XYZ'.indexOf(tin.charAt(0));
                    let nif = index == -1 ? tin : index.toString() + tin.substring(1);

                    let rest = parseInt(nif.substring(0, 8)) % 23;
                    computedDigit = 'TRWAGMYFPDXBNJZSQVHLCKE'.charAt(rest);
                }

                return computedDigit == lastDigit;
            }
        },
        it: {
            regExp: /^(\d{11}|[A-Z]{6}\d{2}[A-Z]\d{2}[A-Z]\d{3}[A-Z])$/
        },
        pt: {
            regExp: /^\d{9}$/
        }
    };

    let validator = validators[country];

    if (!validator)
        return true;

    return validator.regExp.test(tin)
        && (!validator.validate || validator.validate());
};