package webServer

import (
	"sync"
	"time"
)

var (
	//已经登录的用户
	loginUserMap = make(map[int64]*TokenInfo)

	//锁
	lock sync.RWMutex

	//跳过验证token的页面
	skipVerifyTokenPage = make(map[string]bool)

	//需要获取请求信息
	needGetRequestInfo = make(map[string]bool)
)

type TokenInfo struct {
	//管理员id
	Id int64

	//管理员账号
	Account string

	//登录用户缓存
	UserInfo any

	//过期时间
	ExpireTime time.Time
}

// AddLoginUserToken 添加登录用户及其令牌信息到缓存中
// 参数:
//
//	token: 用户的登录令牌
//	tokenInfo: 令牌的详细信息，包括过期时间等
func AddLoginUserToken(token int64, tokenInfo *TokenInfo) {

	//添加锁防止并发
	lock.Lock()
	defer lock.Unlock()

	// 默认24小时过期
	tokenInfo.ExpireTime = time.Now().Add(time.Hour * 24)

	//移除旧的令牌
	for tokenKey, tokenInfoValue := range loginUserMap {
		if tokenInfo.Id == tokenInfoValue.Id {
			delete(loginUserMap, tokenKey)
		}
	}

	// 将令牌与用户信息添加到全局的登录用户映射中
	loginUserMap[token] = tokenInfo
}

// CheckToken 检查令牌是否有效
// 参数:
//
//	token: 需要检查的令牌字符串
//
// 返回值:
//
//	bool: 表示令牌是否有效的布尔值，true表示有效，false表示无效
func CheckToken(token int64) (bool, *TokenInfo) {

	//添加锁防止并发
	lock.Lock()
	defer lock.Unlock()

	// 获取当前时间
	now := time.Now()

	// 获取令牌对应的用户信息
	tokenInfo, ok := loginUserMap[token]
	if !ok {
		// 如果没有找到对应的用户信息，则令牌无效
		return false, nil
	}

	// 获取令牌过期时间
	expireTime := tokenInfo.ExpireTime

	// 如果令牌过期时间早于当前时间，则令牌无效
	if expireTime.Before(now) {

		//移除令牌
		delete(loginUserMap, token)

		return false, nil
	}

	//如果生效的话，则更新过期时间
	tokenInfo.ExpireTime = now.Add(time.Hour * 24)

	return true, tokenInfo
}

// AddSkipVerifyTokenPage 添加跳过验证token的页面
func AddSkipVerifyTokenPage(moduleName, methodName string) {
	skipVerifyTokenPage[moduleName+"_"+methodName] = true
}

// IsSkipVerifyTokenPage 判断是否跳过验证token的页面
func IsSkipVerifyTokenPage(moduleName, methodName string) bool {
	exist, ok := skipVerifyTokenPage[moduleName+"_"+methodName]
	if !exist {
		return false
	}
	return ok
}

// AddNeedGetRequestInfo 添加需要获取请求信息的页面
func AddNeedGetRequestInfo(moduleName, methodName string) {
	needGetRequestInfo[moduleName+"_"+methodName] = true
}

// IsNeedGetRequestInfo 判断是否需要获取请求信息的页面
func IsNeedGetRequestInfo(moduleName, methodName string) bool {
	exist, ok := needGetRequestInfo[moduleName+"_"+methodName]
	if !exist {
		return false
	}
	return ok
}
