package luhn

import (
	"fmt"
	"regexp"
	"strconv"
)

// Valid takes a numeric string and returns whether
// it's Luhn valid.
func Valid(toCheck string) bool {
	return GetRemainder(toCheck) == 0
}

// GetRemainder returns the leftover from
// running a number through the Luhn checker
func GetRemainder(toCheck string) int {
	// Remove any non-numeric characters
	r := regexp.MustCompile("[^0-9]+")
	toCheck = r.ReplaceAllString(toCheck, "")

	if len(toCheck) == 0 {
		return -1
	}
	var total int
	var double bool
	for i := range toCheck {
		var add int
		var err error
		idx := (len(toCheck) - 1) - i
		if add, err = strconv.Atoi(string(toCheck[idx])); err != nil {
			return -1
		}
		if double {
			add = add * 2
			if add >= 10 {
				add = add - 9
			}
		}
		double = !double
		total += add
	}
	return total % 10
}

// AddCheck takes a number and returns the appropriate
// number with an added digit that makes it valid
func AddCheck(toCheck string) string {
	if GetRemainder(toCheck) != 0 {
		for i := 0; i <= 9; i++ {
			tst := fmt.Sprintf("%s%d", toCheck, i)
			if GetRemainder(tst) == 0 {
				return tst
			}
		}
	}
	return toCheck
}
