package middleware

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.guxuan/haibei/pkg/jwtx"
	"github.guxuan/haibei/pkg/logging"
	"github.guxuan/haibei/pkg/util"
)

type AuthConfig struct {
	AllowedPathPrefixes []string
	SkippedPathPrefixes []string
	RootID              string
	Skipper             func(c *gin.Context) bool
	ParseUserID         func(c *gin.Context) (string, error)
}

func AuthWithConfig(config AuthConfig) gin.HandlerFunc {
	return func(c *gin.Context) {
		if !AllowedPathPrefixes(c, config.AllowedPathPrefixes...) ||
			SkippedPathPrefixes(c, config.SkippedPathPrefixes...) ||
			(config.Skipper != nil && config.Skipper(c)) {
			c.Next()
			return
		}

		userID, err := config.ParseUserID(c)
		if err != nil {
			util.ResError(c, jwtx.ErrInvalidToken, 401)
			return
		}
		var subject jwtx.JwtSubject
		err = json.Unmarshal([]byte(userID), &subject)
		if err != nil {
			util.ResError(c, jwtx.ErrInvalidToken, 401)
			return
		}
		ctx := util.NewUserID(c.Request.Context(), subject.ID)
		ctx = util.NewUserPlaform(ctx, subject.Typer)
		ctx = logging.NewUserID(ctx, fmt.Sprintf("%v", subject))
		if userID == config.RootID {
			ctx = util.NewIsRootUser(ctx)
		}
		c.Request = c.Request.WithContext(ctx)

		c.Next()
	}
}
