package secret

import (
	"crypto/rand"
	"fmt"
	"math/big"
	"os"
	"path/filepath"
)

// generateRandomString generates a random string of the specified length using the given character set
func generateRandomString(length int, charset string) (string, error) {
	if length <= 0 {
		return "", fmt.Errorf("length must be positive")
	}

	result := make([]byte, length)
	charsetLen := big.NewInt(int64(len(charset)))

	for i := 0; i < length; i++ {
		randomIndex, err := rand.Int(rand.Reader, charsetLen)
		if err != nil {
			return "", fmt.Errorf("failed to generate random number: %w", err)
		}
		result[i] = charset[randomIndex.Int64()]
	}

	return string(result), nil
}

// DetermineStateDir determines the state directory based on environment variables and OS
func DetermineStateDir(customConfigDir string) string {
	// Check for environment variable first
	if envStateDir := os.Getenv(EnvStateDir); envStateDir != "" {
		return envStateDir
	}

	// Use custom config dir if provided
	if customConfigDir != "" {
		return filepath.Join(customConfigDir, AppID)
	}

	// Use os.UserConfigDir() which handles platform-specific directories:
	// - On Unix systems, it returns $XDG_CONFIG_HOME or $HOME/.config
	// - On Darwin, it returns $HOME/Library/Application Support
	// - On Windows, it returns %AppData%
	configDir, err := os.UserConfigDir()
	if err != nil {
		// Fallback to a reasonable default if we can't determine user config dir
		homeDir, _ := os.UserHomeDir()
		return filepath.Join(homeDir, ".config", AppID)
	}
	return filepath.Join(configDir, AppID)
}
