package middleware

import (
	"context"
	"github.com/casbin/casbin/v2"
	"github.com/redis/go-redis/v9"
	"github.com/spf13/cast"
	"github.com/suyuan32/simple-admin-common/enum/errorcode"
	"github.com/suyuan32/simple-admin-core/rpc/coreclient"
	"github.com/zeromicro/go-zero/core/errorx"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/rest/httpx"
	"net/http"
	"wechat-api/internal/config"
	jwtutils "wechat-api/internal/utils/jwt"
)

type MiniprogramMiddleware struct {
	Cbn     *casbin.Enforcer
	Rds     redis.UniversalClient
	CoreRpc coreclient.Core
	Config  config.Config
}

func NewMiniprogramMiddleware(cbn *casbin.Enforcer, rds redis.UniversalClient, core coreclient.Core, c config.Config) *MiniprogramMiddleware {
	return &MiniprogramMiddleware{
		Cbn:     cbn,
		Rds:     rds,
		CoreRpc: core,
		Config:  c,
	}
}

func (m *MiniprogramMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		tokenStr := jwtutils.StripBearerPrefixFromToken(r.Header.Get("Authorization"))
		claims, err := jwtutils.ParseJwtToken(m.Config.Auth.AccessSecret, tokenStr)
		if err != nil {
			logx.Errorw("check user auth error", logx.Field("detail", err.Error()))
			httpx.Error(w, errorx.NewApiError(http.StatusInternalServerError, err.Error()))
			return
		}

		jwtUid, ok := claims["userId"]
		userId := cast.ToUint64(jwtUid)
		if ok && userId > 0 {
			r = r.WithContext(context.WithValue(r.Context(), "userId", userId))
			next(w, r)
			return
		} else {
			logx.Errorw("User need to login in to access the resource")
			httpx.Error(w, errorx.NewCodeError(errorcode.PermissionDenied, "User need to login in to access the resource"))
			return
		}
	}
}
