package service

import (
	"WorldEpcho/src/config"
	"WorldEpcho/src/config/e"
	"WorldEpcho/src/utils"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
	"github.com/pkg/errors"
	"net/http"
	"strconv"
	"time"
)

//从session中获取用户id,判断用户是否登录，如果用户已经登录则返回用户id，并返回布尔值
func IsUserLoggedIn2(ctx *gin.Context) (int64, bool) {

	session := sessions.Default(ctx)
	userId := session.Get("WorldUserID")
	if userId == nil {
		// 处理未找到值的情况，返回错误信息
		//ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "Session中未找到用户ID,用户未登录"})
		return 0, false
	}
	// 处理未找到值的情况，返回错误信息
	user_id := utils.Strval(userId)
	//userId作为string类型的值从服务器缓存获取用户id
	_, b := config.WorldLoginCacheCode.Get(user_id)
	uid, err := strconv.ParseInt(user_id, 10, 64)
	if err != nil {
		fmt.Println("转换失败:", err)
		return 0, false
	}
	/*
	   判断用户是否登录
	*/
	if !b {
		//ctx.JSON(http.StatusOK, gin.H{"code": 0, "message": "用户未登录"})
		return 0, false
	}
	return uid, true

}

func IsUserLoggedIn(ctx *gin.Context) (int64, bool) {
	session := sessions.Default(ctx)
	userId := session.Get("WorldUserID")
	if userId != nil {
		user_id := utils.Strval(userId)
		_, b := config.WorldLoginCacheCode.Get(user_id)
		uid, err := strconv.ParseInt(user_id, 10, 64)
		if err == nil && b {
			return uid, true // 如果session验证成功，直接返回
		}
	}

	// 从请求头中获取 JWT token
	tokenString := ctx.GetHeader("Token")
	if tokenString != "" {
		isValid, err := IsValidMiGuToken(tokenString)
		if err == nil && isValid {
			// 解析并验证 JWT token
			token, isValid, err := ParseMIGUToken(tokenString)
			if err == nil && isValid {
				// 提取 Token 中的声明（Claims）
				if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
					if userID, ok := claims["user_id"].(float64); ok {
						return int64(userID), true
					}
				}
			}
		}
	}

	// 如果所有方法都失败，返回未授权的访问错误
	ctx.JSON(http.StatusOK, gin.H{"code": e.UnauthorizedStatus, "data": nil, "message": "未授权的访问或无效的身份验证"})
	return 0, false
}

func IsUserLoggedIn1(ctx *gin.Context) (int64, bool) {
	session := sessions.Default(ctx)
	userId := session.Get("WorldUserID")
	var uid int64
	var err error
	var sessionValid bool

	// 先从session中获取用户信息
	if userId != nil {
		user_id := utils.Strval(userId)
		uid, err = strconv.ParseInt(user_id, 10, 64)
		if err == nil {
			_, sessionValid = config.WorldLoginCacheCode.Get(user_id)
		}
	}

	// 如果 session 有效，直接返回
	if sessionValid {
		return uid, true
	}

	// 如果 session 不存在或无效，从请求头中获取 JWT token
	tokenString := ctx.GetHeader("Token")
	if tokenString != "" {
		isValid, err := IsValidMiGuToken(tokenString)
		if err == nil && isValid {
			// 解析并验证 JWT token
			token, isValid, err := ParseMIGUToken(tokenString)
			if err == nil && isValid {
				// 提取 Token 中的声明（Claims）
				if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
					if userID, ok := claims["user_id"].(float64); ok {
						return int64(userID), true
					}
				}
			}
		}
	}

	// 如果所有方法都失败，返回未授权的访问错误
	ctx.JSON(http.StatusOK, gin.H{"code": e.UnauthorizedStatus, "data": nil, "message": "未授权的访问或无效的身份验证"})
	return 0, false
}

func MiGuIsUserLoggedIn(ctx *gin.Context) (int64, bool) {
	session := sessions.Default(ctx)
	userId := session.Get("WorldUserID")
	if userId != nil {
		user_id := utils.Strval(userId)
		_, b := config.WorldLoginCacheCode.Get(user_id)
		uid, err := strconv.ParseInt(user_id, 10, 64)
		if err == nil && b {
			return uid, true
		}
	}

	// 从请求头中获取 JWT token
	tokenString := ctx.GetHeader("Token")
	if tokenString == "" {
		ctx.JSON(http.StatusOK, gin.H{"code": e.UnauthorizedStatus, "data": nil, "message": "请求头中无token,或未授权的token访问"})
		return 0, false
	}
	// 解析并验证 JWT 令牌
	isValid, err := IsValidMiGuToken(tokenString)
	if err != nil || !isValid {
		ctx.JSON(http.StatusOK, gin.H{"code": e.InvalidToken, "data": nil, "message": "无效或已过期的令牌"})
		return 0, false
	}

	// 解析并验证 JWT token
	token, isValid, err := ParseMIGUToken(tokenString)
	if err != nil || !isValid {
		fmt.Printf("error parsing token: %v", err)
		return 0, false
	}
	// 提取 Token 中的声明（Claims）
	if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
		if userID, ok := claims["user_id"].(float64); ok {
			return int64(userID), true
		} else {
			fmt.Printf("user_id claim is missing or type is error")
			return 0, false
		}
	}
	return 0, false
}

// ParseMIGUToken 解析和验证 JWT 令牌，并检查是否过期
func ParseMIGUToken(tokenString string) (*jwt.Token, bool, error) {
	// 使用与生成 Token 相同的密钥
	jwtSecret := []byte(config.Conf.JwtSecret)

	// 解析令牌
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("不支持的签名方法: %v", token.Header["alg"])
		}
		return jwtSecret, nil
	})

	if err != nil {
		return nil, false, err // 如果解析过程中发生错误，返回错误信息
	}

	if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
		// 获取令牌的过期时间戳
		if exp, ok := claims["exp"].(float64); ok {
			// 检查令牌是否过期
			now := time.Now().Unix()
			if int64(exp) < now {
				return nil, false, fmt.Errorf("令牌已过期")
			}
			fmt.Println("Token is valid and not expired!")
			fmt.Printf("User ID: %v, Level: %v, Expiry: %v\n", claims["user_id"], claims["level"], time.Unix(int64(exp), 0))
			return token, true, nil // 返回 true 表示令牌有效且未过期
		} else {
			return nil, false, fmt.Errorf("无法获取令牌的过期时间")
		}
	}

	return nil, false, fmt.Errorf("无效的令牌")
}

//校验咪咕的服务商token是否合法
func IsValidMiGuToken(tokenString string) (bool, error) {

	// 解析并验证 JWT token
	_, isValid, err := ParseMIGUToken(tokenString)
	if err != nil || !isValid {
		fmt.Printf("error parsing token: %v", err)
		return false, errors.New("无效的token或解析token出错")
	}
	return true, nil
}
