package middleware

import (
	"eta/eta_mini_ht_api/common/component/cache"
	logger "eta/eta_mini_ht_api/common/component/log"
	"eta/eta_mini_ht_api/common/exception"
	"eta/eta_mini_ht_api/common/utils/jwt"
	"eta/eta_mini_ht_api/common/utils/redis"
	stringUtils "eta/eta_mini_ht_api/common/utils/string"
	"eta/eta_mini_ht_api/controllers"
	"eta/eta_mini_ht_api/service/user"
	"fmt"
	"github.com/beego/beego/v2/server/web"
	"github.com/beego/beego/v2/server/web/context"
	"strings"
)

var (
	rdCache *cache.RedisCache
)

const (
	ILLEGALUSER   = "用户信息异常"
	UNAUTHORIZED  = "请重新登录"
	TOKENEXPIRED  = "token过期"
	FORBIDDEN     = "禁止访问"
	NOTFOUND      = "未找到"
	authorization = "Authorization"
	baseUrl       = "/htapi"
	Bearer        = "Bearer"
)

func rd() *cache.RedisCache {
	if rdCache == nil {
		rdCache = cache.GetInstance()
	}
	return rdCache
}

var publicRoutes = []string{
	"/auth/areaCodes",
	"/auth/wxAppid",
	"/auth/notice",
	"/auth/disclaimer",
	"/auth/refreshToken",
	"/auth/sendCode",
	"/user/bind_gzh",
	"/user/wx/notify",
}

func AuthMiddleware() web.FilterFunc {
	return func(ctx *context.Context) {
		path := ctx.Input.URL()
		logger.Info("请求路径:%v", path)
		if !allowed(path) {
			rep := unAuthorized()
			auth := ctx.Input.Header(authorization)
			if auth == "" {
				logger.Error("token信息不存在")
				_ = ctx.JSONResp(rep)
				return
			}
			fmt.Println(auth)
			parts := strings.Split(auth, " ")
			fmt.Println(len(parts))
			if len(parts) != 2 || parts[0] != Bearer {
				logger.Error("token参数不符合格式" + auth)
				_ = ctx.JSONResp(rep)
				return
			}
			info, err := jwt.CheckToken(parts[1])
			if err != nil {
				logger.Error("token无效:%v", err)
				_ = ctx.JSONResp(rep)
				return
			}
			fmt.Println(info)
			//校验redis中是否合法
			redisToken := rd().GetString(redis.GenerateTokenKey(info.OpenId))
			if redisToken != parts[1] {
				logger.Error("token无效:用户token已刷新")
				_ = ctx.JSONResp(tokenExpired())
				return
			}
			//组装用户信息
			var userInfo user.User
			userInfo, err = user.GetUserByOpenId(info.OpenId)
			if err != nil {
				logger.Error("获取用户信息失败:%v", err)
				_ = ctx.JSONResp(illegalUser())
				return
			}
			if userInfo.Mobile == "" && path != baseUrl+"/auth/login" {
				logger.Error("用户手机号为空：%v", err)
				_ = ctx.JSONResp(illegalUser())
				return
			}
			ctx.Input.SetData("user", userInfo)
			return
		}
		return
	}
}

func unAuthorized() controllers.BaseResponse {
	return controllers.BaseResponse{
		Ret:    401,
		Msg:    UNAUTHORIZED,
		ErrMsg: exception.GetMsg(exception.Unauthorized),
	}
}
func tokenExpired() controllers.BaseResponse {
	return controllers.BaseResponse{
		Ret:    408,
		Msg:    TOKENEXPIRED,
		ErrMsg: exception.GetMsg(exception.Unauthorized),
	}
}
func illegalUser() controllers.BaseResponse {
	return controllers.BaseResponse{
		Ret:    401,
		Msg:    ILLEGALUSER,
		ErrMsg: exception.GetMsg(exception.Unauthorized),
	}
}
func allowed(path string) bool {
	for _, p := range publicRoutes {
		if stringUtils.IsBlank(p) {
			continue
		}
		src := baseUrl + p
		if strings.HasSuffix(p, "*") {

			target := src[:len(src)-1]
			fmt.Println("target:" + target)
			if strings.HasPrefix(path, target) {
				return true
			}
		} else {
			if src == path {
				return true
			}
		}
	}
	return false
}
