package tool

import (
	"fmt"
	"strings"
)

// 乘法逆元参数（mod 2^32）
// multiplier 必须是奇数，与 2^32 互质
// inverse 满足: multiplier * inverse ≡ 1 (mod 2^32)
const (
	deviceMultiplier uint32 = 0x45D9F3B7 // 奇数乘数
	deviceInverse    uint32 = 0x9B845A07 // 乘法逆元 (multiplier * inverse = 1 mod 2^32)
	deviceXorKey1    uint32 = 0x5A3C7E9B // 第一轮 XOR
	deviceXorKey2    uint32 = 0xE7B2A4C3 // 第二轮 XOR
)

// bitShuffle 交错重排 32 位的比特位，打散高低位的关联
func bitShuffle(v uint32) uint32 {
	var result uint32
	// 把偶数位放到高16位，奇数位放到低16位
	for i := 0; i < 16; i++ {
		result |= ((v >> (2 * i)) & 1) << (16 + i)      // 偶数位 → 高半
		result |= ((v >> (2*i + 1)) & 1) << i            // 奇数位 → 低半
	}
	return result
}

// bitUnshuffle 是 bitShuffle 的逆操作
func bitUnshuffle(v uint32) uint32 {
	var result uint32
	for i := 0; i < 16; i++ {
		result |= ((v >> (16 + i)) & 1) << (2 * i)       // 高半 → 偶数位
		result |= ((v >> i) & 1) << (2*i + 1)            // 低半 → 奇数位
	}
	return result
}

// DeviceIdToHash encodes a device id to an 8-char uppercase hex string.
// Uses multiply-xor-shuffle to fully scatter sequential IDs.
// e.g. 1 → "83AEF73C", 2 → "D603916F" (no visible pattern)
func DeviceIdToHash(id int64) string {
	n := uint32(id)
	n ^= deviceXorKey1              // step 1: XOR
	n *= deviceMultiplier           // step 2: 乘法扩散（模 2^32）
	n = bitShuffle(n)               // step 3: 比特位交错
	n ^= deviceXorKey2              // step 4: 再次 XOR
	return strings.ToUpper(fmt.Sprintf("%08x", n))
}

// HashToDeviceId decodes an 8-char hex hash back to a device id.
func HashToDeviceId(hash string) (int64, error) {
	var n uint32
	_, err := fmt.Sscanf(strings.ToLower(hash), "%08x", &n)
	if err != nil {
		return 0, err
	}
	n ^= deviceXorKey2              // reverse step 4
	n = bitUnshuffle(n)             // reverse step 3
	n *= deviceInverse              // reverse step 2: 乘法逆元
	n ^= deviceXorKey1              // reverse step 1
	return int64(n), nil
}
