package tools

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"strconv"
	"time"
)

func GenUid() uint32 {
	code := []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
		"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}
	index := RandomNum(0, 25)
	_, m, d := time.Now().Date()
	month := int(m)
	var monthStr string
	if month >= 10 {
		monthStr = SwitchMonthToHex(month)
	} else {
		monthStr = strconv.Itoa(month)
	}
	timeStr := []rune(strconv.Itoa(int(time.Now().Unix())))
	timeUnixStr := []rune(strconv.Itoa(int(time.Now().UnixNano())))
	randStr := fmt.Sprintf("%s%s%02d%s%s%02d", code[index], monthStr, d, string(timeStr[len(timeStr)-5:]),
		string(timeUnixStr[2:7]), RandomNum(0, 99))
	md := md5.New()
	md.Write([]byte(randStr))
	a := []rune(hex.EncodeToString(md.Sum(nil)))
	s := []rune("0123456789012345678901234567890123456789")
	var h string
	for f := 0; f < 8; f++ {
		a := ((a[f] ^ a[f+8]) - a[f]) & 0x1F
		h += string(s[a])
	}
	id, _ := strconv.Atoi(h)
	return uint32(id)
}

func SwitchMonthToHex(month int) string {
	switch month {
	case 10:
		return "A"
	case 11:
		return "B"
	case 12:
		return "C"
	default:
		return "D"
	}
}

//$code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
//        $rand = $code[rand(0, 25)]
//        . strtoupper(dechex(date('m')))
//        . date('d') . substr(time(), -5)
//        . substr(microtime(), 2, 5)
//        . sprintf('%02d', rand(0, 99));
//        for (
//            $a = md5($rand, true),
//            $s = '0123456789012345678901234567890123456789',
//            $d = '',
//            $f = 0;
//            $f < 8;
//            $g = ord($a[$f]),
//            $d .= $s[($g ^ ord($a[$f + 8])) - $g & 0x1F],
//            $f++
//        );
//        return $d;
