// License: LGPL-3.0-or-later
const R = require('ramda')

// Reference: https://en.wikipedia.org/wiki/Luhn_algorithm

module.exports = val => {
  val = val.replace(/[-\s]/g, '')
  return val.match(/^[0-9-\s]+$/) && luhnCheck(val)
}

const luhnCheck =
  R.compose(
    R.equals(0)
  , R.modulo(R.__, 10)
  , R.sum
  , R.map(n => n > 9 ? n - 9 : n) // Subtract 9 from those digits greater than 9
  , R.addIndex(R.map)((n, i) => i % 2 === 0 ? n : n * 2) // Double the value of every second digit
  , R.map(ch => Number(ch))
  , R.reverse)

/*
Luhn check in haskell:
luhn = (0 ==) . (`mod` 10) . sum . map (uncurry (+) . (`divMod` 10)) .
       zipWith (*) (cycle [1,2]) . map digitToInt . reverse
*/