package random

import (
	"math/rand"
	"time"
)

// RandomXS128 实现 xorshift128+ 伪随机数生成器
type RandomXS128 struct {
	seed0 uint64 // 内部状态前半部分
	seed1 uint64 // 内部状态后半部分
}

// 归一化常数
const (
	normDouble = 1.0 / (1 << 53)
	normFloat  = 1.0 / (1 << 24)
)

// NewRandomXS128 创建一个新的随机数生成器，自动生成初始种子
func NewRandomXS128() *RandomXS128 {
	// 用系统随机数初始化种子（模拟 Java 中 new Random().nextLong() 的行为）
	// 实际使用中可替换为更安全的种子源（如 crypto/rand）
	source := rand.NewSource(time.Now().UnixNano()) // 基于时间的种子源
	r := rand.New(source)                           // 用种子源创建 Rand 实例

	seed := uint64(r.Int())<<32 | uint64(r.Int())
	return NewRandomXS128WithSeed(seed)
}

// NewRandomXS128WithSeed 用单个 uint64 种子创建生成器
func NewRandomXS128WithSeed(seed uint64) *RandomXS128 {
	seed0 := murmurHash3(seed)
	seed1 := murmurHash3(seed0)
	return &RandomXS128{seed0: seed0, seed1: seed1}
}

// NewRandomXS128WithTwoSeeds 用两个 uint64 种子直接设置状态
func NewRandomXS128WithTwoSeeds(seed0, seed1 uint64) *RandomXS128 {
	return &RandomXS128{seed0: seed0, seed1: seed1}
}

// NextLong 生成下一个 64 位随机整数
func (r *RandomXS128) NextLong() uint64 {
	s1 := r.seed0
	s0 := r.seed1
	r.seed0 = s0
	s1 ^= s1 << 23
	r.seed1 = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26)
	return r.seed1 + s0
}

// NextInt 生成下一个 32 位随机整数
func (r *RandomXS128) NextInt() int {
	return int(r.NextLong() & 0xFFFFFFFF)
}

// NextIntN 生成 [0, n) 范围内的随机整数
func (r *RandomXS128) NextIntN(n int) int {
	if n <= 0 {
		panic("n must be positive")
	}
	for {
		bits := int(r.NextLong() >> 1)
		value := int(bits % n)
		if bits-value+n-1 >= 0 {
			return value
		}
	}
}

// NextLongN 生成 [0, n) 范围内的随机 64 位整数
func (r *RandomXS128) NextLongN(n uint64) uint64 {
	if n <= 0 {
		panic("n must be positive")
	}
	for {
		bits := r.NextLong() >> 1
		value := bits % n
		if bits-value+(n-1) >= 0 {
			return value
		}
	}
}

// NextDouble 生成 [0.0, 1.0) 范围内的随机浮点数
func (r *RandomXS128) NextDouble() float64 {
	return float64(r.NextLong()>>11) * normDouble
}

// NextFloat 生成 [0.0, 1.0) 范围内的随机单精度浮点数
func (r *RandomXS128) NextFloat() float32 {
	return float32(float64(r.NextLong()>>40) * normFloat)
}

// NextBoolean 生成随机布尔值
func (r *RandomXS128) NextBoolean() bool {
	return (r.NextLong() & 1) != 0
}

// NextBytes 填充字节数组为随机字节
func (r *RandomXS128) NextBytes(b []byte) {
	i := len(b)
	for i > 0 {
		n := i
		if n > 8 {
			n = 8
		}
		bits := r.NextLong()
		for j := 0; j < n; j++ {
			b[i-1-j] = byte(bits >> (8 * j))
		}
		i -= n
	}
}

// SetSeed 用单个种子重置生成器状态
func (r *RandomXS128) SetSeed(seed uint64) {
	seed0 := murmurHash3(seed)
	r.seed0 = seed0
	r.seed1 = murmurHash3(seed0)
}

// SetState 直接设置内部状态
func (r *RandomXS128) SetState(seed0, seed1 uint64) {
	r.seed0 = seed0
	r.seed1 = seed1
}

// GetState 获取内部状态
func (r *RandomXS128) GetState() (seed0, seed1 uint64) {
	return r.seed0, r.seed1
}

// murmurHash3 用于种子扩展的哈希函数
func murmurHash3(x uint64) uint64 {
	x ^= x >> 33
	x *= 0xff51afd7ed558ccd
	x ^= x >> 33
	x *= 0xc4ceb9fe1a85ec53
	x ^= x >> 33
	return x
}
