package user

import (
	"common/cache"
	"common/connection"
	"goutil/logUtilPlus"
	"sync"
)

var (
	// 用户缓存对象
	userMap        = make(map[int64]*User)
	rwmu           sync.RWMutex
	userAccountMap = make(map[string]*User)
	rwmu2          sync.RWMutex
)

// GetUserByID 根据用户id获取用户信息
func GetUserByID(UserID int64) (*User, error) {

	//判断缓存是否存在
	var user *User

	func() *User {
		rwmu.RLock()
		defer rwmu.RUnlock()
		ok := true
		if user, ok = userMap[UserID]; ok {
			return user
		}
		return nil
	}()

	if user != nil {
		return user, nil
	}

	result := connection.GetUserDB().First(&user, UserID)
	if result.Error != nil {
		return nil, result.Error
	}

	//添加缓存
	func() {
		rwmu.Lock()
		defer rwmu.Unlock()
		user.Cache = cache.NewCache()
		userMap[user.ID] = user
	}()

	return user, nil
}

// AddUserCache 添加用户缓存
func AddUserCache(user *User) {
	rwmu.Lock()
	defer rwmu.Unlock()
	user.Cache = cache.NewCache()
	userMap[user.ID] = user
}

func GetUserByAccount(account string) (*User, error) {
	rwmu2.RLock()
	defer rwmu2.RUnlock()

	//判断缓存是否存在
	var user *User
	ok := true
	if user, ok = userAccountMap[account]; ok {
		return user, nil
	}
	return nil, nil
}

func AddUserIdCache(user *User) {
	rwmu2.Lock()
	defer rwmu2.Unlock()
	user.Cache = cache.NewCache()
	userAccountMap[user.Account] = user
}

// AddUser 添加用户
// AddUser 添加新的用户到数据库中。
// 参数 User: 包含用户信息的对象。
// 返回值: 插入操作影响的行数和可能发生的错误。
func AddUser(user *User) (int64, error) {

	//处理一些验证

	// 写入到数据库
	result := connection.GetUserDB().Create(&user) // 通过数据的指针来创建
	if result.Error != nil {
		logUtilPlus.ErrorLog("添加用户失败 错误信息：", result.Error.Error())
	}

	return user.ID, nil
}

// Login 用户登录
func Login(account string, password string) (*User, error) {

	var user *User

	//这里优先验证缓存数据
	user, err := GetUserByAccount(account)
	if err == nil && user != nil {
		return user, err
	}
	result := connection.GetUserDB().Where("account = ? AND password = ?", account, password).First(&user)
	if result.Error != nil {
		return nil, result.Error
	}

	//写入缓存
	AddUserCache(user)
	AddUserIdCache(user)

	return user, nil
}
