package mw

import (
	"applet/app/db"
	"applet/app/db/model"
	"applet/app/e"
	"applet/app/lib/auth"
	"applet/app/md"
	"applet/app/svc"
	"applet/app/utils"
	"applet/app/utils/cache"
	"applet/app/utils/logx"
	"errors"
	"fmt"
	"strings"

	"github.com/gin-gonic/gin"
)

// AuthJWT is jwt middleware
func AuthJWT(c *gin.Context) {
	authHeader := c.Request.Header.Get("Authorization")
	if authHeader == "" {
		e.OutErr(c, e.ERR_UNAUTHORIZED, errors.New("token 不能为空"))
		return
	}

	// 按空格分割
	parts := strings.SplitN(authHeader, " ", 2)
	if !(len(parts) == 2 && parts[0] == "Bearer") {
		e.OutErr(c, e.ERR_TOKEN_FORMAT, errors.New("token 格式不对"))
		return
	}

	// parts[1]是token
	mc, err := utils.ParseToken(parts[1])
	if err != nil {
		e.OutErr(c, e.ERR_UNAUTHORIZED, errors.New("token 过期或无效"))
		return
	}

	// 获取user
	u, err := db.UserFindByID(db.DBs[c.GetString("mid")], mc.UID)
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err)
		return
	}
	if u == nil {
		e.OutErr(c, e.ERR_UNAUTHORIZED, errors.New("token 过期或无效"))
		return
	}

	// 检验账号是否未激活或被冻结
	switch u.State {
	case 0:
		e.OutErr(c, e.ERR_USER_NO_ACTIVE)
		return
	case 2:
		if c.GetString("mid") == "31585332" {
			utils.FilePutContents("ERR_USER_IS_BAN", utils.SerializeStr(map[string]interface{}{
				"token": parts[1],
				"mc":    mc,
				"user":  u,
			}))
		}
		e.OutErr(c, e.ERR_USER_IS_BAN)
		return
	}

	// 校验是否和缓存的token一致，只能有一个token 是真实有效
	key := fmt.Sprintf("%s:token:%s", c.GetString("mid"), u.Username)
	cjwt, err := cache.GetString(key)
	fmt.Println("====================token", u.Username, key, cjwt, parts[1])
	if err != nil {
		fmt.Println("====================token", err)
		logx.Warn(err)
		NOCACHE(c, parts, mc, u, false)
		return
	}
	if parts[1] != cjwt {
		e.OutErr(c, e.ERR_TOKEN_AUTH, errors.New("token expired"))
		return
	}
	NOCACHE(c, parts, mc, u, true)
}

func NOCACHE(c *gin.Context, parts []string, mc *auth.JWTUser, u *model.User, isTrue bool) {
	// 获取user profile
	up, err := db.UserProfileFindByID(db.DBs[c.GetString("mid")], mc.UID)
	if err != nil || up == nil {
		e.OutErr(c, e.ERR_DB_ORM, err)
		return
	}
	if parts[1] != up.ArkidToken && isTrue == false || up.ArkidToken == "" {
		e.OutErr(c, e.ERR_TOKEN_AUTH, errors.New("token expired"))
		return
	}
	if parts[1] != up.ArkidToken && isTrue {
		up.ArkidToken = parts[1]
		db.UserProfileUpdate(svc.MasterDb(c), up.Uid, up, "arkid_token")
	}
	if up.AvatarUrl == "" {
		up.AvatarUrl = c.GetString("appUserDefaultAvatar")
	}
	// 获取user 等级
	ul, err := db.UserLevelByID(db.DBs[c.GetString("mid")], u.Level)
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err)
		return
	}

	user := &md.User{
		Info:    u,
		Profile: up,
		Level:   ul,
	}

	// 将当前请求的username信息保存到请求的上下文c上
	c.Set("user", user)
	c.Next() // 后续的处理函数可以用过c.Get("user")来获取当前请求的用户信息

}
