package middlewares

import (
	"quyun/v2/app/errorx"
	"quyun/v2/app/services"
	"quyun/v2/providers/jwt"

	"github.com/gofiber/fiber/v3"
	log "github.com/sirupsen/logrus"
)

// Middlewares provides reusable Fiber middlewares shared across modules.
//
// @provider
type Middlewares struct {
	// log is the module logger injected by the framework.
	log *log.Entry `inject:"false"`
	// jwt is the JWT provider used by auth-related middlewares.
	jwt *jwt.JWT
}

func (f *Middlewares) Prepare() error {
	f.log = log.WithField("module", "middleware")
	return nil
}

func (m *Middlewares) Auth(ctx fiber.Ctx) error {
	authHeader := ctx.Get("Authorization")
	if authHeader == "" {
		return ctx.Next()
	}

	claims, err := m.jwt.Parse(authHeader)
	if err != nil {
		return errorx.ErrUnauthorized.WithCause(err).WithMsg("Invalid token")
	}

	// get user model
	user, err := services.User.GetModelByID(ctx, claims.UserID)
	if err != nil {
		return errorx.ErrUnauthorized.WithCause(err).WithMsg("UserNotFound")
	}

	// Set Context
	ctx.Locals("__ctx_user", user)
	if claims.TenantID > 0 {
		tenant, err := services.Tenant.GetModelByID(ctx, claims.TenantID)
		if err != nil {
			return errorx.ErrUnauthorized.WithCause(err).WithMsg("TenantNotFound")
		}
		ctx.Locals("__ctx_tenant", tenant)
	}

	return ctx.Next()
}
