package utils

import (
	"crypto/rand"
	"math/big"
	"regexp"
	"strings"

	"github.com/mozillazg/go-pinyin"
)

// GenerateUsername 根据姓名生成拼音用户名
// 规则：取每个汉字的首字母小写，如果是英文则直接转小写
// 例如：刘强 -> lq (这里用户要求是 liuq，需要全拼还是首字母？)
// 用户需求：刘强 -> liuq。看起来是第一个字全拼 + 后面的字首字母？或者全拼？
// 再次确认用户需求："比如姓名叫刘强，用户名叫liuq" -> liu (刘) q (强)。
// 所以规则应该是：姓的全拼 + 名的首字母。
func GenerateUsernameBase(name string) string {
	a := pinyin.NewArgs()
	// 包含声调
	// a.Style = pinyin.Tone
	// 不包含声调，只取拼音
	a.Style = pinyin.Normal

	// 简单的处理逻辑：
	// 如果是纯英文，直接转小写并去空格
	if isEnglishName(name) {
		return strings.ToLower(strings.ReplaceAll(name, " ", ""))
	}

	rows := pinyin.Pinyin(name, a)
	if len(rows) == 0 {
		// 无法转换，返回随机字符串或原名处理
		return "user" + GenerateRandomString(4)
	}

	var sb strings.Builder
	// 姓：取全拼 (rows[0])
	if len(rows) > 0 && len(rows[0]) > 0 {
		sb.WriteString(rows[0][0])
	}
	// 名：取首字母 (rows[1:]...)
	for i := 1; i < len(rows); i++ {
		if len(rows[i]) > 0 {
			// 取拼音的第一个字母
			str := rows[i][0]
			if len(str) > 0 {
				sb.WriteString(string(str[0]))
			}
		}
	}

	return sb.String()
}

func isEnglishName(name string) bool {
	match, _ := regexp.MatchString(`^[a-zA-Z\s]+$`, name)
	return match
}

// GenerateRandomPassword 生成随机强密码
// 长度至少10位，包含大小写字母、数字、特殊字符
func GenerateRandomPassword() string {
	const (
		upperLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
		lowerLetters = "abcdefghijklmnopqrstuvwxyz"
		digits       = "0123456789"
		specialChars = "!@#$%^&*()_+-=[]{}|;:,.<>?"
	)
	
	length := 12
	ret := make([]byte, length)
	
	// 保证每种类型至少有一个
	ret[0] = upperLetters[randInt(len(upperLetters))]
	ret[1] = lowerLetters[randInt(len(lowerLetters))]
	ret[2] = digits[randInt(len(digits))]
	ret[3] = specialChars[randInt(len(specialChars))]

	allChars := upperLetters + lowerLetters + digits + specialChars
	for i := 4; i < length; i++ {
		ret[i] = allChars[randInt(len(allChars))]
	}

	// Shuffle
	// ... (shuffle implementation optional but good)
	
	return string(ret)
}

func randInt(max int) int {
	n, _ := rand.Int(rand.Reader, big.NewInt(int64(max)))
	return int(n.Int64())
}

func GenerateRandomString(n int) string {
	const letters = "abcdefghijklmnopqrstuvwxyz0123456789"
	ret := make([]byte, n)
	for i := 0; i < n; i++ {
		num, _ := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
		ret[i] = letters[num.Int64()]
	}
	return string(ret)
}

