package string_utils

import (
	"golang.org/x/text/runes"
	"golang.org/x/text/transform"
	"golang.org/x/text/unicode/norm"
	"regexp"
	"strconv"
	"strings"
	"unicode"
)

// ReplaceNonSpacingMarks removes diacritics e.g. êžů becomes ezu
func ReplaceNonSpacingMarks(str string) string {
	t := transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC) // Mn: non-spacing marks
	result, _, _ :=  transform.String(t, str)
	return result
}

func RemoveAllWhiteSpaces(s string) string {
	return strings.ReplaceAll(strings.ReplaceAll(s, " ", ""), "\t", "")
}

func ReplaceCaseInsensitive(string, toReplace, replaceWith string) string {
	regex := regexp.MustCompile("(?i)" + strings.ToLower(toReplace))
	return regex.ReplaceAllString(string, replaceWith)
}

// TrimQuotes - trims quotes from a string (ie: "foo" will return foo)
func TrimQuotes(stringToTrim string) string {
	if len(stringToTrim) >= 2 {
		if stringToTrim[0] == '"' && stringToTrim[len(stringToTrim)-1] == '"' {
			return stringToTrim[1 : len(stringToTrim)-1]
		}
	}

	return stringToTrim
}

// IsNumericString returns true if the string can be converted to a float without error
func IsNumericString(s string) bool {
	_, err := strconv.ParseFloat(s, 64)
	return err == nil
}

// Standardise phone numbers with +27 instead of 0 prefix
func StandardisePhoneNumber(number string) string {
	// is the first rune/char of the string a 0
	if []rune(number)[0] == []rune("0")[0] {
		// Add south african country code (hardcoded for now)
		number = "+27" + number[1:len(number)]
	}
	return number
}

func FormatPhoneNumber(phoneNumber string) string {
	if len(phoneNumber) > 7 {
		return phoneNumber
	}

	// Format as 076 453 2188
	phoneNumber = insertInto(phoneNumber, 3, " ")
	phoneNumber = insertInto(phoneNumber, 7, " ")
	return phoneNumber
}

func insertInto(s string, index int, characters string) string {
	return s[:index] + characters + s[index:]
}

func IsAlphaNumeric(str string) bool {
	regex := regexp.MustCompile("^[a-zA-Z0-9]*$")
	return regex.MatchString(str)
}

func Equal(a string, b string) bool {
	return strings.TrimSpace(strings.ToLower(a)) == strings.TrimSpace(strings.ToLower(b))
}

func UnwrapString(s *string) string {
	if s == nil {
		return ""
	}
	return *s
}