package mixrepoimpl

import (
	"context"
	"hash/fnv"
	"math"
	"strconv"
	"voucher/internal/biz/mixrepos"
	"voucher/internal/data"
	"voucher/internal/pkg/uid"
)

type GenerateRepoImpl struct {
	rdb *data.Rdb
}

func NewGenerateMixRepoImpl(rdb *data.Rdb) mixrepos.GenerateMixRepo {
	return &GenerateRepoImpl{rdb: rdb}
}

// GeneratorString 生成字符串
func (s *GenerateRepoImpl) GeneratorString(ctx context.Context, workId int) (string, error) {
	serverIdStr := uid.GetAppId(ctx)
	serverId := s.hashMod(serverIdStr)
	number, err := uid.NewSignGenerator(s.rdb.Rdb).SetWorkerID(workId).SetServerID(serverId).GetNumber()
	if err != nil {
		return "", err
	}
	return strconv.FormatUint(number, 10), nil
}

// GeneratorNumber 生成unit64
func (s *GenerateRepoImpl) GeneratorNumber(ctx context.Context, workId int) (uint64, error) {
	serverIdStr := uid.GetAppId(ctx)
	serverId := s.hashMod(serverIdStr)
	number, err := uid.NewSignGenerator(s.rdb.Rdb).SetWorkerID(workId).SetServerID(serverId).GetNumber()
	if err != nil {
		return 0, err
	}
	return number, nil
}

// hashMod hash mod
func (s *GenerateRepoImpl) hashMod(hashStr string) int {
	hash := fnv.New32a()
	hash.Write([]byte(hashStr))
	hashValue := hash.Sum32()
	return int(math.Mod(float64(hashValue), 32))
}
