package redismgr

import (
	"encoding/json"
	"errors"
	"fmt"
	"server/msg"
	"strconv"

	"github.com/gomodule/redigo/redis"
	"github.com/name5566/leaf/log"
)

// 保存用户信息到 Redis 哈希表
func SaveUserInfoToRedis(userData *msg.UserInfo) error {
	// 将用户数据转换为 JSON 字符串
	userDataJson, err := json.Marshal(userData)
	if err != nil {
		log.Debug("Error marshalling user data: %v", err)
		return err
	}

	// 获取 Redis 连接
	conn := GetPool().Get()
	defer conn.Close()

	// 使用 HSET 存储用户数据
	_, err = conn.Do("HSET", "user:"+userData.UserId, "data", string(userDataJson))
	if err != nil {
		log.Debug("Error saving user data to Redis: %v", err)
		return err
	}

	// 设置过期时间为3天
	// _, err = conn.Do("EXPIRE", "user:"+userData.UserId, 86400*3) // 86400*3 = 3天
	_, err = conn.Do("EXPIRE", "user:"+userData.UserId)
	if err != nil {
		log.Debug("Error setting expiry for user data in Redis: %v", err)
		return err
	}
	// 进入redis队列存mongodb .
	// UpdateUserInfo(userData)
	log.Debug("User data saved to Redis for userId: %s", userData.UserId)
	return nil
}

// IncrementUserTotal 将UserTotal的值原子性加1，返回增加后的新值
func IncrementUserTotal() (int64, error) {
	conn := GetPool().Get()
	defer conn.Close()

	// 使用INCR命令原子性增加
	newVal, err := redis.Int64(conn.Do("INCR", "UserTotal"))
	if err != nil {
		log.Debug("Failed to increment UserTotal: %v", err)
		return 0, fmt.Errorf("redis INCR failed: %w", err)
	}

	return newVal, nil
}

func GetUserTotal() int64 {
	conn := GetPool().Get()
	defer conn.Close()
	//获取key为UserTotal的 int 类型

	// 使用GET命令获取key为"UserTotal"的值
	reply, err := redis.Int64(conn.Do("GET", "UserTotal"))
	if err != nil {
		if err == redis.ErrNil {
			log.Debug("Key 'UserTotal' does not exist in Redis")
			return 0
		}
		log.Debug("Failed to get 'UserTotal' from Redis: %v", err)
		return 0
	}
	return reply
}

// 根据账号密码设置用户id
func SetUserIDFromRedisByAP(account string, password string) (string, bool) {
	newUserId, err := IncrementUserTotal()
	if err != nil {
		log.Debug("Failed to increment user count: %v", err)
		return strconv.FormatInt(0, 10), false
	}
	conn := GetPool().Get()
	defer conn.Close()
	str := account + "," + password
	_, err_info := redis.String(conn.Do("SET", str, newUserId))
	return strconv.FormatInt(newUserId, 10), err_info == nil
}

// 根据账号密码获取用户id
func GetUserIDFromRedisByAP(account string, password string) (string, error) {
	conn := GetPool().Get()
	defer conn.Close()
	str := account + "," + password
	// 将字符串转换为字节切片
	// data := []byte(str)
	// encoded := base64.StdEncoding.EncodeToString(data)
	userId, err := redis.String(conn.Do("GET", str))

	if err == redis.ErrNil {
		// 如果 Redis 中没有数据
		errorMsg := fmt.Sprintf("User data not found in Redis for userId: %s", userId)
		log.Debug(errorMsg)
		return "", errors.New(errorMsg)
	} else if err != nil {
		log.Debug("Error fetching user data from Redis: %v", err)
		return "", err
	}
	return userId, nil
}

// 获取用户信息从 Redis 哈希表
func GetUserInfoFromRedis(userId string) (*msg.UserInfo, error) {
	// 获取 Redis 连接
	conn := GetPool().Get()
	defer conn.Close()

	// 从 Redis 获取用户数据
	userDataJson, err := redis.String(conn.Do("HGET", "user:"+userId, "data"))
	if err == redis.ErrNil {
		// 如果 Redis 中没有数据
		errorMsg := fmt.Sprintf("User data not found in Redis for userId: %s", userId)
		log.Debug(errorMsg)
		return nil, errors.New(errorMsg)
	} else if err != nil {
		log.Debug("Error fetching user data from Redis: %v", err)
		return nil, err
	}

	// 将获取到的 JSON 字符串反序列化为 UserData 对象
	var userData msg.UserInfo
	err = json.Unmarshal([]byte(userDataJson), &userData)
	if err != nil {
		log.Debug("Error unmarshalling user data from Redis: %v", err)
		return nil, err
	}

	log.Debug("User data fetched from Redis for userId: %s", userId)
	return &userData, nil
}

// // 字符串操作
// _, err := conn.Do("SET", "key", "value")
// val, err := redis.String(conn.Do("GET", "key"))

// // 哈希操作
// _, err := conn.Do("HSET", "user:1000", "name", "Alice", "age", 30)
// name, err := redis.String(conn.Do("HGET", "user:1000", "name"))

// // 列表操作
// _, err := conn.Do("LPUSH", "mylist", "item1")
// item, err := redis.String(conn.Do("RPOP", "mylist"))

// // 过期时间
// _, err := conn.Do("EXPIRE", "key", 3600)
