package utils

import (
	"crypto/rand"
	"fmt"
	"math/big"
)

const (
	lowerChars  = "abcdefghijklmnopqrstuvwxyz"
	upperChars  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	digitChars  = "0123456789"
	symbolChars = "!@#$%^&*()_+-=[]{}|;:,.<>?"
)

// GenerateSecurePassword creates a 7-character random password
// ensuring at least one of each: upper, lower, digit, symbol
func GenerateSecurePassword() string {
	length := 7

	// Requirements: 1 upper, 1 lower, 1 digit, 1 symbol = 4 chars
	// Remaining: 3 chars from any pool

	allChars := lowerChars + upperChars + digitChars // + symbolChars

	password := make([]byte, length)

	// 1. Mandatory chars
	password[0] = mustGetRandomChar(upperChars)
	password[1] = mustGetRandomChar(lowerChars)
	password[2] = mustGetRandomChar(digitChars)
	// password[3] = mustGetRandomChar(symbolChars)

	// 2. Remaining random chars
	for i := 3; i < length; i++ {
		password[i] = mustGetRandomChar(allChars)
	}

	// 3. Shuffle (using secure random)
	shuffleSecure(password)

	return string(password)
}

func mustGetRandomChar(pool string) byte {
	idx, _ := rand.Int(rand.Reader, big.NewInt(int64(len(pool))))
	return pool[idx.Int64()]
}

func shuffleSecure(slice []byte) {
	for i := len(slice) - 1; i > 0; i-- {
		jBig, _ := rand.Int(rand.Reader, big.NewInt(int64(i+1)))
		j := int(jBig.Int64())
		slice[i], slice[j] = slice[j], slice[i]
	}
}

func Example() {
	fmt.Println(GenerateSecurePassword())
}
