package utils

import (
	"regexp"
	"strings"
)

const (
	// DefaultDeveloperName is used when sanitization results in empty string
	DefaultDeveloperName = "Unnamed"
	// DeveloperNameNumericPrefix is prepended when name starts with a number
	DeveloperNameNumericPrefix = "X"
	// DeveloperNameMaxLength is the Salesforce limit for DeveloperName
	DeveloperNameMaxLength = 80
)

// nonAlphanumericOrUnderscore matches any character that is not alphanumeric or underscore
var nonAlphanumericOrUnderscore = regexp.MustCompile(`[^a-zA-Z0-9_]`)

// consecutiveUnderscores matches two or more consecutive underscores
var consecutiveUnderscores = regexp.MustCompile(`_+`)

// SanitizeDeveloperName converts a user-provided name into a valid Salesforce DeveloperName.
// Rules enforced:
// - Only alphanumeric characters and underscores allowed
// - Must start with a letter (prefixes with 'X' if starts with number)
// - Spaces replaced with underscores
// - Special characters removed
// - Consecutive underscores collapsed to single underscore
// - Leading/trailing underscores trimmed
// - Maximum length of 80 characters (Salesforce limit)
func SanitizeDeveloperName(name string) string {
	if name == "" {
		return ""
	}

	// Replace spaces with underscores
	clean := strings.ReplaceAll(name, " ", "_")

	// Remove all non-alphanumeric characters except underscore
	clean = nonAlphanumericOrUnderscore.ReplaceAllString(clean, "")

	// Collapse consecutive underscores to single underscore
	clean = consecutiveUnderscores.ReplaceAllString(clean, "_")

	// Trim leading and trailing underscores
	clean = strings.Trim(clean, "_")

	// Ensure it doesn't start with a number
	if len(clean) > 0 && clean[0] >= '0' && clean[0] <= '9' {
		clean = DeveloperNameNumericPrefix + clean
	}

	// Handle empty result after sanitization
	if clean == "" {
		clean = DefaultDeveloperName
	}

	// Enforce max length (Salesforce limit)
	if len(clean) > DeveloperNameMaxLength {
		clean = clean[:DeveloperNameMaxLength]
		// Re-trim trailing underscore if truncation left one
		clean = strings.TrimSuffix(clean, "_")
	}

	return clean
}
